# Das U-Boot U-Boot is a popular and powerful bootloader. ## How it works The boot process is devided into 4 stages: * First stage bootloader * Second stage bootloader * U-Boot * Kernel ![Bootloader stages](../img/bootloader-stages.png) ### First stage The first stage bootloader is a hardcoded script inside the ROM chip. It can sometimes be modified by switches located on the board. ### Second stage The second stage bootloader (SPL or MLO) is the first stage of U-Boot. It still has very limited functionality and its purpose is setup the boot- process for U-Boot. ### Third stage U-Boot itself comes with a very powerful boot environment consisting of an integrated serial terminal and environment variables. The U-Boot environment variables can be accessed by typing ```bash printenv [VARIABLE] ``` or ```bash setenv VARIABLE VALUE ``` Environment variables can also be persisted ```bash saveenv ``` and executed with the run command: ```bash run bootcmd ``` This example starts the boot process and is the first command to be run when starting U-Boot. Environment variables can also be predefined by using /boot/uEnv.txt. More about that [here!](https://linux-sunxi.org/UEnv.txt) ### Fourth stage The Fourth stage in this concept is the Kernel. It gets loaded into RAM by U-Boot and can be configured by adding options to the Kernel command line. Example from the Yocto Project: ```bash KERNEL_ARGS += " console=ttyS0,115200 " ``` Sets the debug serial to /dev/ttyS0 with a baudrate of 115200. This example is the default for RaspberryPi boards. ## U-Boot boot process When the third stage of the boot process begins, the first thing happening is the execution of "bootcmd". ```bash $ printenv bootcmd bootcmd=echo Booting from mmc ...; mmc dev ${mmcdev}; mmc dev ${mmcdev}; if mmc rescan; then if run loadbootscript; then run bootscript; else if run loadimage; then run mmcboot; else echo ERROR: Cannot run loadimage; fi; fi; else echo ERROR: Cannot run mmc rescan; fi; ``` :::{note} This is not the actual output, but a pritty printed version to visualize what is going on. ::: The usually last command in the boot process is a form of "boot", which executes the Kernel inside the image.itb file that has previously been loaded into the boards DDR main memory. The config file at $loadaddr sets the parameters, such as the ramdisk or kernel address in the .itb file. E.g.: ```bash bootm ${loadaddr} - ${fdtaddr} ```