In this lesson, you will learn how a processor transitions from a blank state to a fully operational Linux environment by tracing the sequential handoffs between boot stages.
The Boot Chain Anatomy
When you apply power, the CPU doesn’t "know" how to run Linux yet. It begins in a highly constrained state where only a small, immutable piece of code is available. The multi-stage boot process is designed to incrementally expand the system's capabilities until it can load the kernel.
Stage 0: The ROM Bootloader
Execution begins in the Primary Bootloader, which is physically etched into the SoC’s Mask ROM. Because the external DRAM is not yet initialized, this code runs in internal SRAM. Its job is strictly limited: identify the boot media (e.g., eMMC, SD card, or NAND), copy the next stage into SRAM, and jump to it.
Stage 1: The Secondary Bootloader (SPL/FSBL)
The Primary Bootloader loads the Secondary Program Loader (SPL). The SPL has a critical mission: hardware initialization. It must configure the memory controller, PLLs (clocks), and pin multiplexing. Once DRAM is initialized and stable, the environment is finally ready for the main bootloader.
Stage 2: The Main Bootloader (U-Boot)
This is the stage you likely interact with. U-Boot resides in DRAM and provides the logic to:
- Load the Kernel image (e.g.,
zImageoruImage) into memory. - Load the Device Tree Blob (DTB) describing the hardware layout.
- Pass control to the Kernel entry point.
The Handoff to Kernel Initialization
The transition occurs when the bootloader jumps to the kernel's memory address, typically passing a pointer to the ATAGs or the Device Tree. At this point, the bootloader is finished. The kernel assumes control of the MMU, sets up exception vectors, and initializes the device drivers defined in the DTB.
/* Conceptual transition flow */
void jump_to_kernel(void *kernel_addr, void *dtb_addr) {
// Disable interrupts, clear caches, and hand off
((void (*)(int, int, void *))kernel_addr)(0, machine_type, dtb_addr);
}
By segmenting the boot process, we ensure that we only use the memory-hungry kernel once we have successfully verified the integrity of the underlying hardware.
Key Takeaway: The multi-stage boot sequence is an incremental bootstrapping process where each stage prepares the environment for the next, moving from immutable internal ROM to the full-featured Linux kernel.