The Many Paths to init, Part 3: The Embedded Frontier

While the PC and server world has evolved towards the simplicity of Unified Kernel Images, the embedded systems domain—dominated by ARM and RISC-V architectures—operates under a completely different set of rules. Here, the boot process is dictated by resource constraints, non-discoverable hardware, and a relentless focus on cost optimization.

 

The Multi-Stage Ascent from Silicon to RAM

 

The boot process on a typical System-on-Chip (SoC) is a multi-stage climb, with each loader establishing a more capable environment for the next. This is a direct consequence of the hardware’s initial memory limitations.

Raghu Bharadwaj

Known for his unique ability to turn complex concepts into deep, practical insights. His thought-provoking writings challenge readers to look beyond the obvious, helping them not just understand technology but truly think differently about it.

His writing style encourages curiosity and helps readers discover fresh perspectives that stick with them long after reading

  • Stage 0: Boot ROM: Execution begins with immutable code etched directly into the SoC’s silicon. This Boot ROM is the ultimate root of trust. Its job is minimal: perform basic setup and search a predetermined sequence of boot devices (eMMC, SD card, etc.) for the next-stage loader. It loads this next stage into the SoC’s small, on-chip Static RAM (SRAM).

 

  • Stage 1: Secondary Program Loader (SPL): The on-chip SRAM is often too small (just a few kilobytes) to hold a full-featured bootloader. Therefore, a tiny intermediate loader, the SPL, is loaded first. The SPL has one critical function: to initialize the main system Dynamic RAM (DRAM) controller.

 

  • Stage 2: Main Bootloader: Once the much larger off-chip DRAM is available, the SPL loads the full-featured bootloader into it. This is typically Das U-Boot or its modern alternative, Barebox. This environment is far more powerful, providing an interactive shell, filesystem support, and networking capabilities. Its final task is to load the Linux kernel and hand over control.

 

U-Boot vs. Barebox: A Tale of Two Philosophies

 

While U-Boot and Barebox serve the same function, they represent different design philosophies.

  • U-Boot is the long-standing industry standard, known for its vast hardware support. Its configuration and scripting model is powerful but idiosyncratic, relying on a set of environment variables stored in non-volatile memory.

 

  • Barebox, which began as a fork of U-Boot, was created with the explicit goal of adopting a more Linux-like design. It provides a true shell environment where scripts are actual files, incorporates a Linux-style driver model, and even presents hardware resources through a virtual filesystem (e.g., /dev/mem). This makes development more intuitive for those already familiar with the Linux kernel.

 

The Device Tree Blob (DTB): Describing the Undiscoverable

 

Unlike the PC world with its self-enumerating buses like PCI, the hardware peripherals on an SoC (UARTs, I2C controllers, etc.) are at fixed memory addresses and cannot be discovered by the kernel at runtime.

The Device Tree is the solution. It is a data structure, written in a human-readable text file (.dts), that explicitly describes all the hardware on a specific board: what peripherals exist, their memory addresses, their interrupt connections, and other properties. This file is compiled into a compact Device Tree Blob (.dtb). The bootloader loads this .dtb into memory alongside the kernel and passes a pointer to it. The kernel then parses this data to learn what hardware it is running on, allowing a single, generic kernel binary to support a wide variety of boards.

From the resource-constrained world of embedded devices, we next turn to even more specialized platforms. In Part 4, we will examine the highly controlled boot flows of Android, IBM Z mainframes, and QEMU/KVM virtual machines.

Recent Posts

The Many Paths to init, Part 5: Unifying Themes

In this final installment of our series, we synthesize our exploration of diverse Linux boot processes by examining two critical, cross-platform themes: securing the chain of trust and ensuring system resiliency through atomic updates

Read More »

The Many Paths to init, Part 2: The PC and Server Revolution

In the first part of our series, we established a four-stage framework for understanding any boot process. Now, we apply that model to the modern x86-64 PC and server, a world that has been reshaped by the move from the legacy BIOS to the Unified Extensible Firmware Interface (UEFI).

Read More »

The Many Paths to init, Part 2: The PC and Server Revolution

In the first part of our series, we established a four-stage framework for understanding any boot process. Now, we apply that model to the modern x86-64 PC and server, a world that has been reshaped by the move from the legacy BIOS to the Unified Extensible Firmware Interface (UEFI). This shift has driven a clear trend towards simpler, more secure, and more atomic boot processes.

From BIOS to a Filesystem-Aware Firmware

The legacy BIOS was a simple piece of firmware. After its Power-On Self-Test (POST), its only job was to read the first 512 bytes of a disk—the Master Boot Record (MBR)—and execute whatever code it found there. This tiny space forced a complex chain of loaders just to get to the point where a bootloader like GRUB could understand a filesystem.

Raghu Bharadwaj

Known for his unique ability to turn complex concepts into deep, practical insights. His thought-provoking writings challenge readers to look beyond the obvious, helping them not just understand technology but truly think differently about it.

His writing style encourages curiosity and helps readers discover fresh perspectives that stick with them long after reading

UEFI is fundamentally different. It is a miniature operating system with its own drivers, shell, and, most importantly, the built-in ability to read standardized filesystems like FAT32. This capability led to the creation of the EFI System Partition (ESP), a dedicated FAT-formatted partition that acts as a universal, OS-agnostic hub for boot files. A bootloader is no longer a piece of code in a boot sector; it’s a standard executable file (e.g., grubx64.efi) that the firmware can find and run directly from the ESP.

 

Bypassing the Bootloader: EFI Stub and Unified Kernel Images (UKIs)

 

The power of UEFI opens the door to even simpler boot methods that can bypass a traditional bootloader entirely.

  • Direct Kernel Execution (EFI Stub): The Linux kernel can be compiled with a feature called the “EFI stub” (CONFIG_EFI_STUB=y). This embeds a small UEFI-compliant program into the kernel binary itself, allowing the UEFI firmware to execute the kernel directly. Using the efibootmgr tool from a running system, an administrator can create an entry in the firmware’s NVRAM that points directly to the kernel file on the ESP, completely bypassing GRUB. However, this method can be fragile, as some firmware implementations have bugs that prevent them from correctly passing necessary command-line arguments to the kernel
  • Unified Kernel Images (UKIs): The UKI is the modern solution to these challenges. A UKI is a single, self-contained UEFI application that bundles all necessary boot components—the EFI stub, the Linux kernel, the initramfs, and the kernel command line—into one file. This atomic approach offers three key advantages:
  1. Atomicity: The kernel and its critical dependencies are updated as a single unit.
  2. Robustness: Embedding the command line directly into the file bypasses firmware bugs related to passing arguments.
  3. Security: The entire UKI file can be cryptographically signed. UEFI Secure Boot then verifies this single signature, closing a major security hole where an attacker could modify an unsigned initramfs without being detected.

The nmbl Project: The Bootloader-less Philosophy in Practice

 

The nmbl (“no more bootloader”) project, championed by Marta Lewandowska, is a practical initiative to make the UKI-based, bootloader-less paradigm the default for mainstream distributions like Fedora. The project argues that traditional bootloaders like GRUB add unnecessary complexity, duplicate functionality already in the kernel (like filesystem drivers), and represent a significant and less-scrutinized attack surface. By replacing GRUB with a directly bootable UKI, nmbl aims to deliver a faster, more secure, and more maintainable boot process that leverages the robust and rapidly evolving Linux kernel as the bootloader itself.

The streamlined, secure, and atomic boot process of the modern PC stands in stark contrast to the resource-constrained world of embedded systems. In our next article, we’ll explore the multi-stage boot process of ARM and RISC-V devices.

Recent Posts

The Many Paths to init, Part 5: Unifying Themes

In this final installment of our series, we synthesize our exploration of diverse Linux boot processes by examining two critical, cross-platform themes: securing the chain of trust and ensuring system resiliency through atomic updates

Read More »

The Many Paths to init, Part 2: The PC and Server Revolution

In the first part of our series, we established a four-stage framework for understanding any boot process. Now, we apply that model to the modern x86-64 PC and server, a world that has been reshaped by the move from the legacy BIOS to the Unified Extensible Firmware Interface (UEFI).

Read More »