u-boot启动分析02(board_init_f,board_init_r)

u-boot启动分析01(u-boot.lds,start.S)
接着上一篇文章分析。
arch/arm/cpu/armv8/start.S

bl	_main

跳转到_main函数。

1._main函数分析

u-boot15/arch/arm/lib/crt0_64.S
代码注释非常详细。

  1. 为调用board_init_f()设置初始化环境;
  2. 调用board_init_f(),准备程序在内存中运行的硬件环境;
  3. 设置中间环境(stack 和GD已经在系统内存中就绪,但BSS和non-const data还不可用);
  4. 调用relocate_code重定向;
  5. 为board_init_r()设置最终环境;
  6. 执行board_init_r()。
/*
 * 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().
 */

2. board_init_f()

u-boot15/arch/arm/lib/board.c

2.1 初始化gd(global data)全局结构体变量

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);

2.2 一些硬件相关的初始化

//遍历执行 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,
};

2.3 初始化DRAM

/* Ram ist board specific, so move it to board code ... */
	dram_init_banksize();
	display_dram_config();	/* and display it */

3.board_init_r

u-boot15/arch/arm/lib/board.c

3.1 board_init

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;
}

3.2 加载环境变量

void board_init_r(gd_t *id, ulong dest_addr)
{
... ...
    /* initialize environment */
	if (should_load_env())
		env_relocate();
	else
		set_default_env(NULL);
... ...
}

3.3 board_late_init

#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;
}

3.4 进入主循环

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初始化完成,下一阶段处理命令。

  • 7
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值