Search code examples
raspberry-piqemudevice-tree

Emulate Raspberry Pi zero W with Qemu failed due to missing dtb


I am trying to emulate a Raspberry Pi zero W with Qemu based on an image I used on a real Raspberry Pi zero W.

The command I am using is:

sudo qemu-system-arm \                                                                                                                                                       
-kernel ./qemu-rpi-kernel/kernel-qemu-4.9.59-stretch \
-append "root=/dev/sda2 panic=1 rootfstype=ext4 rw" \
-hda pi_zero_kinetic_raspbian.qcow \
-cpu arm1176 -m 512 \
-M versatilepb \
-no-reboot \
-serial stdio \
-net nic -net user \
-net tap,ifname=vnet0,script=no,downscript=no

But Qemu complain that Error: unrecognized/unsupported machine ID (r1 = 0x00000183)

So added this option:

-dtb linux/arch/arm/boot/dts/bcm2835-rpi-zero-w.dts

But In this case:

qemu-system-arm: Unable to copy device tree in memory
Couldn't open dtb file qemu-rpi-kernel/tools/linux/arch/arm/boot/dts/bcm2835-rpi-zero-w.dts

So I tried to compile the dts in order to get the dtb with:

dtc -O dtb -o bcm2835-rpi-zero-w.dtb bcm2835-rpi-zero-w.dts

But the compilation fail and I get:

Error: bcm2835-rpi-zero-w.dts:13.1-9 syntax error
FATAL ERROR: Unable to parse input tree

I couldn't find any tutorial about Pi zero and all the tutorial about the first Rapsberry Pi seems to be outdated. I am not sure that compiling the dtb on my own is the way to go. Any input would be appreciated, thanks!


Solution

  • This isn't going to work, because the QEMU option "-M versatilepb" says "emulate a VersatilePB development board", which will not run a kernel that is intended to boot on the Pi Zero. The versatilepb board does not have devices in the places that a Pi Zero DTB file says they are, so if you provide the kernel with a Pi Zero DTB then the kernel is going to crash immediately because it can't find anything where it expects.

    In general Arm devboards are not like x86 -- they are all different, and you can't just boot a kernel intended for one on a different one. This is in fact what the "unrecognized machine ID" error is telling you -- it's from the guest kernel, and it's saying "I can't boot on this board".

    You need to either:

    • use -M versatilepb and pass QEMU a kernel and dtb intended for that machine, not some other one
    • use some other -M option and a kernel and dtb that work with it (for instance we support 'raspi2' now for a RaspberryPi 2 board model, with some notable caveats including "no USB, no networking")

    Also, as you seem to have discovered, -dtb wants a DTB file (the compiled binary), not a DTS file (the source).