U-Boot some of the introduction has been already dealt here and picking up from there we know that U-boot is quite capable boot-loader and usually the most preferred one for eLinux or embedded Linux as its open source and highly expandable. This section of writing will take care of a brief walk through on and answer to question ” How u-boot takes up from it’s bootm/bootz execution to Linux Kernel handover.
Just to add some pessimism this wont deal how Linux boots up itself, that’s for some other article soon. Having said that lets take a ride to know u-boot a bit better.
U boot section of basic command set has listed some commands as execution control commands, that goes by bootm, go, bootelf, bootz etcetra. These commands allow users to load their prepacked binaries of their choice accordingly. Just bit of background usually the platforms or SOCs usually have reset vector tied with primary stage boot loader and in normal boot procedures the primary stage boot loader will load secondary stage boot loader such as U-Boot and inside u-boot terminal the environment
bootcmd which has the boot command written how to load required images on RAM addresses from some kind of storage( uboot has extensive file system support). But the obvious question comes the commands type must have been known before the u boot invokes its terminal and this is right time to start talking in code
So in the code base lies the files like bootm.c, bootz.c and each of such file register it self as a command of terminal with a macro
U_BOOT_CMD, now this macro here is responsible for maintaining a linklist for the commands which can be executed by terminal, this macro more or less servers the purpose of registration of commands by passing the name of command and type of link-list passed as arguments to the macro. Apart from bootm this macro help u-boot records all the commands which can be executed by u-boot through the terminal along with help string and callback function(eg.), which also means that this is part of command terminal design on u-boot. The link to example takes to the registration code for bootm command inside uboot and the function registered is do_bootm. Let’s a look at do_bootm.
When bootm command is executed at u-boot terminal do_bootm function is executed as a call back response. Just to add some context before bootm is executed we do load the binaries with file-system type commands to expropriate RAM addresses and these RAM addresses are passed as command line parameters
bootm <kernel address> <ramdisk address> <flattened device tree adress>
The function do_bootm supports sub commands like
bootm start etc. Also, u-boot support of FIT images (pdf link) hence this function checks for availability of any sub-command in the command-line params and segregates them and deals accordingly with function call to do_bootm_subcommand. Before this there is manual config (flag CONFIG_NEEDS_MANUAL_RELOC ) on do_bootm to enable manual relocation of sub-command table if required. Either the case it calls a function from common/bootm.c do_bootm_states with elaborate set of parameters usually the boot states and all the command line params passed to do_bootm earlier.
The function do_bootm_states walks through the states, states are passed by the caller function either do_bootm_subcommand or do_bootm_states. If any of the state check fails i.e. on error it returns with nonzero value and leads to failure of boot. The first state is BOOTM_STATE_START which is merely the check work of addresses done by function bootm_start but important to avoid boot time address failures. Next state check if passed by caller function is BOOTM_STATE_FINDOS this checks through the passed kernel image finding out its header and type of image weather is android supported or FIT supported etc. and prepares the boot header type image global variable for final boot. After preparing the image variable for kernel image the other important parts by call to bootm_find_other and further to bootm_find_images of the if available in the passed arguments to do_bootm , parts like ramdisk image flattened device tree, other loadable-s. and the checks goes on and for ramdisk high region, memory reserve areas to prevent u-boot from touching those area to load any other loadable and relocates the ftd if required. Then ahead if all states passed then it looks for the os boot function from image variable and checks for flags passed and call the various states on os boot function to do the type saftey check and avoid malicious load or to simulate pseudo loads and in end called boot_selected_os which calls the arch_preboot_os to do customized arch type checks and write the values to respective pins/registers if required board_preboot_os which is for a dedicated board type if it is booting for else this is empty function call and the boot os function is called with flag BOOTM_STATE_OS_GO and all kernel args.
This is small brief up on “how u-boot tries to load OS ?”. Please comment below if doubts/question/appreciations. We would love to hear back from you.