u-boot启动分析03( main_loop)

u-boot启动分析02(board_init_f,board_init_r)

接着上一篇文章继续分析。

main_loop

u-boot15/common/main.c

/* We come here after U-Boot is initialised and ready to process commands */
void main_loop(void)
{
	const char *s;

	bootstage_mark_name(BOOTSTAGE_ID_MAIN_LOOP, "main_loop");

#ifndef CONFIG_SYS_GENERIC_BOARD
	debug("Warning: Your board does not use generic board. Please read\n");
	debug("doc/README.generic-board and take action. Boards not\n");
	debug("upgraded by the late 2014 may break or be removed.\n");
#endif

	modem_init();//根据定义CONFIG_MODEM_SUPPORT,初始化modem,项目无此配置
#ifdef CONFIG_VERSION_VARIABLE
	setenv("ver", version_string);  /* set version variable */
#endif /* CONFIG_VERSION_VARIABLE */

	cli_init();//CONFIG_SYS_HUSH_PARSER,CONFIG_HUSH_INIT_VAR,项目无此配置
	run_preboot_environment_command();//执行preboot命令,role 1章节分析

#if defined(CONFIG_UPDATE_TFTP) //未定义
	update_tftp(0UL);
#endif /* CONFIG_UPDATE_TFTP */
	s = bootdelay_process();//命令行延时处理 2章节分析
	if (cli_process_fdt(&s))
		cli_secure_boot_cmd(s);
	autoboot_command(s); //执行启动命令 3章节分析
	cli_loop();// u-boot命令行处理
}

1 run_preboot_environment_command

u-boot15/common/main.c

static void run_preboot_environment_command(void)
{
#ifdef CONFIG_PREBOOT
	char *p;
	p = getenv("preboot");//role
	if (p != NULL) {
# ifdef CONFIG_AUTOBOOT_KEYED
		int prev = disable_ctrlc(1);	/* disable Control C checking */
# endif
		run_command_list(p, -1, 0); // 执行命令行,入参p指向的内容是“role”  1.1小节分析
# ifdef CONFIG_AUTOBOOT_KEYED
		disable_ctrlc(prev);	/* restore Control C checking */
# endif
	}
#endif /* CONFIG_PREBOOT */
}

1.1 do_role

u-boot15/common/cmd_role.c

int do_role(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
{
#ifdef CONFIG_ZEBU
	boot_mode_t boot_role = BOOTLOADER_MODE_LOAD;
#else
	boot_mode_t boot_role = get_boot_role();//从chipram中读取boot_role
#endif
	switch(boot_role) {
		case BOOTLOADER_MODE_DOWNLOAD:
			setenv("bootdelay", "0");
			setenv("bootcmd", "download");
			debugf("Get chipram env mode %x,go download\n", boot_role);
			break;
		case BOOTLOADER_MODE_LOAD:  //走这个分支,bootcmd环境变量赋值cboot
			setenv("bootcmd", "cboot");
			debugf("Get chipram env mode %x,go cboot\n", boot_role);
			break;
		default :
			printf("unkown uboot role ,nothing to do in preboot\n");
	}

	return 0;
}

2 bootdelay_process

u-boot15/common/autoboot.c

const char *bootdelay_process(void)
{
... ... //省略不满足判断条件的代码
	char *s;
	int bootdelay;

	s = getenv("bootdelay");
	bootdelay = s ? (int)simple_strtol(s, NULL, 10) : CONFIG_BOOTDELAY;//bootdelay取值,如果s不为空,取s的值,否则取CONFIG_BOOTDELAY

	debug("### main_loop entered: bootdelay=%d\n\n", bootdelay);//打印bootdelay的值

	bootretry_init_cmd_timeout();//初始化 command line timeout的时间

	s = getenv("bootcmd"); //读取bootcmd环境变量的值赋值给s

	process_fdt_options(gd->fdt_blob); //如果配置了CONFIG_OF_CONTROL,则做fdt相关处理
	stored_bootdelay = bootdelay; //赋值给stored_bootdelay,used by autoboot_command()

	return s;
}

3 autoboot_command

u-boot15/common/autoboot.c

void autoboot_command(const char *s)
{
	debug("### main_loop: bootcmd=\"%s\"\n", s ? s : "<UNDEFINED>");

	if (stored_bootdelay != -1 && s && !abortboot(stored_bootdelay)) {
#if defined(CONFIG_AUTOBOOT_KEYED) && !defined(CONFIG_AUTOBOOT_KEYED_CTRLC)
		int prev = disable_ctrlc(1);	/* disable Control C checking */
#endif

		run_command_list(s, -1, 0); //执行命令 cboot,3.1小节分析

#if defined(CONFIG_AUTOBOOT_KEYED) && !defined(CONFIG_AUTOBOOT_KEYED_CTRLC)
		disable_ctrlc(prev);	/* restore Control C checking */
#endif
	}
... ...
}

3.1 do_cboot

u-boot15/common/cmd_cboot.c
这个函数比较长,只分析重点部分。

int do_cboot(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
{
... ...
		/* s_boot_func_array是一个函数指针数组,入参为void,返回值类型为boot_mode_enum_type 
		*  typedef boot_mode_enum_type (*CBOOT_FUNC) (void);
		* boot_mode_enum_type 是枚举类型,枚举了CMD_NORMAL_MODE,CMD_RECOVERY_MODE等多种启动类型
		* 此for循环遍历s_boot_func_array,执行相应的函数,匹配启动模式
		*/
		for (i = 0;  i < CHECK_BOOTMODE_FUN_NUM; i++) {
			if (0 == s_boot_func_array[i]) {
				bootmode = CMD_POWER_DOWN_DEVICE;
				break;
			}
			bootmode = s_boot_func_array[i]();
			if (CMD_UNDEFINED_MODE == bootmode) {

				continue;
			} else {
				debugf("get boot mode in boot func array[%d]\n",i);
				break;
			}
		}
		board_boot_mode_regist(boot_mode_array); //注册启动模式,即给boot_mode_array赋值。
		if ((bootmode > CMD_POWER_DOWN_DEVICE) &&(bootmode < CMD_MAX_MODE)&& (0 != boot_mode_array[bootmode])) {
		write_log();
		boot_mode_array[bootmode](); //执行相应的启动模式代码
	}
} 

下面以正常启动模式为例,分析后续的执行流程。

// 1. 注册NORMAL启动模式
void board_boot_mode_regist(CBOOT_MODE_ENTRY *array)
{
	MODE_REGIST(CMD_NORMAL_MODE, normal_mode); 
	... ...
}
// 2. 执行启动模式对应的函数
boot_mode_array[CMD_NORMAL_MODE](); 

//3. 执行normal_mode
// 代码路径: u-boot15/common/loader/boot_mode.c
void normal_mode(void)
{
#ifndef CONFIG_ZEBU //走这个分支
	vibrator_hw_init();
	set_vibrator(1);
	vlx_nand_boot(BOOT_PART, BACKLIGHT_ON, LCD_ON);//继续启动,初始化LCD,安全启动验证,加载内核等
#else
	vlx_nand_boot_zebu(BOOT_PART, BACKLIGHT_ON, LCD_ON);
#endif
	return;
}
  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值