Arm QEMU Debian 12 VM on Linux
The goal is to get a 64-bit arm64/aarch64 Debian VM running in QEMU on a typical x86_64/amd64 Linux host machine.
$ qemu-system-aarch64 --version
QEMU emulator version 8.2.2
Copyright (c) 2003-2023 Fabrice Bellard and the QEMU Project developers
The author’s lack of knowledge about Arm, QEMU, and Debian on Arm probably make this process a bit more complex than it needs to be. This article is a guide, but most likely not the best guide.
Download Files
Download the latest arm64 vmlinux
kernel and
initrd.gz
initramfs from
Debian. These files exist specifically for bootstrapping the
installation. These are special kernel and initramfs files for
installing Debian.
curl -O http://ftp.us.debian.org/debian/dists/stable/main/installer-arm64/current/images/cdrom/initrd.gz
curl -O http://ftp.us.debian.org/debian/dists/stable/main/installer-arm64/current/images/cdrom/vmlinuz
Download the latest
Debian arm64 DVD ISO. Version debian-12.5.0-arm64-DVD-1.iso
at time of
writing.
curl -O -L https://cdimage.debian.org/debian-cd/current/arm64/iso-dvd/debian-12.5.0-arm64-DVD-1.iso
That ISO file, in conjunction with the vmlinux
and
initrd.gz
files, are how we install Debian. The
kernel and initramfs files allow us to boot to an installation
environment. The DVD iso file is the installation media that the
installer uses as a repository.
Install Debian
Create a disk for the Arm QEMU emulator image.
qemu-img create -f qcow2 debian-arm.sda.qcow2 100G
Boot the VM to install Debian.
qemu-system-aarch64 \
-m 4G \
-machine type=virt \
-cpu max \
-m 8g \
-smp 4 \
-initrd "./initrd.gz" \
-kernel "./vmlinuz" \
-append "console=ttyAMA0" \
-drive file=./debian-12.5.0-arm64-DVD-1.iso,id=cdrom,if=none,media=cdrom \
-device virtio-scsi-device \
-device scsi-cd,drive=cdrom \
-drive file="./debian-arm.sda.qcow2",id=hd,if=none,media=disk \
-device virtio-scsi-device \
-device scsi-hd,drive=hd \
-netdev user,id=net0,hostfwd=tcp::5555-:22 \
-device virtio-net-device,netdev=net0 \
-nographic
Follow the installation wizard. This will be a minimal
installation. Set a password for the root
user.
Install Debian to a single partition. Do not enable disk
encryption. Do not install a desktop environment. Install the
standard system utilities
and
SSH server
software when prompted.
Installation may take a while.
When installation completes it is crucial to not reboot when prompted.
┌───────────────────┤ [!!] Finish the installation ├────────────────────┐
│ │
│ Installation complete │
│ Installation is complete, so it is time to boot into your new system. │
│ Make sure to remove the installation media, so that you boot into the │
│ new system rather than restarting the installation. │
│ │
│ <Go Back> <Continue> │
│ │
└───────────────────────────────────────────────────────────────────────┘
Choose Go Back
at the
Finish the installation
menu.
Choose to Execute a shell
from the main installer
menu.
Delete the cdrom
repository from apt
.
chroot /target sh -c "sed -i '/deb cdrom/d' /etc/apt/sources.list"
Enable root
SSH login for the installation.
chroot /target sh -c "echo 'PermitRootLogin yes' > /etc/ssh/sshd_config.d/root_ssh.conf"
Start sshd
on the Debian installation so that we can
copy out the kernel and initramfs files from the guest to the
host.
chroot /target sh -c "mkdir -p /var/run/sshd && /sbin/sshd -D"
Use scp
on the host machine to copy boot files from
the guest.
scp -P 5555 root@localhost:/boot/vmlinuz ./vmlinuz-from-guest
scp -P 5555 root@localhost:/boot/initrd.img ./initrd.img-from-guest
Use ctrl + c
or another mechanism to stop
sshd
.
Delete the SSH root
login config file as it is
typically unsafe to allow root
to log in using SSH.
chroot /target sh -c "rm /etc/ssh/sshd_config.d/root_ssh.conf"
Shut down the guest VM.
poweroff
Run VM Normally
Modify a few of the options for subsequent “normal” booting into the VM after installing Debian.
-
-append
must haveroot=/dev/sda2
(or another valid/dev
location) added in order to boot from the virtual hard drive. -
-drive
for thecdrom
is not needed at this point and can be removed -
-netdev
is no longer needed and can be removed -
-initrd
should use the file copied out from the VM -
-kernel
should use the file copied out from the VM
qemu-system-aarch64 \
-m 4G \
-machine type=virt \
-cpu max \
-m 8g \
-smp 4 \
-initrd "./initrd.img-from-guest" \
-kernel "./vmlinuz-from-guest" \
-append "console=ttyAMA0 root=/dev/sda2" \
-drive file="./debian-arm.sda.qcow2",id=hd,if=none,media=disk \
-device virtio-scsi-device \
-device scsi-hd,drive=hd \
-netdev user,id=net0,hostfwd=tcp::5555-:22 \
-device virtio-net-device,netdev=net0 \
-nographic
The Debian VM should now be ready for use as a typical Debian machine.
If the vmlinux
and initrd
files are ever
updated in the VM they should be copied out and updated on the
host as was done during the initial setup.
Note: QEMU Arm Hardware is Picky
Please note that
Arm emulated boards/machine types are extremely specific about
the type of hardware they support. See the
QEMU docs on choosing a board model. For example, the virt
machine type (-M / -machine
) only supports PCI ethernet devices. Specifying a board that
supports 64-bit
/aarch64
vs
32-bit
boards has implications on the
cpu
and other options that will be allowed.
The orangepi-pc
machine type requires exactly 1GB of
RAM. The Raspberry Pi related machine types have similar
restrictions. Boards that simulate physical hardware must accept
parameters that align with that device type.
See this text here regarding the
QEMU Arm Versatile Express
boards.
Note that as this hardware does not have PCI, IDE or SCSI, the only available storage option is emulated SD card.
See some example errors here for
qemu-system-arm
configuration options that were
incompatible with the selected machine type.
qemu-system-arm: This machine can only be used with 512MiB or 1GiB RAM
qemu-system-arm: This board can only be used with cortex-a7 CPU
qemu-system-arm: Unsupported NIC model: rtl8139
qemu-system-arm: Invalid SD card size: 100 GiB
SD card size has to be a power of 2, e.g. 128 GiB.