Cover image for SoC Boot Process

SoC Boot Process


Timeline

Timeline

2025-12-26

init

This article introduces the complete boot process of an SoC from power-on to loading the operating system, detailing the BootROM's hardware initialization and the mechanism of loading programs into internal SRAM via Bootstrap Pins. Addressing the limited capacity of internal SRAM, it further discusses the uboot relocation and SPL scheme, and uses Rockchip as an example to analyze the division of responsibilities where TPL handles system hardware initialization and SPL loads the uboot and trust images.

BootROM

Generally, SoC manufacturers embed a small ROM inside the SoC, which contains the power-on boot code (once solidified, it can never be changed, as it is built into the chip during manufacturing); this code is called BootROM, also known asPrimary Boot Program

After power-on, the SoC manufacturer’s BootROM takes control of the system first. It initializes the hardware and then loads the program into SRAM.

Initialize Hardware

  • CPU Configuration
  • Disable Watchdog
  • Initialize Clock
  • Initialize some peripherals (such as USB Controller, MMC Controller, Nand Controller, etc.);

Load Program into SRAM

A new SoC typically hasexternal storage devices attached(eMMC, Nand, Nor, SDCard, etc.) and memory (SDRAM, DDR, etc.).

Then we need to burn a program for the CPU to execute. Burning a program essentially means writing theexecutable binary filetoan external storage device(such aseMMC、Nand、SDetc.). When the system powers on, it willread them into memory for execution

After power-on, the first to take over the system is the SoC manufacturer’s BootROM. Other executable programs (u-boot, Kernel) are placed (burned) onto external storage. Therefore, besides initializing the hardware environment, the BootROM code also needs to read the next executable program from external storage into memory for execution.

Since it is read into memory for execution, can this memory be our onboard DDR?

Theoretically, yes, but the DDR controller designed by the SoC manufacturer generally supports many types of DDR devices and provides a compatibility list. How could the SoC manufacturer possibly know which specific memory is used on the user’s PCB?

Therefore, directly reading the external executable program into DDR is obviously not very friendly. So generally speaking,the SoC will have an internal small-capacity SRAMThe BootROM reads the external executable program from external storage and places it into SRAM for execution

So, from which specific storage device does the BootROM read the binary file?

SoC manufacturers generally support multiple boot methods, such as:

  • Reading from eMMC
  • Reading from SDCard
  • Reading from Nand Flash, etc.

When powered on, it needs to be told which peripheral to use to read the subsequent boot binary file;

The typical design approach is to have a set of Bootstrap Pins. When powered on, the BootROM samples the levels of these IOs to determine which external memory to load the subsequent executable file from. For example, with 2 IOs, 2’b00 indicates booting from Nand, 2’b01 indicates booting from eMMC, 2’b10 indicates booting from SDCard, etc.;

After the BootROM reads these values, it initializes the corresponding peripheral and then reads the code to be executed later. These IOs are generally implemented as onboard DIP switches to adjust the chip’s boot method;

Here, when reading the burned binary, some details need attention. For example, the SoC manufacturer tells you that you need to initialize the SDCard as a certain file system and then put the content in for it to work, becausea file system is a way to organize files, not a raw partition; youneed to put it in according to file system A, and the SoC’s BootROM reads it out according to file system A, so that they can be consistent

SPL

After the chip is powered on, the BootROM determines from which memory to read an executable binary file into SRAM and execute it based on the Bootstrap Pins. Theoretically, this binary file could be ouru-boot.binfile; that is, the BootROM directly loadsu-boot.bin

Theoretically, this is the case, but there is a problem: SRAM is expensive. Generally, the on-chip SRAM of SoCs is not very large, typically ranging from 4KB, 8KB, 16KB… to 256KB. However, the compiled u-boot is very large, several hundred KB, and cannot fit.

What to do if it doesn’t fit? There are two methods:

  • Assume the on-chip SRAM is 4KB,the first 4KB program of uboot implements the relocation of uboot, that is,copy uboot to SDRAM for execution
  • Create a smaller boot program,first let BootROM load this small program, and then this small boot loads uboot;

Scheme 1: uboot relocation

For example, our uboot is 400KB, SRAM is 4KB, and external SDRAM is 64MB;

If using the first scheme, the first 4KB of uboot is loaded into SRAM for execution, and uboot is truncated, we need toensure that within the first 4KB code of uboot, the onboard SDRAM is initialized, the entire uboot is copied to SDRAM, and then jump to SDRAM for execution

Scheme 2: SPL

For the second scheme, we make a small uboot, which is calledSPLSecondary Program Loader), it is very very small (smaller than SRAM size), itis first loaded into SRAM by BootROM for execution, and the main thing SPL does is toInitialize the memory controller, then read the actual large u-boot from external storage into SDRAM, and then jump to the large u-boot.

Boot Process
Boot Process

As shown in the figure above:

  1. After power-on, BootROM starts executing, initializes the clock, disables the watchdog, disables cache, disables interrupts, etc., determines the boot device based on the Bootstrap Pin, and initializes peripherals;
  2. Use the peripheral driver to read the SPL from memory;

---------------- The above part is the responsibility of the SoC manufacturer, the following is what the user needs to do ----------------

  1. The SPL is read into SRAM for execution; at this point, control has been transferred to our SPL;
  2. The SPL initializes the external SDRAM;
  3. The SPL uses the driver to read u-boot from external storage and place it into SDRAM;
  4. Jump to the u-boot in SDRAM for execution;
  5. Load the kernel;

In practice, many issues need to be considered:

  • Does the link address during compilation need to be position-independent?
  • Is there any overlap between the SPL code and the u-boot code? If so, does it mean that what the SPL has executed will be executed again when jumping to u-boot?
  • In specific cases, which hardware needs to be configured? How to configure it?

Rockchip Boot Flow

For different solutions, Rockchip provides two different bootloader methods, with completely different steps and generated image files.

  • TPL/SPL Loading: Using the TPL/SPL provided by Rockchip (the small U-Boot mentioned above), this method is fully open-source;
  • Official Firmware Loading: Using Rockchip idbLoader, which consists ofRockchip rkbin project’sRockchip ddr init binandminiloader bincombined, this method is not open-source;

We introduced SPL above, so what is TPL? Actually, it separates the part ofthe SPL that initializes hardware like SDRAM, and that independent part is TPL. So let’s summarize:

  • TPLisTarget Program Loader, that isthe chip-level initialization processAt this point, the code is all based on the chip platform part. It performs DDR initialization and some other system configurations during the boot process, so that the subsequent SPL can run correctly;
  • SPLisSecondary Program Loader, it reads from the storage devicereads the trust (such as ATF/OP-TEE) and uboot binary files, loads them into system memory, and runs them, thereby booting the complete operating system

The difference between TPL and SPL lies in their different responsibilities. TPL is mainly responsible for initializing system hardware, while SPL is responsible for loading and running other software components, such as trust and uboot.

In addition, in some special cases, such as encrypted boot or secure boot mode, TPL may also perform other additional tasks.

Boot stage

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
+--------+----------------+----------+-------------+---------+
| Boot | Terminology #1 | Actual | Rockchip | Image |
| stage | | program | Image | Location|
| number | | name | Name | (sector)|
+--------+----------------+----------+-------------+---------+
| 1 | Primary | ROM code | BootROM | |
| | Program | | | |
| | Loader | | | |
| | | | | |
| 2 | Secondary | U-Boot |idbloader.img| 0x40 | pre-loader
| | Program | TPL/SPL | | |
| | Loader (SPL) | | | |
| | | | | |
| 3 | - | U-Boot | u-boot.itb | 0x4000 | including u-boot and atf
| | | | uboot.img | | only used with miniloader
| | | | | |
| | | ATF/TEE | trust.img | 0x6000 | only used with miniloader
| | | | | |
| 4 | - | kernel | boot.img | 0x8000 |
| | | | | |
| 5 | - | rootfs | rootfs.img | 0x40000 |
+--------+----------------+----------+-------------+---------+

The boot stage involves multiple image files:

  • The BootROM in stage one is provided by the SoC manufacturer;
  • Stage two method requires providing aidbloader.img
  • Stage three is actually the uboot image file. There are two types here:uboot.img (also needs to be paired with trust.img)andu-boot.itb (this is because it has already packaged ATF into it); besides both containing the original u-boot.bin binary file, these two files also contain some other things, which can beidbloader.imgIdentify, then load;
  • Stage four and stage five are the kernel image and root filesystem;

When we discuss booting from eMMC/SD/USB drive/network, they involve different concepts:

  • The first stage is always in BootROM, which loads the second stage and may load the third stage (when the SPL_BACK_TO_BROM option is enabled);
  • Booting from SPI flash means the second and third stage firmware (only SPL and U-Boot) are in SPI flash, while the fourth/fifth stages are elsewhere;
  • Booting from eMMC means all firmware (including stages two, three, four, and five) are in eMMC;
  • Booting from SD Card means all firmware (including stages two, three, four, and five) are in the SD Card;
  • Booting from USB drive means the fourth and fifth stage firmware (excluding SPL and U-Boot) are on the disk, optionally including only the fifth stage;
  • Booting from Net/TFTP means the fourth and fifth stage firmware (excluding SPL and U-Boot) are on the network.

idbloader.img

The idbloader.img file is a Rockchip-format preloader that works when the SoC boots, and it contains:

  • The IDBlock header known by the Rockchip BootROM;
  • The DDR initialization program, loaded into SRAM by BootROM and running inside SRAM;
  • The next-stage loader, loaded by BootROM and running on DDR;

u-boot.img

u-boot.bin is the raw binary image generated after compiling the U-Boot source code, which can be directly flashed into the device’s flash memory. Meanwhile, u-boot.img is generated bymkimageThe tool adds a header to the u-boot.bin, which may also include additional data such as boot parameters and kernel image addresses.

Therefore, byusing u-boot.img instead of u-boot.bin, the boot ROM can more easily recognize the U-Boot image and better guide U-Boot to boot correctly on the device.

u-boot.itb

u-boot.itb is actually another variant of u-boot.img, also built with mkimage. In addition to the two files compiled from U-Boot source code, u-boot.dtb and u-boot-nodtb.bin, it also includes ARM Trusted Firmware such as bl31.elf, bl32.bin, and tee.bin. Among these, bl31.elf is mandatory, while bl32.bin and tee.bin are optional and can be omitted.

trust.img

ARM64 SoCs also need to compileATF (ARM Trust Firmware)ATF is mainly responsible for switching the CPU from secure EL3 to EL2 before booting U-Bootthen jumping to U-Boot, and after the kernel starts, it is responsible for booting other CPUs

ATF completely and uniformly divides the system boot from the lowest level, placing the secure monitor functionality in bl31. Thus, after the system fully boots, when an SMC or other interrupt is triggered in the CA or TEE OS, it first traverses the services registered in bl31 to determine the specific handler. This allows unified management and allocation of all critical SMC or interrupt operations in the system. The block diagram of the entire ATF code boot process is as follows:

ATF
ATF

Flowchart of external U-Boot loading provided by Rockchip
Flowchart of external U-Boot loading provided by Rockchip

As shown in the figure above:

  • Boot flow 1 is the typical Rockchip boot flow using the Rockchip miniloader;
  • Boot flow 2 is used for most SoCs, using U-Boot TPL for DDR initialization and SPL to load the u-boot.itb file;

Note 1: If loader1 has multiple stages, the program returns to BootROM, which loads and runs the next stage. For example, if loader1 is TPL and SPL, BootROM first runs to TPL, TPL initializes DDR and returns to BootROM, then BootROM loads and runs SPL.

Note 2: If trust is enabled, in secure mode (EL3 in ARMv8), loader1 needs to load both trust and U-Boot, then run to trust. Trust initializes in non-secure mode (EL2 in ARMv8) and runs to U-Boot.

Note 3: For trust (in trust.img or u-boot.itb), armv7 only has a tee.bin with or without TA, while armv8 has bl31.elf and optionally includes bl32.

Note 4: In boot.img, the content can be Linux’s zImage and its dtb, optionally grub.efi, or it can be an AOSP boot.img, with ramdisk optional.

References