I am using an RPi4 in a product and want to make a bootable USB image that users can connect to reflash the microSD card. My solution (normal/microSD card image includes script that makes sure boot order is USB first then microSD, updater/USB image runs script that triggers
/etc/rc.local) mostly works, but I am looking for a way to make it so that after flashing, the device can be rebooted without removing the USB storage device or changing the boot order stored in EEPROM (i.e. in case the update fails I want to be able to boot from USB again since the microSD card is not easily accessible). Is there a simple way I can add a step to the boot process to signal that I actually want to boot from a different device? Ideally, I wish there were an "override for next boot only" option that I could set in the EEPROM boot config (similar to pressing F11 during power-up on many PCs).
What I am currently trying to do is to have the updater (USB image) to check for a file on the microSD card that indicates that the card was just flashed/updated (and maybe including a timestamp). (The normal / microSD card image would delete this file upon booting.) If it's there, rather than continue booting from USB I'd like to boot from microSD instead. It seems very hard to "back-track" (e.g. change kernel boot parameters /
init=...), but doesn't NOOBS do something like this to allow choosing an OS to boot? (While I wait for answers here I think I'll go peek at NOOBS code to see if I can find out how it does that.)
FWIW I am using Raspberry Pi OS (formerly Raspian) on both images, but I have a lot of flexibility on the updater (e.g. could use Debian). Looks like there are some more hints at ways to boot here.
Possible solutions I have thought of so far:
- Modify bootloader settings after imaging. Problem with this is that if the freshly imaged microSD card doesn't boot properly the system will be "stuck" (always trying to boot the bad card). There are some interesting options in the RPi 4 bootloader configuration documentation:
ENABLE_SELF_UPDATE(maybe easier than running
rpi-eeprom-config) and the "Multiple bootable drives" section
cmdline.txtof USB device so that it uses the microSD card as the rootfs (similar to how normal Raspberry Pi OS resize script works as well as the method used in this example). I'm not quite sure this will work (won't it still try to load the kernel from the USB device?), but even if it does, it has a draw back that the
cmdline.txtfile will need to be reverted back after the stick is removed. This isn't a big deal if just imaging one device, but it would be a major nuisance if performing the update on one device and then another and another in sequence.
- Use some kind of boot manager (Das U-Boot?) See https://www.reddit.com/r/raspberry_pi/comments/gte2lp/raspberry_pi_4_uefi_boot/ & https://rpi4-uefi.dev/ (still reading about this -- might be the most promising solution path yet)