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 have root=/dev/sda2 (or another valid /dev location) added in order to boot from the virtual hard drive.
  • -drive for the cdrom 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.

Citations