调用 board_init_r,传入全局 GD 和 SDRAM 中的目的地址 gd->rellocaddr
1 void board_init_r(gd_t *new_gd, ulong dest_addr) 2 { 3 /* 4 * Set up the new global data pointer. So far only x86 does this 5 * here. 6 * TODO(sjg@chromium.org): Consider doing this for all archs, or 7 * dropping the new_gd parameter. 8 */ 9 /* 打开LOG标志*/ 10 gd->flags &= ~GD_FLG_LOG_READY; 11 12 if (initcall_run_list(init_sequence_r)) 13 hang(); 14 15 /* NOTREACHED - run_main_loop() does not return */ 16 hang(); 17 }
这里同样建立了一个链表,分析里面的设置即可。
10.1 init_sequence_r
里面只是进行了一系列的初始化。
1 static init_fnc_t init_sequence_r[] = { 2 initr_trace, 3 initr_reloc, 4 #ifdef CONFIG_ARM 5 initr_caches, 6 #endif 7 initr_reloc_global_data, 8 initr_barrier, 9 initr_malloc, 10 log_init, 11 initr_bootstage, /* Needs malloc() but has its own timer */ 12 initr_console_record, 13 bootstage_relocate, 14 #if defined(CONFIG_ARM) || defined(CONFIG_NDS32) || defined(CONFIG_RISCV) 15 board_init, /* Setup chipselects */ 16 #endif 17 #ifdef CONFIG_EFI_LOADER 18 efi_memory_init, 19 #endif 20 stdio_init_tables, 21 initr_serial, 22 initr_announce, 23 INIT_FUNC_WATCHDOG_RESET 24 INIT_FUNC_WATCHDOG_RESET 25 INIT_FUNC_WATCHDOG_RESET 26 power_init_board, 27 #ifdef CONFIG_MTD_NOR_FLASH 28 initr_flash, 29 #endif 30 INIT_FUNC_WATCHDOG_RESET 31 #ifdef CONFIG_CMD_NAND 32 initr_nand, 33 #endif 34 initr_env, 35 INIT_FUNC_WATCHDOG_RESET 36 initr_secondary_cpu, 37 INIT_FUNC_WATCHDOG_RESET 38 stdio_add_devices, 39 initr_jumptable, 40 console_init_r, /* fully init console as a device */ 41 INIT_FUNC_WATCHDOG_RESET 42 interrupt_init, 43 #ifdef CONFIG_ARM 44 initr_enable_interrupts, 45 #endif 46 /* PPC has a udelay(20) here dating from 2002. Why? */ 47 #ifdef CONFIG_CMD_NET 48 initr_ethaddr, 49 #endif 50 #ifdef CONFIG_CMD_NET 51 INIT_FUNC_WATCHDOG_RESET 52 initr_net, 53 #endif 54 run_main_loop, 55 };
到最后执行run_main_loop 函数,进行内核的调用。
10.2 main_loop
run_main_loop 调用 main_loop,main_loop定义在common/main.c中:
1 /* We come here after U-Boot is initialised and ready to process commands */ 2 void main_loop(void) 3 { 4 const char *s; 5 6 /* bootstage_mark_name函数调用了show_boot_progress,利用它显示启动进程(progress), 7 此处为空函数 */ 8 bootstage_mark_name(BOOTSTAGE_ID_MAIN_LOOP, "main_loop"); 9 10 #ifdef CONFIG_VERSION_VARIABLE 11 /* setenv 设置环境变量 ver 为 version_string,后者在common/cmd_version.c中定义为: 12 const char __weak version_string[] = U_BOOT_VERSION_STRING; */ 13 /* U_BOOT_VERSION_STRING在version.h中定义 */ 14 env_set("ver", version_string); /* set version variable */ 15 #endif /* CONFIG_VERSION_VARIABLE */ 16 17 /* cli_init用来初始化hush shell使用的一些变量。 */ 18 cli_init(); 19 20 /* run_preboot_environment_command函数从环境变量中获取"preboot"的定义,*/ 21 /* 该变量包含了一些预启动命令,一般环境变量中不包含该项配置。 */ 22 run_preboot_environment_command(); 23 24 #if defined(CONFIG_UPDATE_TFTP) 25 update_tftp(0UL, NULL, NULL); 26 #endif /* CONFIG_UPDATE_TFTP */ 27 28 /* bootdelay_process从环境变量中取出"bootdelay"和"bootcmd"的配置值 */ 29 /* 将取出的"bootdelay"配置值转换成整数,赋值给全局变量stored_bootdelay */ 30 /* 最后返回"bootcmd"的配置值 */ 31 /*bootdelay为u-boot的启动延时计数值,计数期间内如无用户按键输入干预,那么将执行"bootcmd"配置中的命令。*/ 32 s = bootdelay_process(); 33 if (cli_process_fdt(&s)) 34 cli_secure_boot_cmd(s); 35 36 /* autoboot_command,该函数在common/autoboot.c中实现 */ 37 autoboot_command(s); 38 39 /* 进入 uboot 命令行中 */ 40 cli_loop(); 41 panic("No CLI available"); 42 }