Search code examples
virtualizationqemuopenwrt

qemu can't start OpenWRT after Ubuntu upgrade


When I had Ubuntu 18.04 I stated OpenWRT with the following command:

qemu-system-arm -machine virt -cpu cortex-a15 -nographic -netdev bridge,id=lan,br=br-lan,helper=/usr/lib/qemu/qemu-bridge-helper -device virtio-net-pci,id=devlan,netdev=lan,mac=52:54:00:32:52:3a -netdev bridge,id=wan,br=br-wan,helper=/usr/lib/qemu/qemu-bridge-helper -device virtio-net-pci,id=devwan,netdev=wan,mac=52:54:00:35:04:84 -kernel openwrt-armvirt-32-zImage -drive file=openwrt-armvirt-32-root.ext4,format=raw,if=virtio -append root=/dev/vda rootwait

Now, after upgrading to Ubuntu 19.10, I can't start OpenWRT with qemu. The boot process stops due to the inability to mount the /dev/vda device:

[    0.358902] Concatenating MTD devices:
[    0.359031] (0): "0.flash"
[    0.359113] (1): "0.flash"
[    0.359193] into device "0.flash"
[    0.378013] rtc-pl031 9010000.pl031: rtc core: registered pl031 as rtc0
[    0.382185] NET: Registered protocol family 10
[    0.392266] Segment Routing with IPv6
[    0.392847] NET: Registered protocol family 17
[    0.394003] 8021q: 802.1Q VLAN Support v1.8
[    0.395030] 9pnet: Installing 9P2000 support
[    0.395488] Registering SWP/SWPB emulation handler
[    0.403133] rtc-pl031 9010000.pl031: setting system clock to 2020-01-02 08:17:06 UTC (1577953026)
[    0.415460] Waiting for root device /dev/vda...

What's wrong? Has something changed in the new version of qemu? Thank you.


Solution

  • My first guess is that you're running into a combination of a new enabled-by-default feature in the newer QEMU and a guest kernel bug where it gets confused by the device tree information advertising that new feature.

    Newer QEMU versions of the 'virt' board provide some devices, including an extension of the PCI window, at addresses above 4GB. This should be fine, because 32-bit non-LPAE kernels should ignore those addresses as unreachable, and continue to use the smaller PCI window that is below the 4GB mark. Unfortunately a bug in older versions of the Linux 32-bit Arm kernel meant they truncated the 64-bit address in the device tree and thought there was a clash with some other device, and refused to enable PCI at all. (There is probably a message about this further up in the part of the bootlog you don't quote in your question.)

    Possible fixes:

    • add -machine highmem=off to the QEMU command line, disabling the extra features
    • build the guest kernel with LPAE support
    • use a newer version of the guest kernel which has a fix for the address-truncation bug

    (Start with the first of those to check that my diagnosis is correct.)