The Embedded Linux Boot Chain
July 30, 2026 · – visitors
Last time I wrote about DFU as a way to flash firmware over USB. That post skipped a question worth answering on its own: what actually happens between pressing the power button and a shell prompt showing up? DFU is just one branch off this path, so it's worth walking the whole thing once.
The stages
Drawn as a Mermaid flowchart, the chain (with DFU's place in it) looks like this:
flowchart TD
A[Power-on / Reset] --> B[Boot ROM<br/>immutable, on-chip]
B --> C{Valid image on<br/>boot media?}
C -->|No / forced| D[ROM recovery mode<br/>UART / USB]
C -->|Yes| E[SPL<br/>first-stage bootloader]
E --> F[U-Boot<br/>second-stage bootloader]
F --> G{Enter DFU?}
G -->|Yes| H[DFU mode<br/>waiting for firmware over USB]
G -->|No| I[Load kernel + device tree]
I --> J[Linux kernel]
J --> K[Mount root filesystem]
K --> L[init / systemd]
And rendered:
Boot ROM
Baked into the silicon at manufacturing time — nothing about it can be changed after the fact. Its only job is to find something bootable on one of a small set of boot media (eMMC, SD, QSPI flash, sometimes USB) according to boot-mode pins or eFuses, and jump to it. If it can't find anything valid, most SoCs fall back to a minimal UART or USB recovery mode at this stage — the very first place you can talk to the chip at all.
SPL
Short for Secondary Program Loader (U-Boot's term for it; other vendors call it FSBL or similar). It runs from a small amount of on-chip SRAM, before DRAM is even initialized, so it has to be tiny. Its main job is exactly that: bring up DRAM, then load the next stage — full U-Boot — into it.
U-Boot proper
This is the bootloader most people mean when they say "bootloader." It has drivers, a shell, environment variables, network support, and a command interpreter. It's also where DFU actually lives — running dfu 0 mmc 0 (or similar) drops U-Boot into DFU mode instead of continuing the normal boot, which is the mode dfu-util talks to from the host side. Otherwise, it loads the kernel image and device tree blob into memory and jumps to the kernel.
Kernel and userspace
The kernel decompresses itself, brings up the console, probes hardware using the device tree it was handed, and mounts a root filesystem — often the same eMMC or SD card the bootloader booted from, sometimes NFS during development. Once the root filesystem is mounted, the kernel hands off to PID 1 — usually systemd on a Yocto-built image — and that's where "userspace" actually starts.
Why this matters for DFU
DFU only makes sense once you see where it sits: it's a detour U-Boot can take instead of loading the kernel, not a separate thing bolted on top. That's also why DFU can't rescue every failure mode — if the boot ROM itself can't find a valid SPL, you never reach U-Boot at all, and you're relying on whatever recovery mode the boot ROM supports instead (which varies a lot by vendor and is a good topic for another post).
Further reading
- U-Boot: Generic SPL framework — how SPL is built and what it's responsible for.
- Trusted Firmware-A: Firmware Design — the more elaborate multi-stage boot flow (BL1/BL2/BL31/BL32/BL33) used on many modern Arm SoCs with a secure boot chain, which sits underneath U-Boot on those platforms.
Related Reading
- What Is a Device Tree? — how hardware is described to the kernel
- What Is DFU? — flashing firmware over USB when there is no other way in
Comments