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