Debian on ARM via QEMU
NOTE this post has been superseded by https://phwl.org/2022/qemu-aarch64-debian/.
This post describes how to emulate an ARM 64 bit (aarch64) or ARM hard float 32 bit (armhf) processor using using qemu
and install Debian Linux on the emulator. Actually I did the 32 bit one first so the process is a little more streamlined for 64 bit.
I used Ubuntu 18.04.5 but any Debian/Ubuntu distribution can be used with minor changes and it should work under VirtualBox.
1. Create QEMU Image
1.1. For (64-bit) aarch64
I used the lastest version of qemu from github and created a 32G qcow2 image (there isn’t any disk space advantage to specifying 16G but it is a pain if it runs out).
$ qemu-system-aarch64 --version
QEMU emulator version 5.2.92 (v6.0.0-rc2)
Copyright (c) 2003-2021 Fabrice Bellard and the QEMU Project developers
$ qemu-img create -f qcow2 debian-3607-aarch64.qcow2 32G
$ wget https://cdimage.debian.org/mirror/cdimage/archive/10.9.0/arm64/iso-cd/debian-10.9.0-arm64-xfce-CD-1.iso
$ wget http://ftp.au.debian.org/debian/dists/buster/main/installer-arm64/20190702/images/cdrom/initrd.gz
$ wget http://ftp.au.debian.org/debian/dists/buster/main/installer-arm64/20190702/images/cdrom/vmlinuz
$ qemu-system-aarch64 -M virt -cpu cortex-a53 -m 1G -initrd initrd.gz -kernel vmlinuz -append "root=/dev/sda2 console=ttyAMA0" -global virtio-blk-device.scsi=off -device virtio-scsi-device,id=scsi -drive file=debian-3607-aarch64.qcow2,id=rootimg,cache=unsafe,if=none -device scsi-hd,drive=rootimg -net user,hostfwd=tcp::10022-:22 -net nic -nographic -device intel-hda -device hda-duplex
- No common CD-ROM drive was detected: Manually select to use /dev/vdb
$ sudo apt install libguestfs-tools
$ virt-copy-out -a debian-3607-aarch64.qcow2 /boot/vmlinuz-4.19.0-16-arm64 /boot/initrd.img-4.19.0-16-arm64 .
$ qemu-system-aarch64 -M virt -cpu cortex-a53 -m 1G -initrd initrd.img-4.19.0-16-arm64 \
-kernel vmlinuz-4.19.0-16-arm64 -append "root=/dev/vda2 console=ttyAMA0" \
-drive if=virtio,file=debian-3607-aarch64.qcow2,format=qcow2,id=hd \
-net user,hostfwd=tcp::10022-:22 -net nic -nographic -device intel-hda -device hda-duplex
$ qemu-system-aarch64 -M virt -cpu cortex-a53 -m 1G -initrd initrd.img \
-kernel vmlinuz -append "root=/dev/vda2 console=ttyAMA0" \
-drive if=virtio,file=debian-3607-aarch64.qcow2,format=qcow2,id=hd \
-drive file=debian-11.2.0-arm64-DVD-1.iso,id=cdrom,if=none,media=cdrom -device virtio-scsi-device -device scsi-cd,drive=cdrom \
-net user,hostfwd=tcp::10022-:22 -net nic -nographic -device intel-hda -device hda-duplex
Then you can login as root and
# apt update
# apt
1.2. For (32-bit) armhf
Install qemu.
$ sudo apt update
$ sudo apt upgrade
$ mkdir qemu; cd qemu
$ sudo apt install qemu-system-arm
Download initrd.gz, vmlinuz and debian-10.9.0-armhf-netinst.iso (alternatively debian-10.9.0-armhf-xfce-CD-1.iso).
$ wget http://ftp.debian.org/debian/dists/buster/main/installer-armhf/20190702/images/netboot/initrd.gz
$ wget http://ftp.debian.org/debian/dists/buster/main/installer-armhf/20190702/images/netboot/vmlinuz
$ wget http://debian.mirror.digitalpacific.com.au/debian-cd/10.9.0/armhf/iso-cd/debian-10.9.0-armhf-netinst.iso
$ qemu-img create -f qcow2 debian-3607.qcow2 16G # 8G will also work but not leave enough disk space for other things
$ qemu-system-arm -M virt -kernel ./vmlinuz -initrd ./initrd.gz -hda debian-3607.qcow2 -nographic -m 1024M -append "console=ttyAMA0" -drive file=debian-10.9.0-armhf-netinst.iso,id=cdrom,if=none,media=cdrom -device virtio-scsi-device -device scsi-cd,drive=cdrom
Use all of the defaults for the Debian installer.
- I used “elec3607” for all user names and passwords.
- For partitioning select “Guided - use entire disk”. Note that this chooses /dev/vda2 for / (we will use this later).
- If you get a “Failed to install the base system” message, try a second time from the menu.
- Select linux-image-armmp-lpae for the kernel.
- Select targeted for initrd (This was a mistake, choose generic)
- For software to install, just choose “SSH server” and “standard system utilities” (the default).
- You will receive the message that GRUB installation failed. We will fix this later.
- Exit
qemu
with “control-A x”.
Extract the kernel and initrd from the disk image.
$ sudo apt-get install libguestfs-tools
$ virt-ls -a debian-3607.qcow2 /boot/
$ virt-copy-out -a debian-3607.qcow2 /boot/vmlinuz-4.19.0-16-armmp-lpae /boot/initrd.img-4.19.0-16-armmp-lpae .
Now you can run your Debian-Arm Linux from either Linux:
$ qemu-system-arm -M virt -kernel vmlinuz-4.19.0-16-armmp-lpae -initrd initrd.img-4.19.0-16-armmp-lpae \
-append 'root=/dev/vda2' -drive if=virtio,file=debian-3607-lab4sol.qcow2,format=qcow2,id=hd \
-nographic -net user,hostfwd=tcp::10022-:22 -net nic
2. Install sudo and put ELEC3607 in the sudo group
Login as elec3607
(password is elec3607
) and execute the following commands.
Note that the basic distribution of Debian does not include sudo.
$ su -
Password:
# apt install sudo
Reading package lists... Done
...
usermod -a -G sudo elec3607
shutdown now
You can also ssh to the machine and use X windows.
$ ssh -Y elec3607@localhost -p 10022
The complete list of Debian packages is available here.
3. Install Debian Audio
Start by booting QEMU.
$ qemu-system-aarch64 -M virt -cpu cortex-a53 -m 1G -initrd initrd.img-4.19.0-16-arm64 \
-kernel vmlinuz-4.19.0-16-arm64 -append "root=/dev/vda2 console=ttyAMA0" \
-drive if=virtio,file=debian-3607-aarch64.qcow2,format=qcow2,id=hd \
-net user,hostfwd=tcp::10022-:22 -net nic -nographic -device intel-hda -device hda-duplex&
Rather than login directly, I prefer to ssh to the QEMU machine so I can run Xwindows.
$ ssh -Y elec3607@localhost -p 10022
You can also copy files to it.
scp -P 10022 -r lab5-audio elec3607@localhost:
Install the alsa and pulseaudio.
$ sudo apt install libasound2 libasound2-plugins libasound2-doc alsa-utils pulseaudio pavucontrol paprefs libpulse-dev libcanberra-gtk-dev
$ sudo usermod -aG audio,pulse,pulse-access elec3607
Then you have to log out and log in again.
$ aplay -l
**** List of PLAYBACK Hardware Devices ****
card 0: Intel [HDA Intel], device 0: Generic Analog [Generic Analog]
Subdevices: 1/1
Subdevice #0: subdevice #0
$ pulseaudio --start
$ pactl info
Server String: /run/user/1000/pulse/native
Library Protocol Version: 32
Server Protocol Version: 32
Is Local: yes
Client Index: 2
Tile Size: 65472
User Name: elec3607
Host Name: debian
Server Name: pulseaudio
Server Version: 12.2
Default Sample Specification: s16le 2ch 44100Hz
Default Channel Map: front-left,front-right
Default Sink: alsa_output.platform-4010000000.pcie-pci-0000_00_02.0.analog-stereo
Default Source: alsa_input.platform-4010000000.pcie-pci-0000_00_02.0.analog-stereo
Cookie: 1295:3f1d
Then you can start it up via systemctl.
$ systemctl --user enable pulseaudio
$ systemctl --user start pulseaudio
Job for pulseaudio.service failed because the control process exited with error code.
See "systemctl --user status pulseaudio.service" and "journalctl --user -xe" for details.
$ sudo shutdown -r now
Wait for everything to come back up and login again via ssh
$ systemctl --user status pulseaudio
● pulseaudio.service - Sound Service
Loaded: loaded (/usr/lib/systemd/user/pulseaudio.service; enabled; vendor pre
Active: active (running) since Sat 2021-04-10 15:59:48 AEST; 4s ago
Main PID: 336 (pulseaudio)
CGroup: /user.slice/user-1000.slice/[email protected]/pulseaudio.service
├─336 /usr/bin/pulseaudio --daemonize=no
└─357 /usr/lib/aarch64-linux-gnu/pulse/gsettings-helper
Now edit /etc/pulse/default.pa
and append the line:
load-module module-null-sink sink_name=MySink format=s16le channels=1 rate=12000
We can restart the daemon and configure with.
$ systemctl --user restart pulseaudio
$ pacmd list-sinks
2 sink(s) available.
* index: 0
name: <alsa_output.platform-4010000000.pcie-pci-0000_00_02.0.analog-stereo>
driver: <module-alsa-card.c>
flags: HARDWARE HW_MUTE_CTRL HW_VOLUME_CTRL DECIBEL_VOLUME LATENCY FLAT_VOLUME DYNAMIC_LATENCY
state: IDLE
suspend cause: (none)
priority: 9039
volume: front-left: 30419 / 46% / -20.00 dB, front-right: 30419 / 46% / -20.00 dB
balance 0.00
base volume: 65536 / 100% / 0.00 dB
volume steps: 65537
muted: no
current latency: 1283.09 ms
max request: 344 KiB
max rewind: 344 KiB
monitor source: 0
sample spec: s16le 2ch 44100Hz
channel map: front-left,front-right
Stereo
used by: 0
linked by: 0
configured latency: 2000.00 ms; range is 0.50 .. 2000.00 ms
card: 0 <alsa_card.platform-4010000000.pcie-pci-0000_00_02.0>
module: 6
properties:
alsa.resolution_bits = "16"
device.api = "alsa"
device.class = "sound"
alsa.class = "generic"
alsa.subclass = "generic-mix"
alsa.name = "Generic Analog"
alsa.id = "Generic Analog"
alsa.subdevice = "0"
alsa.subdevice_name = "subdevice #0"
alsa.device = "0"
alsa.card = "0"
alsa.card_name = "HDA Intel"
alsa.long_card_name = "HDA Intel at 0x10040000 irq 50"
alsa.driver_name = "snd_hda_intel"
device.bus_path = "platform-4010000000.pcie-pci-0000:00:02.0"
sysfs.path = "/devices/platform/4010000000.pcie/pci0000:00/0000:00:02.0/sound/card0"
device.bus = "pci"
device.vendor.id = "8086"
device.vendor.name = "Intel Corporation"
device.product.id = "2668"
device.product.name = "82801FB/FBM/FR/FW/FRW (ICH6 Family) High Definition Audio Controller (QEMU Virtual Machine)"
device.form_factor = "internal"
device.string = "front:0"
device.buffering.buffer_size = "352800"
device.buffering.fragment_size = "176400"
device.access_mode = "mmap+timer"
device.profile.name = "analog-stereo"
device.profile.description = "Analog Stereo"
device.description = "Built-in Audio Analog Stereo"
alsa.mixer_name = "QEMU Generic"
alsa.components = "HDA:1af40022,1af40022,00100101"
module-udev-detect.discovered = "1"
device.icon_name = "audio-card-pci"
ports:
analog-output-lineout: Line Out (priority 9900, latency offset 0 usec, available: unknown)
properties:
active port: <analog-output-lineout>
index: 1
name: <MySink>
driver: <module-null-sink.c>
flags: DECIBEL_VOLUME LATENCY FLAT_VOLUME DYNAMIC_LATENCY
state: IDLE
suspend cause: (none)
priority: 1000
volume: mono: 65536 / 100% / 0.00 dB
balance 0.00
base volume: 65536 / 100% / 0.00 dB
volume steps: 65537
muted: no
current latency: 1576.69 ms
max request: 46 KiB
max rewind: 46 KiB
monitor source: 2
sample spec: s16le 1ch 12000Hz
channel map: mono
Mono
used by: 0
linked by: 0
configured latency: 2000.00 ms; range is 0.50 .. 2000.00 ms
module: 20
properties:
device.description = "Null Output"
device.class = "abstract"
device.icon_name = "audio-card"
$ pacmd list-sources
3 source(s) available.
index: 0
name: <alsa_output.platform-4010000000.pcie-pci-0000_00_02.0.analog-stereo.monitor>
driver: <module-alsa-card.c>
flags: DECIBEL_VOLUME LATENCY DYNAMIC_LATENCY
state: SUSPENDED
suspend cause: IDLE
priority: 1030
volume: front-left: 65536 / 100% / 0.00 dB, front-right: 65536 / 100% / 0.00 dB
balance 0.00
base volume: 65536 / 100% / 0.00 dB
volume steps: 65537
muted: no
current latency: 0.00 ms
max rewind: 0 KiB
sample spec: s16le 2ch 44100Hz
channel map: front-left,front-right
Stereo
used by: 0
linked by: 0
configured latency: 0.00 ms; range is 0.50 .. 2000.00 ms
monitor_of: 0
card: 0 <alsa_card.platform-4010000000.pcie-pci-0000_00_02.0>
module: 6
properties:
device.description = "Monitor of Built-in Audio Analog Stereo"
device.class = "monitor"
alsa.card = "0"
alsa.card_name = "HDA Intel"
alsa.long_card_name = "HDA Intel at 0x10040000 irq 50"
alsa.driver_name = "snd_hda_intel"
device.bus_path = "platform-4010000000.pcie-pci-0000:00:02.0"
sysfs.path = "/devices/platform/4010000000.pcie/pci0000:00/0000:00:02.0/sound/card0"
device.bus = "pci"
device.vendor.id = "8086"
device.vendor.name = "Intel Corporation"
device.product.id = "2668"
device.product.name = "82801FB/FBM/FR/FW/FRW (ICH6 Family) High Definition Audio Controller (QEMU Virtual Machine)"
device.form_factor = "internal"
device.string = "0"
module-udev-detect.discovered = "1"
device.icon_name = "audio-card-pci"
* index: 1
name: <alsa_input.platform-4010000000.pcie-pci-0000_00_02.0.analog-stereo>
driver: <module-alsa-card.c>
flags: HARDWARE HW_MUTE_CTRL HW_VOLUME_CTRL DECIBEL_VOLUME LATENCY DYNAMIC_LATENCY
state: SUSPENDED
suspend cause: IDLE
priority: 9039
volume: front-left: 65536 / 100% / 0.00 dB, front-right: 65536 / 100% / 0.00 dB
balance 0.00
base volume: 65536 / 100% / 0.00 dB
volume steps: 65537
muted: no
current latency: 0.00 ms
max rewind: 0 KiB
sample spec: s16le 2ch 44100Hz
channel map: front-left,front-right
Stereo
used by: 0
linked by: 0
configured latency: 0.00 ms; range is 0.50 .. 2000.00 ms
card: 0 <alsa_card.platform-4010000000.pcie-pci-0000_00_02.0>
module: 6
properties:
alsa.resolution_bits = "16"
device.api = "alsa"
device.class = "sound"
alsa.class = "generic"
alsa.subclass = "generic-mix"
alsa.name = "Generic Analog"
alsa.id = "Generic Analog"
alsa.subdevice = "0"
alsa.subdevice_name = "subdevice #0"
alsa.device = "0"
alsa.card = "0"
alsa.card_name = "HDA Intel"
alsa.long_card_name = "HDA Intel at 0x10040000 irq 50"
alsa.driver_name = "snd_hda_intel"
device.bus_path = "platform-4010000000.pcie-pci-0000:00:02.0"
sysfs.path = "/devices/platform/4010000000.pcie/pci0000:00/0000:00:02.0/sound/card0"
device.bus = "pci"
device.vendor.id = "8086"
device.vendor.name = "Intel Corporation"
device.product.id = "2668"
device.product.name = "82801FB/FBM/FR/FW/FRW (ICH6 Family) High Definition Audio Controller (QEMU Virtual Machine)"
device.form_factor = "internal"
device.string = "front:0"
device.buffering.buffer_size = "352800"
device.buffering.fragment_size = "176400"
device.access_mode = "mmap+timer"
device.profile.name = "analog-stereo"
device.profile.description = "Analog Stereo"
device.description = "Built-in Audio Analog Stereo"
alsa.mixer_name = "QEMU Generic"
alsa.components = "HDA:1af40022,1af40022,00100101"
module-udev-detect.discovered = "1"
device.icon_name = "audio-card-pci"
ports:
analog-input-linein: Line In (priority 8100, latency offset 0 usec, available: unknown)
properties:
active port: <analog-input-linein>
index: 2
name: <MySink.monitor>
driver: <module-null-sink.c>
flags: DECIBEL_VOLUME LATENCY DYNAMIC_LATENCY
state: SUSPENDED
suspend cause: IDLE
priority: 1000
volume: mono: 65536 / 100% / 0.00 dB
balance 0.00
base volume: 65536 / 100% / 0.00 dB
volume steps: 65537
muted: no
current latency: 0.00 ms
max rewind: 46 KiB
sample spec: s16le 1ch 12000Hz
channel map: mono
Mono
used by: 0
linked by: 0
configured latency: 0.00 ms; range is 0.50 .. 2000.00 ms
monitor_of: 1
module: 20
properties:
device.description = "Monitor of Null Output"
device.class = "monitor"
device.icon_name = "audio-input-microphone"
The Volume Control program allows you to monitor what sources and sinks are available. If you play something and run pavucontrol
.
$ paplay iq-16b.wav&
$ pavucontrol&
- In the Configuration tab, select Off as the Built-in Audio profile
- If you look at Input Devices and Show: All Input Devices, you should only see Monitor of Null Output and the meter should indicate something is playing.
- If you look at Output Devices and Show: All Output Devices, you should only see Null Output and the meter should indicate something is playing. `
If you play a file in the background, you can decode it.
$ paplay data/iq-16b.wav &
$ wsprcan/k9an-wsprd
Writing data/wf-1618037425.wav
mode -1 -3.1 0.001437 -3 VK2RG QF56 30
mode -19 -2.9 0.001455 -2 VK3GOD QF23 23
mode -21 -2.9 0.001478 -2 VK4YEH QG62 37
<DecodeFinished,data/wf-1618037425.wav,3>
[3]+ Done paplay data/iq-16b.wav
Other useful tools include:
- Firefox and audacity packages are useful but run too slow on QEMU.
sudo apt install firefox-esr audacity
- PulseAudio Preferences can be used to configure the network.
$ paprefs
- Under the Network Access tab, select “Make discoverable PulseAudio network sound devices available locally”
- Under the Network Server tab, select “Enable network access to local sound devices” and “Don’t require authentication”
If you go to a websdr in Firefox, you can route the audio to your machine.
$ firefox http://websdr1.sdrutah.org:8901/index1a.html?tune=7038.6usb &
Unfortunately, this doesn’t run fast enough under QEMU to work on wspr decoding but it does under native x86 Linux.