Faking HD Booting with RAID-1

Later editions of the Raspberry Pi family can boot off of USB storage devices, but they are, hm, choosy, and generally prefer flash media to spinning rust. (For details, see USB mass storage boot or Raspberry Pi 4 and 5 boot flow.) This is true even of the bootcode.bin only mode, which pulls bootcode.bin off an SD card which will then in turn find the boot partition on another device. Often one has to resort to stunts like “try to boot, let the external drive spin up, and then quickly power cycle before the drive can spin down”. This stinks.

A hack more forgiving of the vagaries of media devices would be to put the whole firmware partition – from bootcode.bin through the kernel and initrd – on an SD card and the rest of the system on an external device. This works, but an SD card failure will be obnoxious, as the external device will not be bootable in its own right and will not contain the material needed for recovery if attached to another system.

We can overcome this with a little violence in the form of RAID-1.

  1. Image the boot device like normal.

  2. Mount both of the drive’s partitions (what the Pi will think of as /boot/firmware and /) on a spare machine.

  3. Move everything out of the /boot/firmware mount to a safe location.

  4. Unmount the target’s /boot/firmware.

  5. Grab a SD card and make a primary partition the same size as the target’s first partition (its /boot/firmware).

  6. Create a RAID-1 md array with 0.9 metadata (which goes at the end of the partition) composed of the target’s first partition and the SD card’s. That will be something like:

    sudo mdadm --create --verbose /dev/md0 --level=1 --raid-devices=2 /dev/sda1 /dev/sdb1
    

    You can check your work with cat /proc/mdstat.

  7. mkfs.vfat /dev/md0, mount it somewhere, and move back the contents of /boot/firmware.

  8. Save the relevant output of mdadm --detail --scan to the target’s /etc/mdadm/mdadm.conf.

  9. Use blkid to get the UUID of /dev/md0 and patch the target’s /etc/fstab:

    UUID=1234-5678  /boot/firmware  vfat    defaults          0       2
    

Verify that / is mounted by a topology-agnostic name (that is, UUID or PARTUUID) and matches what’s said in the target’s /boot/firmware/cmdline.txt.

  1. Now unmount everything, plug the external device and SD card into the Pi, and give it power.

    The device will load its firmware and the kernel off of the SD card, and the kernel will wait for the external device to report in before mounting the root filesystem.

This trick should work on any RasPi, even as early as the very first model. If the SD card dies, it’s a simple matter of recreating it with mdadm using the external device as reference: partition a new SD card, bring the md online (mdadm --assemble --run /dev/md0 /...) and then mdadm --fail and mdadm --remove the old device and mdadm --add the new SD card’s partition.