調用 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 }
這里同樣建立了一個鏈表,分析里面的設置即可。
11.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 函數,進行內核的調用。
11.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 }