Early boot phase- very bare bones, access only to the microprocessor and some on chip static memory, no modules available to work with DRAM/eMMC etc
Finally, the bootloader puts the kernel in main memory, passes information about the hardware and an ASCII string and exits.
Phase 1- ROM Code
Earlier, the bootloader was simply placed in a ROM which contained the address pointing to the processor’s reset vector. It copied itself to the main memory, executed the kernel.
Today, the code is placed on the SoC. This is immutable. This code tried to load code from the first sectors of the flash(may be connected via SPI)/eMMC(MLO file on first partition of eMMC). If all fails, the code looks for boot from USB/UART.
Phase 2- SPL
Responsible for loading the third stage program loader(TPL) in main memory(DRAM). May use preprogrammed offsets from the flash memory. Can utilize u-boot.bin(to start U-Boot).
Phase 3- TPL
TPL loads the kernel, initramDisk and FDT(Flattened Device Tree blob).
Moving from bootloader to kernel
The bootloader may pass to kernel the following:
- A number unique to SoC
- Kernel command line- Basic ASCII string containing info such as device containing root file system
- Location and size of DT blob
- Basic hardware details
- Location and size of initrd
Initrd and InitramFS
The bootloader will load the kernel and initial root file system image into memory and then start the kernel, passing in the memory address of the image of the initial root file system. At the end of its boot sequence, the kernel tries to determine the format of the image from its first few blocks of data, which can lead either to the initrd or initramfs scheme.
In the initramfs scheme, the kernel executes /init as its first process that is not expected to exit. This may be compared to initrd where the first executed process(after decompression) is expected to mount the real file system and then exit.(/linuxrc)