Call board_init_r and pass in the destination address gd->rellocaddr in global GD and SDRAM
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([email protected]): 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 }
A linked list is also established here, and the settings in it can be analyzed.
10.1 init_sequence_r
Inside is just a series of initializations.
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 };
At the end, execute the run_main_loop function to call the kernel.
10.2 main_loop
run_main_loop calls main_loop, which is defined in 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 /* The bootstage_mark_name function calls show_boot_progress and uses it to display the boot process (progress ), 7 is an empty function here */ 8 bootstage_mark_name(BOOTSTAGE_ID_MAIN_LOOP, " main_loop " ); 9 10 #ifdef CONFIG_VERSION_VARIABLE 11 /* setenv set the environment variable ver to version_string, which is defined in common/cmd_version.c as: 12 const char __weak version_string[] = U_BOOT_VERSION_STRING; */ 13 /* U_BOOT_VERSION_STRING is defined in version.h */ 14 env_set( " ver " , version_string); /* set version variable */ 15 #endif /* CONFIG_VERSION_VARIABLE */ 16 17 /* cli_init is used to initialize some variables used by the hush shell. */ 18 cli_init(); 19 20 /* The run_preboot_environment_command function obtains the definition of "preboot" from the environment variable, */ 21 /* This variable contains some pre-boot commands, and this configuration is not included in general environment variables. */ 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 takes the configuration values of "bootdelay" and "bootcmd" from environment variables */ 29 /* Convert the extracted "bootdelay" configuration value to an integer and assign it to the global variable stored_bootdelay */ 30 /* Finally return the "bootcmd" configuration value */ 31 /* bootdelay is the boot delay count of u-boot If there is no user key input intervention during the count period, the command in the "bootcmd" configuration will be executed. */ 32 s = bootdelay_process(); 33 if(cli_process_fdt(& s)) 34 cli_secure_boot_cmd(s); 35 36 /* autoboot_command, this function is implemented in common/autoboot.c */ 37 autoboot_command(s); 38 39 /* enter the uboot command line */ 40 cli_loop (); 41 panic( " No CLI available " ); 42 }