03-U-Boot2017.01 U-Boot阶段分析

U-Boot2017.01的启动过程比较复杂,本文分为6部分讲述,笔者将主要过程和函数调用关系整理成一个文档方便查看,文档链接为
U-Boot2017.01启动过程分析pdf
U-Boot2017.01源码分析及启动命令解析

启动过程6部分内容如下
01-U-Boot2017.01 启动过程概述
02-U-Boot2017.01 SPL阶段分析
03-U-Boot2017.01 U-Boot阶段分析
04-U-Boot2017.01 加载内核过程
05-U-Boot2017.01 bootz加载过程
06-U-Boot2017.01 读取uEnv.txt过程

 U-Boot启动阶段函数调用关系如下

/* u-boot阶段 */
u-boot.lds(board/ti/am335x/u-boot.lds)
	|--> vectors.S(arch/arm/lib/vectors.S)
	|--> start.S(arch/arm/cpu/armv7/start.S)
		... ...
		|--> _main(arch/arm/lib/crt0.S )
			|--> board_init_f_alloc_reserve(common/init/board_init.c) /* 为u-boot的gd结构体分配空间 */
			|--> board_init_f_init_reserve(common/init/board_init.c)  /* 将gd结构体清零 */
			|--> board_init_f(common/board_f.c) /* 将gd结构体清零 */
				|--> initcall_run_list(init_sequence_f) (lib/initcall.c)
					|--> init_sequence_f[](common/board_f.c) /* 函数指针数组 */
						|--> /* 初始化各种外设,比如使能看门狗,串口打印,控制台,并保存板子信息到gd等等 */
			|--> relocate_code(arch\arm\lib\relocate.S) /* 运行 relocate_vectors,实现uboot代码的重定位 */
			|--> board_init_r(common/board_r.c)
				|--> initcall_run_list(init_sequence_r) (lib/initcall.c)	/* 遍历数组,一系列初始化 */
					|--> initr_reloc(common/board_r.c) /* 设置 gd->flag表示relocation完成 */
					|--> board_init(board/ti/am335x/board.c) /* 初始化看门狗,可选使能gpmc和PRU* */
					|--> efi_memory_init(lib/efi_loader/efi_memory.c) 
					|--> interrupt_init(arch/arm/lib/interrupts.c) /* 初始化中断 */
					|--> run_main_loop(common/board_r.c)
						|--> main_loop(common/main.c)
							|--> setenv("ver", version_string) /* 设置版本变量 */
								|--> version_string[](cmd/version.c) /* u-boot版本号,编译日期和时间,以及时间区 */
									|--> #define U_BOOT_VERSION_STRING U_BOOT_VERSION(include/version.h)
							|--> run_preboot_environment_command(common/main.c) /* 从环境变量中获取"preboot"的定义,一般环境变量中不包含该项配置 */		
							|--> bootdelay_process(common/autoboot.c) /* 从环境变量中取出"bootdelay"和"bootcmd"的配置值 */	
								|--> s = getenv("bootcmd")(common/autoboot.c)
								|--> "bootcmd="  CONFIG_BOOTCOMMAND "\0" /* include/configs/platinum.h  */
									|--> #define CONFIG_BOOTCOMMAND \    /* include/configs/am335x_evm.h */                       
										"if test ${boot_fit} -eq 1; then " \ /* include/configs/ti_armv7_common.h  boot_fit = 0 */
											"run update_to_fit;"    \	/* 不执行 */
										"fi;"   \
										"run findfdt; " \				
										"run init_console; " \
										"run envboot; " \
										"run distro_bootcmd"	
										|--> "findfdt="\       /* include/configs/am335x_evm.h */
											"if test $board_name = A335BONE; then " \	/* (board/ti/am335x/board.h) board_ti_is("A335BONE") */
												"setenv fdtfile am335x-bone.dtb; fi; " \
											"if test $board_name = A335BNLT; then " \
												"setenv fdtfile am335x-boneblack.dtb; fi; " \
											"if test $board_name = BBG1; then " \                                                                                  
												"setenv fdtfile am335x-bonegreen.dtb; fi; " \
											"if test $board_name = A33515BB; then " \
												"setenv fdtfile am335x-evm.dtb; fi; " \
											"if test $board_name = A335X_SK; then " \
												"setenv fdtfile am335x-evmsk.dtb; fi; " \
											"if test $board_name = A335_ICE; then " \
												"setenv fdtfile am335x-icev2.dtb; fi; " \
											"if test $fdtfile = undefined; then " \
												"echo WARNING: Could not determine device tree to use; fi; \0" \
										|--> "init_console=" \   /* include/configs/am335x_evm.h */
											"if test $board_name = A335_ICE; then "\
												"setenv console ttyO3,115200n8;" \
											"else " \
												"setenv console ttyO0,115200n8;" \
											"fi;\0" \
										|--> "envboot=mmc dev ${mmcdev}; " \  /* include/environment/ti/mmc.h  */
											"if mmc rescan; then " \
												"echo SD/MMC found on device ${mmcdev};" \
												"if run loadbootscript; then " \
													"run bootscript;" \
												"else " \
													"if run loadbootenv; then " \
														"echo Loaded env from ${bootenvfile};" 
														"run importbootenv;" \
													"fi;" \
													"if test -n $uenvcmd; then " \
														"echo Running uenvcmd ...;" \
														"run uenvcmd;" \
													"fi;" \
												"fi;" \
											"fi;\0" \
										|--> "distro_bootcmd=" BOOTENV_SET_SCSI_NEED_INIT           
											"for target in ${boot_targets}; do "               
											"run bootcmd_${target}; "                      
											"done\0"	/* include/config_distro_bootcmd.h */
											|--> #define BOOTENV_SET_SCSI_NEED_INIT "setenv scsi_need_init;" 
							|--> autoboot_command(common/autoboot.c)  /* 倒计时按下执行,没有操作执行bootcmd的参数 */		
								|--> ... ...
							|--> cli_loop(common/cli.c)	/* 倒计时按下space键,执行用户输入命令 */			
								|--> ... ...

程序框图如下
在这里插入图片描述

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值