When an ARM processor powers on, it goes through a process called booting to load and start executing the software that controls the system. This boot process has several key steps:
Reset
After power is applied, the processor begins executing code from a known reset vector location. This reset handler code is stored in on-chip ROM or configured from on-chip fuses. It sets up some basic hardware state, like stack pointers, and prepares to load code from boot memory.
Boot Sequence
The reset handler starts executing boot code from a boot memory device, usually flash memory. The early boot code is called the Primary Boot Loader (PBL) or First-Stage Boot Loader (FSBL). It does crucial setup like:
- Configuring SDRAM memory controllers
- Setting up board-specific details like clocks and power
- Initializing hardware peripherals
Once SDRAM is available, later-stage bootloaders can be loaded from flash or other storage into SDRAM and executed. These may include a Secondary Program Loader (SPL) and U-Boot.
U-Boot
U-Boot is an open-source bootloader used on many ARM boards. It provides crucial boot functions like:
- Initializing more complex peripherals like Ethernet, USB
- Mounting filesystems
- Loading Linux kernel, device tree, ramdisk from storage
- Passing kernel parameters, board info
U-Boot is highly configurable and includes commands to manage images in flash, set environment variables, and more.
Kernel Initialization
U-Boot loads the Linux kernel image and optional device tree blob into memory and passes control to the kernel entry point. The kernel then initializes itself and hardware:
- Sets up low-level hardware like interrupt controller
- Initializes memory management unit (MMU) and page tables
- Registers device tree to discover hardware
- Starts rest of core kernel subsystems
User Space Initialization
Once the kernel is up, it starts the user space. This includes:
- Mounting the root filesystem (initramfs/initrd)
- Starting the first user space process (init)
- Init setting up other services and programs
- Eventually starting a login prompt or GUI
At this point, the core OS is booted and ready for apps and user interaction.
Bootloaders
Several bootloader stages execute to bring up ARM cores from reset to fully booted software. Each handles specific phases of system initialization.
Reset Handler
The reset vector code runs first after reset. It is located in on-chip ROM or configured from fuses. It sets up minimal hardware state needed to run boot code.
Primary Bootloader (PBL)
The PBL runs immediately after reset and does crucial SoC setup:
- Enable caches, MMU, and clocks
- Configure SDRAM and memory interfaces
- Initialize basic peripherals
- Set up stack and globals
Afterward, later boot stages are run from SDRAM.
Secondary Program Loader (SPL)
The SPL provides additional setup after the PBL:
- More system initialization
- Initialize more complex peripherals
- Load U-Boot into SDRAM
U-Boot
U-Boot provides extensive boot support:
- Board-specific init
- Driver model for devices
- Networking stack
- Filesystems and storage
- Commands to manage flash
- Load and start Linux
Linux Boot Phases
The Linux kernel execution has several phases during boot:
Kernel Initialization
Sets up kernel core:
- Interrupt handling
- Early memory manager
- Scheduler, timers
- Kernel subsystems
Hardware Discovery
Enumerates hardware and resources:
- Register interrupt controllers
- Initialize device tree
- Detect and initialize buses, devices
Memory Management
Sets up full virtual memory support:
- Initialize page allocator, zones
- Set up page tables, TLB
- Enable MMU to switch to virtual addresses
User Space Init
Starts non-kernel programs:
- Mount root filesystem
- Launch init process
- Init starts services and daemons
Boot Options
There are many configurable options that control the ARM system boot process:
U-Boot Environment
U-Boot environment variables control many aspects of boot:
- bootcmd – Linux command line
- bootargs – Kernel parameters
- bootdelay – Timeout before auto boot
- ipaddr – Static IP configuration
Device Tree
The device tree blob provides hardware details to Linux:
- SoC identification
- Interrupt controller
- Bus topology and devices
Kernel Parameters
The Linux kernel supports many command line options:
- root – Root filesystem location
- rw/ro – Read-write or read-only mount
- init – Initial process to launch
- ramdisk – ramdisk for initramfs
Boot Optimizations
There are several ways to optimize ARM boot time:
- Use a minimalist initramfs/initrd
- Remove unnecessary drivers from kernel
- Parallelize driver initialization
- Use asynchronous kernel init calls
- Reduce U-Boot delay and ramdisk load time
- Store bootloaders in fast SPI flash
- Optimize SDRAM configuration
Newer ARM cores also include architectural options to accelerate boot:
- Trusted boot with TrustZone
- Boot over PCIe from host processor
- Fast restart without reset
With careful tuning, an optimized Linux boot on ARM can achieve start times under a second.