Running Debian ARM64 on QEMU with UEFI

1. Pre-installation

Download the Debian ARM64 netinstall ISO:

debian-8.1.0-arm64-CD-1.iso

2. Prepare QEMU UEFI Flash and Disk Images

Create UEFI Flash Images

dd if=/dev/zero of=flash0.img bs=1M count=64
dd if=/dev/zero of=flash1.img bs=1M count=64

Download Linaro UEFI Firmware

LINARO_EDK2_URL=http://releases.linaro.org/15.01/components/kernel/uefi-linaro/
wget $LINARO_EDK2_URL/release/qemu64-intelbds/QEMU_EFI.fd

Write Firmware to Flash

dd if=QEMU_EFI.fd of=flash0.img conv=notrunc

Create Virtual Disk

dd if=/dev/zero of=hda.img bs=1M count=8192

3. Installation Script

Create an install.sh script:

#!/bin/sh

CDROM_IMG=debian-8.1.0-arm64-CD-1.iso
HDA_IMG=hda.img

make_cdrom_arg()
{
  echo "-drive file=$1,id=cdrom,if=none,media=cdrom" \
       "-device virtio-scsi-device -device scsi-cd,drive=cdrom"
}

make_hda_arg()
{
  echo "-drive if=none,file=$1,id=hd0" \
       "-device virtio-blk-device,drive=hd0"
}

HDA_ARGS=`make_hda_arg $HDA_IMG`

if [ $# -eq 1 ]; then
  case $1 in
    install)
      CDROM_ARGS=`make_cdrom_arg $CDROM_IMG`
      ;;
    *)
      CDROM_ARGS=""
      ;;
  esac
fi

qemu-system-aarch64 -m 1024 -cpu cortex-a57 -M virt -nographic \
  -pflash flash0.img \
  $CDROM_ARGS \
  $HDA_ARGS \
  -netdev user,id=eth0 \
  -device virtio-net-device,netdev=eth0

Make it executable and start installation:

chmod +x install.sh
./install.sh install
Proceed with normal Debian installation inside QEMU.

4. Extract Installed Kernel and Initrd

After installation completes:

sudo modprobe nbd max_part=63
sudo qemu-nbd -c /dev/nbd0 hda.img
mkdir mnt
sudo mount /dev/nbd0p2 mnt   # Adjust partition if necessary

Copy kernel and initrd:

sudo cp mnt/boot/vmlinuz-3.13.0-53-generic .
sudo cp mnt/boot/initrd.img-3.13.0-53-generic .

Unmount and disconnect:

sudo umount mnt
sudo qemu-nbd -d /dev/nbd0
rmdir mnt

5. Troubleshooting

Error: Failed to set NBD socket

nbd.c:nbd_init(): Failed to set NBD socket

Likely caused by an existing qemu-nbd process.

ps -ef | grep qemu
kill <pid>
Retry mounting after killing stale process.

Error: Executing code outside RAM or ROM

qemu: fatal: Trying to execute code outside RAM or ROM

Cause:

  • Using wrong kernel image (e.g. vmlinux instead of vmlinuz)
  • Kernel version mismatch

Always use vmlinuz and matching initrd.


6. Boot Debian on QEMU

qemu-system-aarch64 \
  -machine virt \
  -cpu cortex-a57 \
  -nographic \
  -smp 1 \
  -m 2048 \
  -pflash flash0.img \
  -drive if=none,file=hda.img,id=hd0 \
  -device virtio-blk-device,drive=hd0 \
  -kernel vmlinuz-3.16.0-4-arm64 \
  -initrd initrd.img-3.16.0-4-arm64 \
  -netdev user,id=unet \
  -device virtio-net-device,netdev=unet \
  --append "console=ttyAMA0 root=/dev/vda2"

7. Sharing Files Between Host and Guest

One simple method is to create a shared disk image.

Create Shared Disk

dd if=/dev/zero of=share.img bs=1M count=1024
mkfs.ext4 share.img

Mount on Host

mkdir mnt
mount -o loop share.img mnt

Add to QEMU Boot Command

-drive if=none,file=share.img,id=hd1 \
-device virtio-blk-device,drive=hd1

Inside guest, mount the additional virtio block device.


Conclusion

This workflow demonstrates:

  • Installing Debian ARM64 on QEMU virt machine
  • Using UEFI firmware (EDK2)
  • Extracting kernel/initrd manually
  • Booting with explicit kernel parameters
  • Sharing files via additional disk image

The virt machine type with virtio devices provides a clean and efficient AArch64 virtualization environment for development and testing.


Reference

http://blog.eciton.net/uefi/qemu-aarch64-jessie.html

← Previous Post
Next Post →

Leave a Comment