u-boot启动分析01(u-boot.lds,start.S)
接着上一篇文章分析。
arch/arm/cpu/armv8/start.S
bl _main
跳转到_main函数。
u-boot15/arch/arm/lib/crt0_64.S
代码注释非常详细。
/*
* This file handles the target-independent stages of the U-Boot
* start-up where a C runtime environment is needed. Its entry point
* is _main and is branched into from the target's start.S file.
*
* _main execution sequence is:
*
* 1. Set up initial environment for calling board_init_f().
* This environment only provides a stack and a place to store
* the GD ('global data') structure, both located in some readily
* available RAM (SRAM, locked cache...). In this context, VARIABLE
* global data, initialized or not (BSS), are UNAVAILABLE; only
* CONSTANT initialized data are available.
*
* 2. Call board_init_f(). This function prepares the hardware for
* execution from system RAM (DRAM, DDR...) As system RAM may not
* be available yet, , board_init_f() must use the current GD to
* store any data which must be passed on to later stages. These
* data include the relocation destination, the future stack, and
* the future GD location.
*
* (the following applies only to non-SPL builds)
*
* 3. Set up intermediate environment where the stack and GD are the
* ones allocated by board_init_f() in system RAM, but BSS and
* initialized non-const data are still not available.
*
* 4. Call relocate_code(). This function relocates U-Boot from its
* current location into the relocation destination computed by
* board_init_f().
*
* 5. Set up final environment for calling board_init_r(). This
* environment has BSS (initialized to 0), initialized non-const
* data (initialized to their intended value), and stack in system
* RAM. GD has retained values set by board_init_f(). Some CPUs
* have some work left to do at this point regarding memory, so
* call c_runtime_cpu_setup.
*
* 6. Branch to board_init_r().
*/
u-boot15/arch/arm/lib/board.c
void board_init_f(ulong bootflag)
{
... ...
memset((void *)gd, 0, sizeof(gd_t));
gd->mon_len = (ulong)&__bss_end - (ulong)_start;
#ifdef CONFIG_OF_EMBED
/* Get a pointer to the FDT */
gd->fdt_blob = __dtb_dt_begin;
#elif defined CONFIG_OF_SEPARATE
/* FDT is at end of image */
gd->fdt_blob = &_end;
#endif
/* Allow the early environment to override the fdt address */
gd->fdt_blob = (void *)getenv_ulong("fdtcontroladdr", 16,
(uintptr_t)gd->fdt_blob);
//遍历执行 init_sequence 函数指针数组里面的每一个函数
for (init_fnc_ptr = init_sequence; *init_fnc_ptr; ++init_fnc_ptr) {
if ((*init_fnc_ptr)() != 0) {
hang ();
}
}
//init_sequence 定义
init_fnc_t *init_sequence[] = {
arch_cpu_init, /* basic arch cpu dependent setup */
mark_bootstage,
#ifdef CONFIG_OF_CONTROL
fdtdec_check_fdt,
#endif
#if defined(CONFIG_BOARD_EARLY_INIT_F)
board_early_init_f,
#endif
timer_init, /* initialize timer */
#ifdef CONFIG_BOARD_POSTCLK_INIT
board_postclk_init,
#endif
#ifdef CONFIG_FSL_ESDHC
get_clocks,
#endif
env_init, /* initialize environment */
init_baudrate, /* initialze baudrate settings */
serial_init, /* serial communications setup */
console_init_f, /* stage 1 init of console */
#ifdef CONFIG_SPRD_LOG
init_log_buffer, /* initialze sprd log buffer */
#endif
display_banner, /* say that we are here */
print_cpuinfo, /* display cpu info (and speed) */
#if defined(CONFIG_DISPLAY_BOARDINFO)
checkboard, /* display board info */
#endif
#if defined(CONFIG_HARD_I2C) || defined(CONFIG_SYS_I2C)
init_func_i2c,
#endif
dram_init, /* configure available RAM banks */
NULL,
};
/* Ram ist board specific, so move it to board code ... */
dram_init_banksize();
display_dram_config(); /* and display it */
u-boot15/arch/arm/lib/board.c
void board_init_r(gd_t *id, ulong dest_addr)
{
... ...
debug("monitor flash len: %08lX\n", monitor_flash_len);
board_init(); /* Setup chipselects */
... ...
}
board_init代码路径:uboot15/board/spreadtrum/uis8581e2h10/uis8581e2h10.c
主要是芯片电源管理,gpio,led,时钟相关初始化,以及片选。
int board_init(void)
{
setup_chipram_env();
#ifndef CONFIG_FPGA
gd->bd->bi_boot_params = PHYS_SDRAM_1 + 0x100;
ADI_init();
/*FPGA forbiden*/
regulator_init();
pmic_adc_Init();
/*FPGA forbiden*/
pin_init();
sprd_gpio_init();
misc_init();
sprd_eic_init();
sprd_led_init();
/*FPGA forbiden*/
sprd_pmu_lowpower_init();
enable_global_clocks();
#endif
return 0;
}
void board_init_r(gd_t *id, ulong dest_addr)
{
... ...
/* initialize environment */
if (should_load_env())
env_relocate();
else
set_default_env(NULL);
... ...
}
#ifdef CONFIG_BOARD_LATE_INIT
board_late_init();
#endif
宏定义位置:u-boot15/include/configs/uis8581e2h10.h
#define CONFIG_BOARD_LATE_INIT /* call board_late_init() */
board_late_init代码路径:uboot15/board/spreadtrum/uis8581e2h10/uis8581e2h10.c
int board_late_init(void)
{
boot_mode_t boot_role;
extern chipram_env_t* get_chipram_env(void);
chipram_env_t* cr_env = get_chipram_env();
boot_role = cr_env->mode;
boot_pwr_check();
my_init(); //自定义init
#if !defined(CONFIG_FPGA)
#ifdef CONFIG_NAND_BOOT
//extern int nand_ubi_dev_init(void);
nand_ubi_dev_init();
debugf("nand ubi init OK!\n");
#endif
battery_init();
debugf("CHG init OK!\n");
#endif
board_keypad_init();
return 0;
}
void board_init_r(gd_t *id, ulong dest_addr)
{
... ...
/* main_loop() can return to retry autoboot, if so just run it again. */
for (;;) {
main_loop();
}
... ...
}
至此,u-boot初始化完成,下一阶段处理命令。