uboot2019.10启动分析:
一、SPL执行流程:
root@ubuntu:/home/uboot/u-boot-2019.10# more board/samsung/common/exynos-uboot-spl.lds
ENTRY(_start)
SECTIONS
{
.text :
{
__start = .;
(.vectors)
arch/arm/cpu/armv7/start.o (.text)
(.text)
} >.sram
. = ALIGN(4);
}
- 根据ENTRY(_start),可知先执行 __start
- 找到 arch/arm/lib/vectors.S
- Symbol _start is referenced elsewhere, so make it global
.globl _start
可知这个符号是一个全局符号。
_start:
#ifdef CONFIG_SYS_DV_NOR_BOOT_CFG
.word CONFIG_SYS_DV_NOR_BOOT_CFG
#endif
b reset
然后执行 reset
3. 找到 root@ubuntu:/home/uboot/u-boot-2019.10# more arch/arm/cpu/armv7/start.S
4. 因为配置了CONFIG_SKIP_LOWLEVEL_INIT,
跳过 bl cpu_init_cp15,
跳过 bl cpu_init_crit,
执行 bl _main
5. root@ubuntu:/home/uboot/u-boot-2019.10# more arch/arm/lib/crt0.S
6. 执行 bl board_init_f
7. 找到 root@ubuntu:/home/uboot/u-boot-2019.10# more arch/arm/mach-exynos/spl_boot.c
执行 void board_init_f(unsigned long bootflag);
执行 void do_lowlevel_init();
8. 进入 root@ubuntu:/home/uboot/u-boot-2019.10# more arch/arm/mach-exynos/lowlevel_init.c
9. 执行 system_clock_init(); 初始化系统时钟
10. 执行 exynos_pinmux_config(PERIPH_ID_UART0, PINMUX_FLAG_NONE);
debug_uart_init(); 初始化串口0
11. 执行 mem_ctrl_init(); 初始化SDRAM,为了下一步加载U-BOOT.bin做准备
12. 执行 tzpc_init(); 配置 TrustZone Protection Controller
13. 执行 copy_uboot_to_ram(), 将u-boo.bin从启动媒介拷贝到SDRAM的
CONFIG_SYS_TEXT_BASE 位置。
14. 跳转到u-boot执行:
/* Jump to U-Boot image */
uboot = (void *)CONFIG_SYS_TEXT_BASE;
(*uboot)();
二、U-BOOT 执行流程:
15. 前面的步骤和SPL中执行的都一样。
16. 执行到 bl board_init_f时,查看文件`arch\arm\mach-exynos\Makefile
ifdef CONFIG_SPL_BUILD
obj-
(
C
O
N
F
I
G
E
X
Y
N
O
S
5
)
+
=
c
l
o
c
k
i
n
i
t
e
x
y
n
o
s
5.
o
o
b
j
−
(CONFIG_EXYNOS5) += clock_init_exynos5.o obj-
(CONFIGEXYNOS5)+=clockinitexynos5.oobj−(CONFIG_EXYNOS5) += dmc_common.o dmc_init_ddr3.o
obj-
(
C
O
N
F
I
G
E
X
Y
N
O
S
4210
)
+
=
d
m
c
i
n
i
t
e
x
y
n
o
s
4.
o
c
l
o
c
k
i
n
i
t
e
x
y
n
o
s
4.
o
o
b
j
−
(CONFIG_EXYNOS4210)+= dmc_init_exynos4.o clock_init_exynos4.o obj-
(CONFIGEXYNOS4210)+=dmcinitexynos4.oclockinitexynos4.oobj−(CONFIG_EXYNOS4412)+= dmc_init_exynos4412.o clock_init_exynos4412.o
obj-y += spl_boot.o tzpc.o
obj-y += lowlevel_init.o
endif
当执行U-BOOT时,这些文件都不会被编译。因此,执行到common\board_f.c时,
会跳转到void board_init_f(ulong boot_flags)函数。
17. 紧接着:
if (initcall_run_list(init_sequence_f))
hang();
init_sequence_f是一个函数指针数组,initcall_run_list()函数会依次遍历
数组中的每一个元素,并执行。正常情况下不会执行到hang(),而数组的最后一个
元素为 NULL,作为退出条件:
for (init_fnc_ptr = init_sequence; *init_fnc_ptr; ++init_fnc_ptr);
18. b relocate_code
19. bl relocate_vectors
20. bl coloured_LED_init
21. bl red_led_on
22. ldr pc, =board_init_r 执行common\Board_r.c
中的
void board_init_r(gd_t *new_gd, ulong dest_addr);
23. 执行:
if (initcall_run_list(init_sequence_r))
hang();
init_sequence_r是一个函数指针数组,最后一个成员是 run_main_loop()
24. 执行 void main_loop(void);
25. 执行 void cli_loop(void);
26. 执行 cli_simple_loop();
参考博客:https://blog.csdn.net/sinat_20006769/article/details/79046230