Hi, I’m developing a custom DietPi image that I want to be able to test by emulating a Raspberry Pi on my personal desktop PC and running the image as a VM before I flash it onto my real Raspberry Pi 4B (though 3B should also be supported).
However, I can’t figure out how to configure Virt-Manager or QEMU in such a way that it will emulate an ARM64 device that actually boots the current RPi 2/3/4 DietPi image. Most resources I find online emulate earlier 32-bit Raspberry Pis, give me other errors, or rely on dhruvvyas90/qemu-rpi-kernel for kernel and DTB files, which is no longer being maintained and does not contain what is necessary for Debian Bookworm (what DietPi is based on at the time of writing). I’ve tried extracting the kernel8.img
and .dtb
files from the boot partition of the image and using those with Virt-Manager / QEMU, but to no avail.
Since my end goal is to test my custom DietPi image, built on CI where I cannot also make an x64 version, I can’t just use an x64 DietPi image. To make matters more complicated, I also need to test the DE and DE settings I pre-install, so I need to have video emulated as well.
Could you help me setup a VM in Virt-Manager that emulates an ARM64 chip and runs DietPi?
This is the Virt-Manager configuration I’ve tried so far:
<domain type="qemu">
<name>virt-dietpi</name>
<uuid>2970c242-ab17-405c-a769-d8d8ab09cfaa</uuid>
<metadata>
<libosinfo:libosinfo xmlns:libosinfo="http://libosinfo.org/xmlns/libvirt/domain/1.0">
<libosinfo:os id="http://debian.org/debian/12"/>
</libosinfo:libosinfo>
</metadata>
<memory unit="KiB">4194304</memory>
<currentMemory unit="KiB">4194304</currentMemory>
<vcpu placement="static">4</vcpu>
<os firmware="efi">
<type arch="aarch64" machine="virt-8.1">hvm</type>
<firmware>
<feature enabled="no" name="enrolled-keys"/>
<feature enabled="no" name="secure-boot"/>
</firmware>
<loader readonly="yes" type="pflash" format="qcow2">/usr/share/edk2/aarch64/QEMU_EFI-silent-pflash.qcow2</loader>
<nvram template="/usr/share/edk2/aarch64/vars-template-pflash.qcow2" format="qcow2">/var/lib/libvirt/qemu/nvram/virt-dietpi_VARS.qcow2</nvram>
<kernel>/home/bart/projects/pi-img/kernel8.img</kernel>
<cmdline>root=/dev/vda2 panic=1</cmdline>
<boot dev="hd"/>
<bootmenu enable="no"/>
</os>
<features>
<acpi/>
<gic version="2"/>
</features>
<cpu mode="custom" match="exact" check="none">
<model fallback="allow">cortex-a72</model>
</cpu>
<clock offset="utc"/>
<on_poweroff>destroy</on_poweroff>
<on_reboot>restart</on_reboot>
<on_crash>destroy</on_crash>
<devices>
<emulator>/usr/bin/qemu-system-aarch64</emulator>
<disk type="file" device="disk">
<driver name="qemu" type="raw"/>
<source file="/home/bart/Downloads/DietPi_RPi-ARMv8-Bookworm.img"/>
<target dev="vda" bus="virtio"/>
<address type="pci" domain="0x0000" bus="0x04" slot="0x00" function="0x0"/>
</disk>
<controller type="usb" index="0" model="qemu-xhci" ports="15">
<address type="pci" domain="0x0000" bus="0x02" slot="0x00" function="0x0"/>
</controller>
<controller type="pci" index="0" model="pcie-root"/>
<controller type="pci" index="1" model="pcie-root-port">
<model name="pcie-root-port"/>
<target chassis="1" port="0x8"/>
<address type="pci" domain="0x0000" bus="0x00" slot="0x01" function="0x0" multifunction="on"/>
</controller>
<controller type="pci" index="2" model="pcie-root-port">
<model name="pcie-root-port"/>
<target chassis="2" port="0x9"/>
<address type="pci" domain="0x0000" bus="0x00" slot="0x01" function="0x1"/>
</controller>
<controller type="pci" index="3" model="pcie-root-port">
<model name="pcie-root-port"/>
<target chassis="3" port="0xa"/>
<address type="pci" domain="0x0000" bus="0x00" slot="0x01" function="0x2"/>
</controller>
<controller type="pci" index="4" model="pcie-root-port">
<model name="pcie-root-port"/>
<target chassis="4" port="0xb"/>
<address type="pci" domain="0x0000" bus="0x00" slot="0x01" function="0x3"/>
</controller>
<controller type="pci" index="5" model="pcie-root-port">
<model name="pcie-root-port"/>
<target chassis="5" port="0xc"/>
<address type="pci" domain="0x0000" bus="0x00" slot="0x01" function="0x4"/>
</controller>
<controller type="pci" index="6" model="pcie-root-port">
<model name="pcie-root-port"/>
<target chassis="6" port="0xd"/>
<address type="pci" domain="0x0000" bus="0x00" slot="0x01" function="0x5"/>
</controller>
<controller type="pci" index="7" model="pcie-root-port">
<model name="pcie-root-port"/>
<target chassis="7" port="0xe"/>
<address type="pci" domain="0x0000" bus="0x00" slot="0x01" function="0x6"/>
</controller>
<controller type="pci" index="8" model="pcie-root-port">
<model name="pcie-root-port"/>
<target chassis="8" port="0xf"/>
<address type="pci" domain="0x0000" bus="0x00" slot="0x01" function="0x7"/>
</controller>
<controller type="pci" index="9" model="pcie-root-port">
<model name="pcie-root-port"/>
<target chassis="9" port="0x10"/>
<address type="pci" domain="0x0000" bus="0x00" slot="0x02" function="0x0" multifunction="on"/>
</controller>
<controller type="pci" index="10" model="pcie-root-port">
<model name="pcie-root-port"/>
<target chassis="10" port="0x11"/>
<address type="pci" domain="0x0000" bus="0x00" slot="0x02" function="0x1"/>
</controller>
<controller type="pci" index="11" model="pcie-root-port">
<model name="pcie-root-port"/>
<target chassis="11" port="0x12"/>
<address type="pci" domain="0x0000" bus="0x00" slot="0x02" function="0x2"/>
</controller>
<controller type="pci" index="12" model="pcie-root-port">
<model name="pcie-root-port"/>
<target chassis="12" port="0x13"/>
<address type="pci" domain="0x0000" bus="0x00" slot="0x02" function="0x3"/>
</controller>
<controller type="pci" index="13" model="pcie-root-port">
<model name="pcie-root-port"/>
<target chassis="13" port="0x14"/>
<address type="pci" domain="0x0000" bus="0x00" slot="0x02" function="0x4"/>
</controller>
<controller type="pci" index="14" model="pcie-root-port">
<model name="pcie-root-port"/>
<target chassis="14" port="0x15"/>
<address type="pci" domain="0x0000" bus="0x00" slot="0x02" function="0x5"/>
</controller>
<controller type="virtio-serial" index="0">
<address type="pci" domain="0x0000" bus="0x03" slot="0x00" function="0x0"/>
</controller>
<interface type="network">
<mac address="52:54:00:4e:59:1d"/>
<source network="default"/>
<model type="virtio"/>
<address type="pci" domain="0x0000" bus="0x01" slot="0x00" function="0x0"/>
</interface>
<serial type="pty">
<target type="system-serial" port="0">
<model name="pl011"/>
</target>
</serial>
<console type="pty">
<target type="serial" port="0"/>
</console>
<channel type="unix">
<target type="virtio" name="org.qemu.guest_agent.0"/>
<address type="virtio-serial" controller="0" bus="0" port="1"/>
</channel>
<tpm model="tpm-tis">
<backend type="emulator" version="2.0"/>
</tpm>
<audio id="1" type="none"/>
<memballoon model="virtio">
<address type="pci" domain="0x0000" bus="0x05" slot="0x00" function="0x0"/>
</memballoon>
<rng model="virtio">
<backend model="random">/dev/urandom</backend>
<address type="pci" domain="0x0000" bus="0x06" slot="0x00" function="0x0"/>
</rng>
</devices>
</domain>
but that just prints:
EFI stub: Booting Linux Kernel...
EFI stub: Generating empty DTB
EFI stub: Exiting boot services...
and then hangs forever, constantly using 100% of 1 CPU core on my host machine, hopping back and forth between two different cores.
- Virt-Manager version 4.1.0
- libvirtd version 9.7.0
- QEMU emulator version 8.1.3
- Host OS: Nobara Linux 39, fully up-to-date as of 2024-05-28
- DietPi version: DietPi_RPi-ARMv8-Bookworm downloaded on 2024-05-28