Home | Projects | Notes > Embedded Linux > BBB Linux Boot Sequence - Step 4: Bootstrap Loader


misc.c uncompresses the compressed kernel image.
head.S of the Bootstrap Loader is different from that of Linux kernel.
Time to explore the source file bootm.c of the U-boot source code.
Download U-boot srouce (u-boot-2017.05-rc2.tar.bz2) from https://ftp.denx.de/pub/u-boot/.
u-boot-2017.05-r2/arch/arm/lib/bootm.c
bootm.c file is where code to read the Linux kernel from memory, verify the checksum, control hand-over is implemented.
xxxxxxxxxx321/* bootm.c */2
3/* Subcommand: GO */4static void boot_jump_linux(bootm_headers_t *images, int flag)5{6 ...78 unsigned long machid = gd->bd->bi_arch_number;9 char *s;10 void (*kernel_entry)(int zero, int arch, uint params);11 unsigned long r2;12 int fake = (flag & BOOTM_STATE_OS_FAKE_GO);13 14 kernel_entry = (void (*)(int, int, uint))images->ep;15 ...16 if (IMAGE_ENABLE_OF_LIBFDT && images->ft_len)17 r2 = (unsigned long)images->ft_addr;18 else19 r2 = gd->bd->bi_boot_params;20
21 if (!fake) {2223 if (armv7_boot_nonsec()) {24 armv7_init_nonsec();25 secure_ram_addr(_do_nonsec_entry)(kernel_entry,26 0, machid, r2);27 } else2829 kernel_entry(0, machid, r2);30 }3132}
L4:
bootm_headers_tis defined ininclude/image.h.L10:
kernel_entryis a function pointer that is initialized in L14 to the entry point of the Linux kernel image.epis found in thebootm_headers_tis defined ininclude/image.h.
L17: r2
Device Tree Binary (DTB) is actually Flattened Device Tree (FDT), which describes various peripherals present on the board. The Linux kernel needs this binary during the boot. Otherwise, Linux boot may not succeed.
L29: U-boot transfers the control to the Bootstrap Loader. The "entry point" (
images->ep) address is dereferenced.
First argument is ignored by the Linux,
machidis U-boot saying "Hey, I've detected this machine!".r2stores the address of FDT.
The Boot Loader transfers the control to head.S (routine Start:) of the Linux's Bootstrap Loader.

Download Linux kernel source from https://github.com/beagleboard/linux.
Linux Bootstrap Loader is located in arch/arm/boot/compressed/. All Bootstrap related files are located in this directory.
xxxxxxxxxx41/* bootm.c */2...3 kernel_entry(0, machid, 2); /* U-boot transfers control to the Bootstrap Loader of Linux */4...xxxxxxxxxx51/* head.S */2...3start: @ control handed over from U-boot starts here! 4 .type start,#function5...
startroutine does some initial tedious setup which you do not necessarily need to dive deeper at this moment.
Decompression of the compressed kernel is taken care of by misc.c.
xxxxxxxxxx41/* head.S */2...3 bl decompress_kernel @ branch to decompress_kernel defined in 'misc.c'4...xxxxxxxxxx251/* misc.c */2...3void4decompress_kernel(unsigned long output_start, unsigned long free_mem_ptr_p,5 unsigned long free_mem_ptr_end_p,6 int arch_id)7{8 int ret;9
10 output_data = (unsigned char *)output_start;11 free_mem_ptr = free_mem_ptr_p;12 free_mem_end_ptr = free_mem_ptr_end_p;13 __machine_arch_type = arch_id;14
15 arch_decomp_setup();16
17 putstr("Uncompressing Linux...");18 ret = do_decompress(input_data, input_data_end - input_data,19 output_data, error);20 if (ret)21 error("decompressor returned an error");22 else23 putstr(" done, booting the kernel.\n");24}25...L17: This message is what you saw on the screen during the booting process.
After kernel decompression is done, the control is transferred to another head.S file that is a part of the Linux kernel.

Go to arch/arm/kernel/ where Linux kernel's architecture dependent files are located. This head.S is the generic startup code for ARM processor (not SoC vedor specific) that does the ARM specific initializations:
CPU specific initialization
Checks for valid processor architecture
Page table inits
Initialize and prepare MMU for the identified processor architecture
Enable MMU to support virtual memory
Calls start_kernel function of the main.c (Architecture dependent code)
This head.S executes lots of architecture specific initialization code implemented in different intermediate files.
It is the responsibility of the Bootstrap Loader (i.e., glued to the Linux kernel image) to decompress and relocate the Linux kernel image. (These are NOT the responsibilities of U-boot)
Again, don't be confused about those two head.S files. One belongs to the Bootstrap Loader, and the other belongs to the Linux kernel. And both are architecture dependent; in this case, ARM.
Nayak, K. (2022). Embedded Linux Step by Step Using Beaglebone Black [Video file]. Retrieved from https://www.udemy.com/course/embedded-linux-step-by-step-using-beaglebone/