π¦ S01E14 β Fourteen Hours in the Forest β
"I have become Death, destroyer of stack traces."
TL;DR
With E13's fix, the Pi finally booted to the kernel β but for fourteen hours afterwards, every step in userspace failed in a new way. Missing init system. Missing networking. Missing dbus. Wrong firmware filenames. Wrong nvram. Wrong silicon variant. rfkill soft-block. The breakthrough was abandoning manual file extraction and using Pi Foundation's apt repo instead. One apt install, the entire kernelβfirmwareβmodules triple resolves correctly, wlan0 registers, DHCP works, SSH works. The lesson: when a curated set exists, use it.
Cast β
| Role | Name |
|---|---|
| Protagonist | the Pi Zero 2 W |
| Antagonist | every default in debootstrap --variant=minbase |
| Mentor (offscreen) | Pi Foundation, who curated the apt repo we ignored |
| Recurring villain | "the BCM43436/BCM43430/CYW43436s naming hydra" |
| Final-boss-revealed-as-friend | firmware-brcm80211 from archive.raspberrypi.com |
β See full Cast and Bestiary.
Episode arcs β
Arc 1 β "Where is /sbin/init?" β
After E13, the Pi blinks then stays solid green. Looks alive but unresponsive. We capture the rootfs via dd on the SD card (it's still on the user's desk), mount it loopback in Multipass VM, run debugfs queries:
=== /sbin/init exists? (PID 1) ===
(empty)
=== /lib/systemd/systemd exists? ===
(empty)
=== installed packages β systemd / openssh / wpasupplicant ===
(empty)Nothing. No init. No systemd. No ssh. No wifi tools.
debootstrap --variant=minbase strips Priority: important packages. systemd is Priority: important, not Priority: required. So minbase has no init system. Kernel boots, tries /sbin/init, file doesn't exist, kernel panic ("No working init found"). Panic = LED frozen in last state β solid green.
The smoking gun
$ debugfs -R "stat /sbin/init" captured.img
/sbin/init: File not found by ext2_lookupβ Filed #388 β S01E14 issue. β Fix: --include=systemd-sysv,openssh-server,wpasupplicant,wireless-tools,ifupdown,isc-dhcp-client,net-tools,rfkill,parted,e2fsprogs,dbus added to debootstrap.
Arc 2 β "Where is /boot mounted?" β
Init installed, kernel boots, but rc.local doesn't fire firstboot.sh. Why? It checks [ -f /boot/nosferato-firstboot ] for the trigger marker. We put the marker on the FAT BOOT partition. But the FAT partition never mounted β /etc/fstab was the debootstrap default:
# UNCONFIGURED FSTAB FOR BASE SYSTEMSo /boot was a vestigial empty directory in the rootfs. Marker invisible. Firstboot never triggered.
β Fix: write a real fstab in build-rootfs.sh:
proc /proc proc defaults 0 0
/dev/mmcblk0p1 /boot vfat defaults,flush,nofail 0 0
/dev/mmcblk0p2 / ext4 defaults,noatime,errors=remount-ro 0 1Arc 3 β "Where are the kernel modules?" β
After fstab fix, /boot mounts, marker visible, firstboot.sh runs. But wifi still doesn't come up. We re-dd, re-mount, re-debugfs:
=== /lib/modules β kernel modules dir? ===
/lib/modules: File not found by ext2_lookupNo kernel modules. Pi kernel from raspberrypi/firmware's stable.tar.gz ships kernel image + module tree. We extracted the kernel image into the BOOT partition but forgot to copy the module tree into /lib/modules/<release>/ of the rootfs. Without modules: no vfat, no brcmfmac, no usb-host, nothing.
β Fix: copy /tmp/fw/modules/*-v8+/ β $ROOTFS_MNT/lib/modules/ during build-rootfs.sh.
Arc 4 β "Where does brcmfmac auto-load from?" β
Modules now present. Reflash, boot. We have wlan0. Wait β do we?
$ journalctl -k | grep -iE '(mmc1|brcmfmac|wlan)'
mmc1: new high speed SDIO card at address 0001
(nothing else)SDIO bus enumerates the wifi chip. But no brcmfmac probe. The udev cold-plug never fired a modprobe for the chip. Why?
We grep modules.alias for SDIO IDs:
$ grep brcmfmac modules.alias | grep '^alias sdio:'
alias sdio:c*v02D0d4345* brcmfmac # Pi 3B+
alias sdio:c*v02D0d4354* brcmfmac # Pi 3
alias sdio:c*v02D0dA9A6* brcmfmac # <-- CYW43436 (Pi Zero 2 W?)
... (32 entries total)Pi Zero 2 W's wifi chip reports 0xa9a6. Matches. Should auto-load. Doesn't.
This was the moment we stopped trusting udev and force-loaded the driver via /etc/modules-load.d/nosferato-wifi.conf:
brcmfmac
brcmutil
cfg80211β Fix: created the modules-load.d config + ensured systemd-modules-load.service runs early.
Arc 5 β "wpa_supplicant talks to dbus over what?" β
Wifi driver loaded! Reflash. Boot. wpa_supplicant.service starts:
wpa_supplicant: dbus: Could not acquire the system bus:
org.freedesktop.DBus.Error.FileNotFound -
Failed to connect to socket /run/dbus/system_bus_socket
wpa_supplicant: Failed to initialize wpa_supplicantNo dbus. wpasupplicant package only recommends dbus β and minbase doesn't install recommends. The systemd unit for wpa_supplicant needs dbus.
β Fix: added dbus to --include.
Arc 6 β "Why does the firmware say it loaded but the chip is silent?" β
dbus installed. wpa_supplicant starts cleanly. But the chip:
brcmfmac: F1 signature read @0x18000000=0x1541a9a6
brcmfmac: brcmf_fw_alloc_request: using brcm/brcmfmac43430-sdio for chip BCM43430/1
brcmfmac mmc1:0001:1: Direct firmware load for brcm/brcmfmac43430-sdio.raspberrypi,model-zero-2-w.bin failed with error -2
brcmfmac mmc1:0001:1: Direct firmware load for brcm/brcmfmac43430-sdio.bin failed with error -2-2 ENOENT. We have files named brcmfmac43436-sdio.bin from RPi-Distro. Driver wants brcmfmac43430-sdio.*. The chip's silicon ID maps to "43430" inside brcmfmac source, even though the Pi Foundation markets the chip as "BCM43436."
This was the naming hydra:
| Name | Where it comes from |
|---|---|
| BCM43436 | Pi Foundation marketing (the Pi Zero 2 W's chip) |
| BCM43430 | brcmfmac source-tree chip name (silicon family) |
| CYW43436s | Cypress (silicon vendor) β s suffix for rev 1.0 |
| cyfmac43430 | Debian's firmware-brcm80211 package β Cypress naming |
β Tried fix: symlinks brcmfmac43430-sdio.* β brcmfmac43436-sdio.*. Driver loads the file. Boot continues.
But the chip stays in HT Avail timeout β firmware loaded but the chip never enters HT clock state. Means: wrong firmware-for-chip-rev. The "43436" file we had was for a DIFFERENT silicon revision than our actual chip.
Arc 7 β "The Pi Foundation's chip ID is not the chip's chip ID" β
We dig deeper. Read brcmfmac source. Inspect the actual firmware blob bytes. Try the 43436s (with s suffix, for older rev). Try Debian's Cypress firmware (cyfmac43430-sdio.bin). Try Pi 3's nvram (brcmfmac43430-sdio.raspberrypi,3-model-b.txt) as a fallback. Each combination β different new failure mode.
After hours of trying combinations:
$ brcmfmac: brcmf_c_preinit_dcmds: Firmware: BCM43430/1 wl0: Jun 14 2023 07:27:45 version 7.45.96.s1 (gf031a129) FWID 01-70bd2af7 es7Chip started. preinit_dcmds succeeded. Wifi firmware running. But⦠wlan0 still didn't register. The driver completed preinit and then fell silent. No register_netdev. No interface. Wpa_supplicant has nothing to bind to.
Raspberry Pi forum thread t=380824 describes the exact symptom: firmware loads, no wlan0. Suggested cause: kernelβfirmware version skew.
Arc 8 β The breakthrough β
We stopped guessing. Ran proper research. Discovered the architecture every successful Pi distro uses:
archive.raspberrypi.com/debian is an apt repo. It ships:
linux-image-rpi-v8β Pi Foundation's arm64 kernel + matching modulesraspi-firmwareβ bootloader blobs, dtbs, initramfs hooksfirmware-brcm80211(Pi-curated, not Debian's) β the right wifi firmwareraspberrypi-sys-modsβ Pi-specific systemd units (sshswitch, display-backlight, etc.)
apt resolves dependencies. apt resolves kernelβmodules version match. apt resolves firmwareβchip-rev match. Everything we'd been hand-assembling, Pi Foundation pre-tested.
We added the repo to our chroot, ran apt install linux-image-rpi-v8 raspi-firmware firmware-brcm80211 raspberrypi-sys-mods, regenerated boot.tgz from the apt-installed /boot/firmware/, updated /etc/fstab to mount the FAT at /boot/firmware/ (Bookworm convention)β¦
β¦and the next flash gave us:
Jun 26 15:58:42 nosferato kernel: brcmfmac: brcmf_c_preinit_dcmds: Firmware: BCM43430/1 wl0: ...
Jun 26 15:58:43 nosferato systemd[1]: Expecting device sys-subsystem-net-devices-wlan0.device
Jun 26 15:58:43 nosferato systemd[1]: Found device sys-subsystem-net-devices-wlan0.device
Jun 26 15:58:43 nosferato systemd[1]: Started ifup@wlan0.service - ifup for wlan0wlan0 registered. First time in the whole saga.
Arc 9 β "rfkill: WLAN soft blocked" β
But wifi didn't transmit:
wpa_supplicant: rfkill: WLAN soft blocked
dhclient: send_packet: Network is downPi kernel default: wifi rfkill soft-blocked at boot (regulatory protection). Pi OS lifts it via raspi-config do_wifi_country. We don't have raspi-config. One-shot fix:
# /etc/systemd/system/nosferato-rfkill.service
[Unit]
Description=Nosferato β unblock wifi rfkill at boot
DefaultDependencies=no
Before=network-pre.target wpa_supplicant.service ifupdown-pre.service
After=local-fs.target
Wants=network-pre.target
[Service]
Type=oneshot
ExecStart=/usr/sbin/rfkill unblock all
RemainAfterExit=yes
[Install]
WantedBy=sysinit.targetβ Commit b28eeb9
The final ten minutes β
After hours of bug-hunting, the actual winning sequence was minutes:
- Apt-install
linux-image-rpi-v8 raspi-firmware firmware-brcm80211 raspberrypi-sys-modsβ 2 minutes. - Add
rfkill unblockoneshot β 30 seconds. - Reflash β 90 seconds.
- SSH in β instant.
~/Projects/neartrace-android-mvp nosferato* 1m 19s
β― ssh nt@192.168.0.129
nt@nosferato:~$ uname -a
Linux nosferato 6.12.75+rpt-rpi-v8 #1 SMP PREEMPT Debian 1:6.12.75-1+rpt1~bookworm (2026-03-11) aarch64π¦ NOSFERATO LIVES.
Final score β
| Stat | Number |
|---|---|
| Hours debugging | ~14 |
| Distinct bugs fought | 12 |
| Re-flashes | 8 |
| Diagnostic captures | 6 |
| GitHub issues filed | 2 (#387, #388) |
| Commits to fix | 11 |
| Lines of stale firmware files we no longer need | ~50 |
| Lines of script that survived | ~600 |
| Boot time (final) | 9 seconds |
| MAC address of the Pi | 2c:cf:67:a6:76:03 |
| IP from home router | 192.168.0.129 |
Lessons banked β
For ANY custom Pi distro: use the Pi Foundation apt repo. Don't hand-extract from upstream tarballs.
feedback_custom_pi_distro_lessons.md.debootstrap --variant=minbaseis too aggressive for embedded work. Always add back:systemd-sysv, dbus, openssh-server, wpasupplicant, wireless-tools, ifupdown, isc-dhcp-client, rfkill, net-tools.Mount FAT at
/boot/firmware/on Bookworm, not/boot/. apt upgrades break otherwise.The Pi kernel boots with wifi rfkill soft-blocked. Always add a
rfkill unblock alloneshot if you don't haveraspi-config.Silent driver failures are the hardest bugs. Always reach for
journalctl -D /path/to/captured/journal -b 0to see what the driver did say, not just what it didn't.debugfs -R "..."can read ext4 partitions without mounting β gold for diagnosing a dead SD card from another machine.
What's next β
- π§ Mgmt AP (
nosferato-mgmt) β uap0 virtual interface + hostapd + dnsmasq. Recipe verified, bake-in pending. - π Nexmon driver for monitor mode + injection.
- π USB OTG tether to the Android NearTrace app.
- π First-boot orchestrator for heavyweight install (tools, NSFAS-specific configs).
- π§Ή Source-level refactor of
build-rootfs.shβ fold the patch-in-place changes back into the source. Current script doesn't produce a clean working image from scratch; needs ~30 min refactor.
Saga close β
"Just files in the right places." β user, ten minutes after we logged in successfully.
The whole 14-hour saga, distilled. We did it from scratch. We did it ourselves. We did it the hard way. And we have the receipts.
β The Recipe β copy-paste this, never read the saga again β Bestiary β every bug, classified β Credits β external sources
Source links β
Issues β
- #386 β Hardware diagnosis (closed; misdiagnosis)
- #387 β bootcode.bin must live at FAT root
- #388 β rootfs needs init + ssh + wifi at build time
Commits (the war chronicle) β
ef0aa1fβ bootcode at FAT root (E13)c6199c9β device path env var + sudo keepaliveaf2d7feβ exact-label safety check (so we don't trash the RPi Imager DMG)69bccbdβ bake init + ssh + wifi at build time4fc58b6β copy kernel modules + nofail /boot34e88d1β dbus + force-load brcmfmac + drop g_multic54cd1eβ symlink brcmfmac43430 β brcmfmac43436 (the wrong fix)e5c9b94β Debian firmware-brcm80211 + Pi-Zero-2-W board nvram2a0ce5fβ drop dtoverlay=dwc2 + gpu_mem=16 (dead end)b28eeb9β rfkill unblock oneshot at boot (the final fix)
External β
- Raspberry Pi forum: missing wlan0 on Pi Zero 2 W Rev 1.0
- Raspberry Pi forum: regulatory.db fix
- RPi-Distro/firmware-nonfree (the right blobs)
- Kali ARM
raspberry-pi-zero-2-w.shbuild script β the apt-based pattern we eventually adopted - raspberrypi/linux issue #6317 β txcap_blob warning is cosmetic
Anime equivalents β
If this saga were an anime:
- Arcs 1-3 (init/fstab/modules): the training arc β recognize you're underprepared, fix your loadout.
- Arcs 4-7 (firmware names hydra): the false-victory arc β keep "winning" only to find the boss had a transformation phase.
- Arc 8 (apt repo): the mentor reveal β the entire technique you needed was sitting in
apt-get installthe whole time. - Arc 9 (rfkill): the final filler episode β small thing, fast fix, victory.
"Time stop. Your move is forfeit." β Dio Brando, JoJo's Bizarre Adventure. The Pi was the time-stopped victim. We were Dio.