Running an ISO installer image for arm64 (AArch64) using QEMU and KVM

Scattered across myriad blogs around the internet you will find many different ways to boot GNU/Linux for arm64 (a.k.a. AArch64) using QEMU with or without KVM. However, when I recently wanted to quickly spin up a KVM VM on my Developerbox using the Debian Installer ISO images, I couldn’t find any end-to-end instructions. There is lots of great information out there but I had to assemble the fragments myself. Having done that I thought I would share the results…

To get started you will need:

  • qemu-system-aarch64, which can usually get using your distributions package manager (the package name is qemu-system-aarch64 on Fedora but on Debian qemu-system-arm contains both AArch32 and AArch64 support,
  • A Debian network installer ISO image for arm64, I have tried both Debian 9 “Stretch” and Debian Testing “Buster”,
  • A UEFI image for QEMU’s virt machine type, I use an EDK II derived snapshot image from Linaro

Having downloaded the prerequisites we need to decompress the UEFI system firmware and create both the main disk image and a much smaller image to hold the EFI variable store:

gunzip QEMU_EFI.img.gz
qemu-img create -f qcow2 debian.img 128G
qemu-img create -f qcow2 varstore.img 64M

Note: It’s generally better to make the debian.img too large rather than too small. qcow2 images are fairly efficient meaning unused space is not allocated and won’t waste space on the host machine.

Almost there… it’s time to boot the installer.

If you are running on an arm64 workstation and want to accelerate things using KVM try:

qemu-system-aarch64 \
    -cpu host -M virt,accel=kvm -m 4096 -nographic \
    -drive if=pflash,format=raw,file=QEMU_EFI.img \
    -drive if=pflash,file=varstore.img \
    -drive if=virtio,file=debian.img \
    -drive if=virtio,format=raw,file=debian-9.3.0-arm64-netinst.iso

Alternatively, for software simulation (on any host platform) try:

qemu-system-aarch64 \
    -cpu cortex-a53 -M virt -m 4096 -nographic \
    -drive if=pflash,format=raw,file=QEMU_EFI.img \
    -drive if=pflash,file=varstore.img \
    -drive if=virtio,file=debian.img \
    -drive if=virtio,format=raw,file=debian-9.3.0-arm64-netinst.iso

The installer should boot automatically and, for the most part, if you need help using the installer try the Debian Installation Guide. There is one more thing we need to look at here though; the installer may not be able to find the installation media automatically because we didn’t ask qemu to read the ISO image is a CD-ROM rather than an USB stick (and we didn’t ask for that because it crashes the system firmware we are using). If this happens you’ll see the follow dialog:

To locate the installation media:

  • Load CD-ROM drivers from removable media?: Select No
  • Manually select a CD-ROM module and device?: Select Yes
  • Module needed for accessing the CD-ROM: Select none
  • Device file for accessing the CD-ROM: Enter /dev/vdb and press Continue

Now complete the installation!

Once you have everything installed can remove the final -drive option. There’s no problem if you don’t remove it though. The default boot device after installation is recorded in the varstore (that’s why we created it) and will be the Debian install inside debian.img.

That’s about it really… although if you are a kernel hacker and want to quickly spin up a system with a custom kernel without going to the trouble of copying the kernel into the image you can (providing your kernel it’s too heavily modulized) try something like:

qemu-system-aarch64 \
    -cpu host -M virt,accel=kvm -m 4096 -nographic \
    -kernel arch/arm64/boot/Image -append root=/dev/vda2 \
    -drive if=virtio,file=debian.img

Have fun!

Share