Wednesday, August 12, 2015

Kernel Entry from u-boot (MIPS)

Lets explore how u-boot to kernel transition happening from MIPS architecture point of view. Before understanding the flow, we should be aware of the following basic questions.

1. What is uImage ?? 

          An image file that has a U-Boot wrapper (installed by the mkimage utility) that includes the OS type and loader information.
2. How to convert Linux kernel to uImage ??
           As part of kernel compilation process, uImage should be specified explicitly for creating uImage.
For example,

make ARCH=mips CROSS_COMPILE=some-mips-toolchain-gcc uImage -j24
3. What is the role of mkimage here ??

            mkimage is a tool which is used for generating the uImage. This script in linux kernel tree calls the mkimage.
While creating uImage, the entry point address of the Linux kernel(kernel_entry) is specified. Refer
VMLINUX_ENTRY_ADDRESS is the starting address of Linux kernel.
237 load-y                                  = $(CONFIG_PHYSICAL_START)
238 endif
239 entry-y                         = 0x$(shell $(NM) vmlinux 2>/dev/null \
240                                         | grep "\bkernel_entry\b" | cut -f1 -d \ )
272 bootvars-y      = VMLINUX_LOAD_ADDRESS=$(load-y) \
273                   VMLINUX_ENTRY_ADDRESS=$(entry-y)

Lets come to our actual discussion. I hope the reader have basic idea of how to use u-boot prompt for loading Linux kernel.
the bootm command is called after all preliminary commands like loading kernel to memory through tftp or some other medium.
bootm command reads the entry point address mentioned during the creation of uImage.
 300 static void boot_jump_linux(bootm_headers_t *images)
 301 {
 302         typedef void __noreturn (*kernel_entry_t)(int, ulong, ulong, ulong);
 303         kernel_entry_t kernel = (kernel_entry_t) images->ep; <----- HERE
 304         ulong linux_extra = 0;
 306         debug("## Transferring control to Linux (at address %p) ...\n", kernel);
 308         bootstage_mark(BOOTSTAGE_ID_RUN_OS);
 310         if (mips_boot_malta)
 311                 linux_extra = gd->ram_size;
 314         bootstage_fdt_add_report();
 315 #endif
 317         bootstage_report();
 318 #endif
 320         if (images->ft_len)
 321                 kernel(-2, (ulong)images->ft_addr, 0, 0);
 322         else
 323                 kernel(linux_argc, (ulong)linux_argv, (ulong)linux_env,
 324                         linux_extra);
 325 }
Refer u-boot code where the call to Linux kernel occurs.
In MIPS, the kernel_entry function in arch/mips/kernel/head.S will be called. Now we are officially in kernel code.
All hardware related initialization are done then start_kernel is called.

No comments:

Post a Comment