上一篇介紹到start.S 最后一個指令是跳轉到_main, 接下來分析 __main 都做了什么
arch/arm/lib/crt0.S
__main 注釋寫的很詳細,主要分為5步
1. 準備board_init_f的運行環境
2. 跳轉到board_init_f
3. 設置broad_init_f 申請的stack 和 GD
4. 完整u-boot 執行relocate_code, 將u-boot 搬到board_init_f計算出的目的地址, tpl, spl 跳回crt0
5. 設置board_init_r運行環境,完整u-boot 有些cpu 剩余工作由c_runtime_cpu_setup完成
6. 跳轉到board_init_r
詳細分析如下:
1. CONFIG_TPL_NEEDS_SEPARATE_STACK=1 CONFIG_TPL_STACK 0xff8effff
bic r0, r0, #7 /* 8-byte alignment for ABI compliance */mov sp, r0bl board_init_f_alloc_reservemov sp, r0/* set up gd here, outside any C code */mov r9, r0bl board_init_f_init_reservebl board_init_f_boot_flagsbl board_init_f
2. board_init_f
代碼位于arch/arm/mach-rockchip/tpl.c
CONFIG_SPL_FRAMEWORK=1
CONFIG_TINY_FRAMEWORK=n
CONFIG_DEBUG_UART=1
CONFIG_TPL_SERIAL=1
debug_uart_init => 到此可以用簡單版的print, c標準printf 還不能用
rockchip_stimer_init => timer 相關,暫時用不到
2.1?spl_early_init
?tpl/spl 中的大部分工作都是在這個函數中完成,代碼位置 common\spl\spl.c,?主要完成
a. fdtdec_setup, 設置fdt,
b. dm_init_and_scan, 初始化所有掛在dm 架構上的驅動
tpl 中目前有如下幾個,其中就包含了TPL 的主要功能,初始化DRAM, 即?.u_boot_list_2_driver_2_dmc_rk3399
?.u_boot_list_2_driver_2_clk_fixed_rate
?.u_boot_list_2_driver_2_clk_rk3399
?.u_boot_list_2_driver_2_dmc_rk3399
?.u_boot_list_2_driver_2_firmware
?.u_boot_list_2_driver_2_generic_syscon
?.u_boot_list_2_driver_2_psci
?.u_boot_list_2_driver_2_rockchip_efuse
?.u_boot_list_2_driver_2_rockchip_rk3399_pmuclk
?.u_boot_list_2_driver_2_root_driver
?.u_boot_list_2_driver_2_simple_bus_drv
?.u_boot_list_2_driver_2_syscon_rk3399
2.2 返回BROM
back_to_bootrom 調用 longjmp(brom_ctx, BROM_BOOT_NEXTSTAGE);
x0 為 brom_ctx, x1 為BROM_BOOT_NEXTSTAGE=1
通過longjump 返回到上一篇中的setjmp 下一條指令,并且ret 被替換為longjmp 返回值,
ret=0, 可以boot next stage,? 不過目前還不知具體原理,有了解的歡迎評論區討論
?? ??? ?/*
?? ??? ? * To instruct the BROM to boot the next stage, we
?? ??? ? * need to return 0 to it: i.e. we need to rewrite
?? ??? ? * the return code once more.
?? ??? ? */
?? ??? ?ret = 0;
#if defined(CONFIG_TPL_ROCKCHIP_BACK_TO_BROM) && !defined(CONFIG_TPL_BOARD_INIT)back_to_bootrom(BROM_BOOT_NEXTSTAGE);
#endif
ENTRY(longjmp)ldp x19, x20, [x0,#0]ldp x21, x22, [x0,#16]ldp x23, x24, [x0,#32]ldp x25, x26, [x0,#48]ldp x27, x28, [x0,#64]ldp x29, x30, [x0,#80]ldr x2, [x0,#96]mov sp, x2/* Move the return value in place, but return 1 if passed 0. */adds x0, xzr, x1csinc x0, x0, xzr, ne/* invalid icache for cortex a35 */
branch_if_a35_core x1, __asm_invalidate_icache_allret
ENDPROC(longjmp)