【imx6ul】U-Boot 2016.03u-boot分析之启动内核流程-ARM Cortex-A7

    前面我们分析了uboot的配置过程、编译过程、执行流程、解析了main_loop()函数、分析了uboot的命令结构。今天我们进一步分析uboot是如何启动内核的,也就是do_bootm/ do_bootz具体做了哪些事。

    U-Boot环境变量如下。main_loop函数中会获取bootcmd环境变量,并执行命令,从而启动内核,所以我们主要分析do_bootm/ do_bootz函数。

U-Boot 2016.03-mys-6ulx+g4ade113 (Sep 16 2017 - 23:49:21 +0800)

CPU:   Freescale i.MX6UL rev1.1 528 MHz (running at 396 MHz)
CPU:   Industrial temperature grade (-40C to 105C) at 36C
Reset cause: POR
Board: MX6UL 14x14 EVK
I2C:   ready
DRAM:  256 MiB
NAND:  256 MiB
MMC:   FSL_SDHC: 0, FSL_SDHC: 1
*** Warning - bad CRC, using default environment

Display: TFT43AB (480x272)
Video: 480x272x24
In:    serial
Out:   serial
Err:   serial
Net:   FEC0
Error: FEC0 address not set.

Normal Boot
Hit any key to stop autoboot:  0 
=> pri
baudrate=115200
board_name=MYS6UL
board_rev=14X14
bootargs=console=ttymxc0,115200 ubi.mtd=3 root=ubi0:rootfs rootfstype=ubifs mtdparts=gpmi-nand:5m(boot),10m(kernel),1m(dtb),-(rootfs)
bootcmd=nand read ${loadaddr} 0x500000 0xA00000;nand read ${fdt_addr} 0xF00000 0x100000;bootz ${loadaddr} - ${fdt_addr}
bootcmd_mfg=run mfgtool_args;bootz ${loadaddr} ${initrd_addr} ${fdt_addr};
bootdelay=3
console=ttymxc0
ethact=FEC0
ethprime=FEC
fdt_addr=0x83000000
fdt_high=0xffffffff
initrd_addr=0x83800000
initrd_high=0xffffffff
loadaddr=0x80800000
mfgtool_args=setenv bootargs console=${console},${baudrate} rdinit=/linuxrc g_mass_storage.stall=0 g_mass_storage.removable=1 g_mass_storage.file=/fat g_mass_storage.ro=1 g_mass_storage.idVendor=0x066F g_mass_storage.idProduct=0x37FF g_mass_storage.iSerialNumber="" mtdparts=gpmi-nand:5m(boot),10m(kernel),1m(dtb),-(rootfs) clk_ignore_unused 
panel=TFT43AB

Environment size: 930/131068 bytes
=>

函数前期执行流程如下:

(1)_start(arch/arm/lib/vector.S)
              b     reset
(2)reset(arch/arm/cpu/armv7/start.S)
              bl    cpu_init_cp15
              bl    cpu_init_crit
              bl    _main
(3)_main(arch\arm\lib\crt0.S)
              board_init_f(common\Board_f.c)
              b     relocate_code
              ldr   lr, =board_init_r(common/Board_r.c)
                     run_main_loop()
                            main_loop()
(4)main_loop()
(5)启动内核:
main_loop->autoboot_command->run_command_list->cli_simple_run_command_list->cli_simple_run_command-> cmd_process-> find_cmd/ cmd_call(result= (cmdtp->cmd)(cmdtp, flag, argc, argv))

cmd_call会执行nand readbootz/bootm函数,接下来主要分析bootz/bootm函数。

调用流程如下:

do_bootz->bootz_start->do_bootm_states->bootm_start/bootm_find_os/bootm_find_other/bootm_load_os(加载内核到指定位置上)/bootm_os_get_boot_func(获取到对应操作系统的启动函数,被存储到boot_fn )->boot_os->do_bootm_linux->boot_prep_linux/boot_jump_linux->kernel_entry(跳转到kernel中,离开uboot)


打印Starting kernel ...

boot_jump_linux->announce_and_cleanup:

    printf("\nStartingkernel ...%s\n\n", fake ? "(fakerun for tracing)" : "");

详细函数分析待后续整理。。。


猜你喜欢

转载自blog.csdn.net/fengyuwuzu0519/article/details/79560249