๐ฆ S01E13 โ Stage One, Where Art Thou? โ
the boot loader is a strict landlord. file in wrong room? eviction. no notice. no recourse.
TL;DR
The Pi Zero 2 W has no EEPROM bootloader โ unlike the Pi 4/5, it loads bootcode.bin directly from the SD card via mask-ROM. The mask-ROM reads from the root of the FAT partition. Our build-rootfs.sh nested everything in a boot/ subdir. Stage 1 failed silently. Black silicon. Fix: flatten the tarball, lay all firmware files at FAT root.
The setup โ
Pi family bootloaders:
| Model | Stage-1 source |
|---|---|
| Pi 1, 2, 3 (BCM2835/2836/2837) | SD card FAT root โ bootcode.bin |
| Pi Zero 2 W (BCM2837 / RP3A0) | SD card FAT root โ bootcode.bin |
| Pi 4 (BCM2711) | EEPROM (with SD fallback) |
| Pi 5 (BCM2712) | EEPROM |
The Pi Zero 2 W sits in the legacy camp. If bootcode.bin isn't at the FAT root, the mask-ROM has nothing to chain to. The chip just sits there silently.
The crime scene โ
build-rootfs.sh line 122 (original):
FW_STAGE=/tmp/nosferato-fw
rm -rf "$FW_STAGE" && mkdir -p "$FW_STAGE/boot" # โ creates boot/ subdirThen files copied into $FW_STAGE/boot/bootcode.bin, etc.
Line 160:
tar czf /mnt/shared/boot.tgz boot/ # โ tarball with boot/ as top-levelThen build.sh step 4:
tar xzf "$SHARED_DIR/boot.tgz" -C "$BOOT_STAGE" # extracts as boot-stage/boot/...Step 8:
cp -R "$BOOT_STAGE/." "$BOOT_MOUNT/" # preserves boot/ on SDResult on the SD's FAT partition: /Volumes/BOOT/boot/bootcode.bin. The mask-ROM looks at /Volumes/BOOT/bootcode.bin โ not there โ boot fails โ no LED activity โ looks dead.
Boss fight: how do we know? โ
Empirical evidence: PINN's working SD card has all firmware files at the FAT root (no boot/ subdir). We could compare directly:
$ ls /Volumes/RECOVERY/ | head -10
bcm2708-rpi-b-plus.dtb
bcm2710-rpi-zero-2-w.dtb # โ at root
bootcode.bin # โ at root
config.txt # โ at root
kernel8.img # โ at root
start4.elf # โ at root
...Authoritative confirmation: Kali ARM's raspberry-pi-zero-2-w.sh uses the raspi-firmware Debian package, which puts files at /boot/firmware/ (which is the FAT partition's mount path on Bookworm, files appearing at the partition's root).
Mainline Debian's raspi-firmware package confirms the same โ staged at /usr/lib/raspi-firmware/, copied by flash-kernel to the mount point at FAT root.
So three independent sources agree: FAT root. Our nested subdir was the anomaly.
The fix โ
Seven-line patch in build-rootfs.sh:
- mkdir -p "$FW_STAGE/boot"
+ mkdir -p "$FW_STAGE"
- cp -v bootcode.bin start*.elf fixup*.dat "$FW_STAGE/boot/"
+ cp -v bootcode.bin start*.elf fixup*.dat "$FW_STAGE/"
- cp -v bcm2710-rpi-zero-2-w.dtb "$FW_STAGE/boot/"
+ cp -v bcm2710-rpi-zero-2-w.dtb "$FW_STAGE/"
- mkdir -p "$FW_STAGE/boot/overlays"
+ mkdir -p "$FW_STAGE/overlays"
- cp -v overlays/dwc2.dtbo ... "$FW_STAGE/boot/overlays/"
+ cp -v overlays/dwc2.dtbo ... "$FW_STAGE/overlays/"
- cp -v kernel8.img "$FW_STAGE/boot/"
+ cp -v kernel8.img "$FW_STAGE/"
- tar czf /mnt/shared/boot.tgz boot/
+ tar czf /mnt/shared/boot.tgz . # flat tarballโ Commit ef0aa1f
Boot sequence diagram โ
sequenceDiagram
participant ROM as Mask ROM (silicon)
participant FAT as FAT BOOT partition
participant GPU as VideoCore GPU
participant CPU as ARM CPU
participant Kernel
Note over ROM,FAT: Power on
ROM->>FAT: read /bootcode.bin
alt File at FAT root
FAT-->>ROM: bootcode.bin bytes
ROM->>GPU: bootstrap GPU
GPU->>FAT: read /start4.elf
FAT-->>GPU: start4.elf bytes
GPU->>FAT: read /config.txt, /cmdline.txt, /kernel8.img, dtb
GPU->>CPU: load kernel, jump
CPU->>Kernel: execute
else File missing or nested
FAT-->>ROM: ENOENT
Note over ROM: halt. LED unchanged.<br/>This is "the dead Pi".
endBonus: ALSO confirmed the user's hypothesis โ
User's exact words during E12:
"whatever the OS partition does wouldn't stop the Pi from booting if the BOOT partition is done correctly."
Truth. Boot stages 1-4 are independent:
| Stage | Failure mode | LED behavior |
|---|---|---|
| 1 โ mask-ROM โ bootcode.bin | File missing at FAT root | LED never lights |
| 2 โ bootcode.bin โ start.elf | start.elf missing | LED never lights |
| 3 โ start.elf โ kernel | kernel8.img missing | brief LED flash then off |
| 4 โ kernel โ init (rootfs mount) | rootfs broken | LED flashes during read attempts, then settles |
"Completely dark" = stage 1 failure = BOOT partition issue. Always. (We didn't know this at the time.)
The bigger lesson โ
The whole build-rootfs.sh followed a "stage everything under a tree that mirrors the Linux mount path" mental model. That model is right for apt install raspi-firmware (which gets unpacked under /boot/firmware/) but wrong for raw SD card preparation (where the FAT partition's root is what matters). Two different filesystems, two different conventions.
Final scene โ
$ diskutil mount /dev/disk4s1
$ ls /Volumes/BOOT/
bootcode.bin # โ at root, finally
kernel8.img # โ at root
bcm2710-rpi-zero-2-w.dtb # โ at root
overlays/ # โ at root (subdir, but at root)
config.txt
cmdline.txtUser: "led blinked, then stayed on (its still on), no connection."
LED activity. Stage 1 passed. The mask-ROM did its job, kernel loaded. Now, what's wrong with the kernel?
โ Next: E14 โ Fourteen Hours in the Forest