04-U-Boot2017.01 加载内核过程

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-Boot2017.01 加载内核过程的函数调用关系如下:

/* u-boot启动内核阶段 */
|--> 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)
	|--> autoboot_command(common/autoboot.c)  /* 倒计时按下执行,没有操作执行bootcmd的参数 */		
		|--> abortboot(stored_bootdelay)(common/autoboot.c)
			|--> __abortboot(bootdelay)(common/autoboot.c) /* 判断倒计时有无按下 */
				|--> Press SPACE to abort autoboot in %d seconds /* 启动信息打印这句话 */
		|--> run_command_list(s, -1, 0)(common/cli.c)	/* 运行命令 */											
====|--> parse_string_outer(common/cli_hush.c)	
||				|--> parse_stream_outer(common/cli_hush.c) /* hush shell的命令解释器 */
||					|--> do{...}while(..);(common/cli_hush.c) /*循环命令解析器的"命令输入解析--执行"运行模式*/			
||						|--> parse_stream(common/cli_hush.c)  /* 读取一行输入命令,并解析 */
||						|--> run_list(common/cli_hush.c)      /* 运行命令 */
||							|--> run_list_real(common/cli_hush.c)
||								|--> run_pipe_real(common/cli_hush.c)
||									|--> cmd_process(common/command.c)	/* 处理命令 */
||										|--> find_cmd(argv[0])(common/command.c)
||											|--> find_cmd_tbl(common/command.c)
||												|--> for (cmdtp = table; cmdtp != table + table_len; cmdtp++) ... return cmd_tbl_t *;  /* 返回命令表项指针 */
||										|--> cmd_call(cmdtp, flag, argc, argv)(common/command.c)	
||											|--> (cmdtp->cmd)(cmdtp, flag, argc, argv)	/* 执行命令 */
||											|--> 例如:do_bootz(cmd/bootz.c)	/* bootz加载uImage */
||												|--> bootz_start(cmd/bootz.c)
||													|--> do_bootm_states(common/bootm.c)	/* states = BOOTM_STATE_START */	
||													|--> images->ep =0x82000000	/* entry point of OS */
||													|--> bootz_setup(arch/arm/lib/zimage.c)
||													|--> bootm_find_images(common/bootm.c)	/* 内核和设备树的获取 */
||												|--> bootm_disable_interrupts(common/bootm.c)	
||												|--> images.os.os = IH_OS_LINUX;
||												|--> do_bootm_states(common/bootm.c) /* states = BOOTM_STATE_OS_PREP |BOOTM_STATE_OS_FAKE_GO | BOOTM_STATE_OS_GO */
||													/* 这个函数最主要的功能是获取kernel的启动函数,执行寻找设备树并进入执行kernel启动函数 */
||														|--> bootm_start(common/bootm.c)	/* return 0; states = BOOTM_STATE_START */
||														|--> bootm_os_get_boot_func(common/bootm_os.c)	/* 获取内核加载函数 */
||														/* return do_bootm_linux; 也就是 boot_fn = do_bootm_linux; */
||												|--> boot_selected_os(common/bootm_os.c)
||												|--> boot_fn(state, argc, argv, images)	/* boot_fn = do_bootm_linux 所以执行下一行 */
||												|--> do_bootm_linux(arch/arm/lib/bootm.c)
||													|--> boot_jump_linux(arch/arm/lib/bootm.c)	
||														|--> announce_and_cleanup(0)(arch/arm/lib/bootm.c)			
||														|--> printf("\nStarting kernel ...%s\n\n", fake ? "(fake run for tracing)" : "");	/* 打印Starting kernel ... */
||														|--> kernel_entry()
||	|--> cli_loop(common/cli.c)	/* 倒计时按下space键,执行用户输入命令 */
||		|--> parse_file_outer(common/cli_hush.c)
||			|--> setup_file_in_str(common/cli_hush.c)
||				|--> file_get(common/cli_hush.c)
||					|--> get_user_input(common/cli_hush.c)
||						|--> uboot_cli_readline(common/cli_hush.c)
||							|--> cli_readline(common/cli_readline.c)
||								|--> cli_readline_into_buffer(common/cli_readline.c)
====|--> parse_stream_outer(common/cli_hush.c)		

加载过程框图如下:
在这里插入图片描述
获取解析执行启动命令的过程如下
在这里插入图片描述

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值