uboot USB-disk reboot hang on RPI2 & workaround

Poul-Henning Kamp phk at phk.freebsd.dk
Tue Oct 15 14:19:03 UTC 2019


I wanted to use an RPI2 with two 1TB USB disks as offline backup
and all those parts worked fine.

The disks are obviously plugged into a powered USB hub.

What didn't work fine was rebooting.

In the end I boiled it down to the following:

Booting after power-on always worked.

If I interrupt uboot and give it the 'reset' command, it fails to reboot:

        MMC:   mmc at 7e300000: 1
        Loading Environment from FAT... In:    serial
        Out:   vidconsole
        Err:   vidconsole
        Net:   No ethernet found.
        starting USB...
        Bus usb at 7e980000: scanning bus usb at 7e980000 for devices... 7 USB Device(s) found
               scanning usb for storage devices... 2 Storage Device(s) found
        Hit any key to stop autoboot:  0 
        MMC Device 0 not found
        no mmc device at slot 0
        switch to partitions #0, OK
        mmc1 is current device
        Scanning mmc 1:1...
        Found EFI removable media binary efi/boot/bootarm.efi
        libfdt fdt_check_header(): FDT_ERR_BADMAGIC
        Scanning disk mmc at 7e300000.blk...

Then after a couple of seconds:

        Scanning disk usb_mass_storage.lun0...

and then it just stops.

So obviously this is entirely a uboot problem.

If I plug in two 64GB flash-sticks, the problem is not there, so
it is probably some kind of timing related to disk-spinup.

I tried 12.0-R, 12.1-SNAP and 13.0-SNAP, same problem everywhere.

Some experimentation finally revealed a usable workaround:

If I interrupt uboot, and give it the `usb stop` command before
`reset`, then it reliably resets and boots the kernel.

I tried to find a way to write a file to the SD card with instructions
to uboot, but utterly failed to get it to react to anything.

(Theory:  It tries to load env from mmc0 where the RPI2 uses mmc1 ?)

In the end this py3 script became my workaround, it patches the
u-boot.bin binary to change the built in preboot variable:

        #!/usr/bin/env python3

        import sys

        assert len(sys.argv) == 3
        a = open(sys.argv[1], "rb").read()
        a = bytearray(a)
        idx = a.find(b'preboot=usb start')
        assert idx > 0
        print(idx, a[idx:idx+18])
        a[idx + 14:idx + 17] = b'op '
        print(idx, a[idx:idx+18])
        open(sys.argv[2], "wb").write(a)

Poul-Henning


-- 
Poul-Henning Kamp       | UNIX since Zilog Zeus 3.20
phk at FreeBSD.ORG         | TCP/IP since RFC 956
FreeBSD committer       | BSD since 4.3-tahoe
Never attribute to malice what can adequately be explained by incompetence.


More information about the freebsd-arm mailing list