十、uboot 代码流程分析---run_main_loop

时间:2023-03-09 05:47:48
十、uboot 代码流程分析---run_main_loop

  调用 board_init_r,传入全局 GD 和 SDRAM 中的目的地址 gd->rellocaddr

 void board_init_r(gd_t *new_gd, ulong dest_addr)
{
/*
* Set up the new global data pointer. So far only x86 does this
* here.
* TODO(sjg@chromium.org): Consider doing this for all archs, or
* dropping the new_gd parameter.
*/
/* 打开LOG标志*/
gd->flags &= ~GD_FLG_LOG_READY; if (initcall_run_list(init_sequence_r))
hang(); /* NOTREACHED - run_main_loop() does not return */
hang();
}

  这里同样建立了一个链表,分析里面的设置即可。

11.1 init_sequence_r

  里面只是进行了一系列的初始化。

 static init_fnc_t init_sequence_r[] = {
initr_trace,
initr_reloc,
#ifdef CONFIG_ARM
initr_caches,
#endif
initr_reloc_global_data,
initr_barrier,
initr_malloc,
log_init,
initr_bootstage, /* Needs malloc() but has its own timer */
initr_console_record,
bootstage_relocate,
#if defined(CONFIG_ARM) || defined(CONFIG_NDS32) || defined(CONFIG_RISCV)
board_init, /* Setup chipselects */
#endif
#ifdef CONFIG_EFI_LOADER
efi_memory_init,
#endif
stdio_init_tables,
initr_serial,
initr_announce,
INIT_FUNC_WATCHDOG_RESET
INIT_FUNC_WATCHDOG_RESET
INIT_FUNC_WATCHDOG_RESET
power_init_board,
#ifdef CONFIG_MTD_NOR_FLASH
initr_flash,
#endif
INIT_FUNC_WATCHDOG_RESET
#ifdef CONFIG_CMD_NAND
initr_nand,
#endif
initr_env,
INIT_FUNC_WATCHDOG_RESET
initr_secondary_cpu,
INIT_FUNC_WATCHDOG_RESET
stdio_add_devices,
initr_jumptable,
console_init_r, /* fully init console as a device */
INIT_FUNC_WATCHDOG_RESET
interrupt_init,
#ifdef CONFIG_ARM
initr_enable_interrupts,
#endif
/* PPC has a udelay(20) here dating from 2002. Why? */
#ifdef CONFIG_CMD_NET
initr_ethaddr,
#endif
#ifdef CONFIG_CMD_NET
INIT_FUNC_WATCHDOG_RESET
initr_net,
#endif
run_main_loop,
};

  到最后执行run_main_loop 函数,进行内核的调用。

11.2 main_loop

  run_main_loop  调用 main_loop,main_loop定义在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函数调用了show_boot_progress,利用它显示启动进程(progress),
此处为空函数 */
bootstage_mark_name(BOOTSTAGE_ID_MAIN_LOOP, "main_loop"); #ifdef CONFIG_VERSION_VARIABLE
/* setenv 设置环境变量 ver 为 version_string,后者在common/cmd_version.c中定义为:
const char __weak version_string[] = U_BOOT_VERSION_STRING; */
/* U_BOOT_VERSION_STRING在version.h中定义 */
env_set("ver", version_string); /* set version variable */
#endif /* CONFIG_VERSION_VARIABLE */ /* cli_init用来初始化hush shell使用的一些变量。 */
cli_init(); /* run_preboot_environment_command函数从环境变量中获取"preboot"的定义,*/
/* 该变量包含了一些预启动命令,一般环境变量中不包含该项配置。 */
run_preboot_environment_command(); #if defined(CONFIG_UPDATE_TFTP)
update_tftp(0UL, NULL, NULL);
#endif /* CONFIG_UPDATE_TFTP */ /* bootdelay_process从环境变量中取出"bootdelay"和"bootcmd"的配置值 */
/* 将取出的"bootdelay"配置值转换成整数,赋值给全局变量stored_bootdelay */
/* 最后返回"bootcmd"的配置值 */
/*bootdelay为u-boot的启动延时计数值,计数期间内如无用户按键输入干预,那么将执行"bootcmd"配置中的命令。*/
s = bootdelay_process();
if (cli_process_fdt(&s))
cli_secure_boot_cmd(s); /* autoboot_command,该函数在common/autoboot.c中实现 */
autoboot_command(s); /* 进入 uboot 命令行中 */
cli_loop();
panic("No CLI available");
}