uboot 【board_init_f】


void board_init_f(ulong boot_flags)
{
#ifdef CONFIG_SYS_GENERIC_GLOBAL_DATA
	/*
	 * For some archtectures, global data is initialized and used before
	 * calling this function. The data should be preserved. For others,
	 * CONFIG_SYS_GENERIC_GLOBAL_DATA should be defined and use the stack
	 * here to host global data until relocation.
	 */
	gd_t data;

	gd = &data;

	/*
	 * Clear global data before it is accessed at debug print
	 * in initcall_run_list. Otherwise the debug print probably
	 * get the wrong vaule of gd->have_console.
	 */
	zero_global_data();
#endif
    //初始化变量gd
	gd->flags = boot_flags;
	gd->have_console = 0;
    
    //按照init_sequence_f顺序进行初始化,包括定时器、串口、ddr等外设,更新gd值,并将uboot拷贝到内存的最后的地址区域
	if (initcall_run_list(init_sequence_f))
		hang();

#if !defined(CONFIG_ARM) && !defined(CONFIG_SANDBOX)
	/* NOTREACHED - jump_to_copy() does not return */
	hang();
#endif
}

board_init_f:

        1.初始化变量gd

        2.按照init_sequence_f顺序进行初始化,包括定时器、串口、ddr等外设,更新gd值,将uboot拷贝到内存的最后的地址区域,跳转到内存中继续运行uboot


static init_fnc_t init_sequence_f[] = {
#ifdef CONFIG_SANDBOX
	setup_ram_buf,
#endif
    //更新gd->mon_len,及uboot代码长度
	setup_mon_len,
	setup_fdt,
#ifdef CONFIG_TRACE
	trace_early_init,
#endif
    //初始化 gd 中跟 malloc 有关的成员变量,比如 malloc_limit,malloc_limit 表示 malloc
内存池大小
	initf_malloc,
#if defined(CONFIG_MPC85xx) || defined(CONFIG_MPC86xx)
	/* TODO: can this go into arch_cpu_init()? */
	probecpu,
#endif
	arch_cpu_init,		/* basic arch cpu dependent setup */
	mark_bootstage,
#ifdef CONFIG_OF_CONTROL
	fdtdec_check_fdt,
#endif
	initf_dm,
#if defined(CONFIG_BOARD_EARLY_INIT_F)
	board_early_init_f,
#endif
	/* TODO: can any of this go into arch_cpu_init()? */
#if defined(CONFIG_PPC) && !defined(CONFIG_8xx_CPUCLK_DEFAULT)
    //获取时钟相关信息,并更新到gd
	get_clocks,		/* get CPU and bus clocks (etc.) */
#if defined(CONFIG_TQM8xxL) && !defined(CONFIG_TQM866M) \
		&& !defined(CONFIG_TQM885D)
	adjust_sdram_tbs_8xx,
#endif
	/* TODO: can we rename this to timer_init()? */
	init_timebase,
#endif
#if defined(CONFIG_ARM) || defined(CONFIG_MIPS) || defined(CONFIG_BLACKFIN)
    //初始化定时器
	timer_init,		/* initialize timer */
#endif
#ifdef CONFIG_SYS_ALLOC_DPRAM
#if !defined(CONFIG_CPM2)
	dpram_init,
#endif
#endif
#if defined(CONFIG_BOARD_POSTCLK_INIT)
	board_postclk_init,
#endif
#ifdef CONFIG_FSL_ESDHC
	get_clocks,
#endif
    //获取环境变量的地址,并更新到gd
	env_init,		/* initialize environment */
#if defined(CONFIG_8xx_CPUCLK_DEFAULT)
	/* get CPU and bus clocks according to the environment variable */
	get_clocks_866,
	/* adjust sdram refresh rate according to the new clock */
	sdram_adjust_866,
	init_timebase,
#endif
    //从环境变量中读取波特率
	init_baud_rate,		/* initialze baudrate settings */
    //初始化串口
	serial_init,		/* serial communications setup */
    //设置 gd->have_console 为 1,表示有个控制台,此函数也将前面
暂存在缓冲区中的数据通过控制台打印出来
	console_init_f,		/* stage 1 init of console */
#ifdef CONFIG_SANDBOX
	sandbox_early_getopt_check,
#endif
#ifdef CONFIG_OF_CONTROL
	fdtdec_prepare_fdt,
#endif
	display_options,	/* say that we are here */
	display_text_info,	/* show debugging info if required */
#if defined(CONFIG_MPC8260)
	prt_8260_rsr,
	prt_8260_clks,
#endif /* CONFIG_MPC8260 */
#if defined(CONFIG_MPC83xx)
	prt_83xx_rsr,
#endif
#ifdef CONFIG_PPC
	checkcpu,
#endif
	print_cpuinfo,		/* display cpu info (and speed) */
#if defined(CONFIG_MPC5xxx)
	prt_mpc5xxx_clks,
#endif /* CONFIG_MPC5xxx */
#if defined(CONFIG_DISPLAY_BOARDINFO)
	checkboard,		/* display board info */
#endif
	INIT_FUNC_WATCHDOG_INIT
#if defined(CONFIG_MISC_INIT_F)
	misc_init_f,
#endif
	INIT_FUNC_WATCHDOG_RESET
#if defined(CONFIG_HARD_I2C) || defined(CONFIG_SYS_I2C)
    //初始化i2c接口
	init_func_i2c,
#endif
#if defined(CONFIG_HARD_SPI)
    //初始化spi接口
	init_func_spi,
#endif
	announce_dram_init,
	/* TODO: unify all these dram functions? */
#if defined(CONFIG_ARM) || defined(CONFIG_X86)
	dram_init,		/* configure available RAM banks */
#endif
#if defined(CONFIG_MIPS) || defined(CONFIG_PPC)
    //初始化ddr,并获取ddr大小,更新到gd
	init_func_ram,
#endif
#ifdef CONFIG_POST
	post_init_f,
#endif
	INIT_FUNC_WATCHDOG_RESET
#if defined(CONFIG_SYS_DRAM_TEST)
	testdram,
#endif /* CONFIG_SYS_DRAM_TEST */
	INIT_FUNC_WATCHDOG_RESET

#ifdef CONFIG_POST
	init_post,
#endif
	INIT_FUNC_WATCHDOG_RESET
	/*
	 * Now that we have DRAM mapped and working, we can
	 * relocate the code and continue running from DRAM.
	 *
	 * Reserve memory at end of RAM for (top down in that order):
	 *  - area that won't get touched by U-Boot and Linux (optional)
	 *  - kernel log buffer
	 *  - protected RAM
	 *  - LCD framebuffer
	 *  - monitor code
	 *  - board info struct
	 */
    //开始为uboot代码搬运做准备
    //更新gd->ram_size,gd->ram_top ,gd->relocaddr
	setup_dest_addr,
#if defined(CONFIG_BLACKFIN) || defined(CONFIG_NIOS2)
	/* Blackfin u-boot monitor should be on top of the ram */
    //根据uboot代码段的大小,计算gd->relocaddr
	reserve_uboot,
#endif
#if defined(CONFIG_LOGBUFFER) && !defined(CONFIG_ALT_LB_ADDR)
	reserve_logbuffer,
#endif
#ifdef CONFIG_PRAM
	reserve_pram,
#endif
	reserve_round_4k,
#if !(defined(CONFIG_SYS_ICACHE_OFF) && defined(CONFIG_SYS_DCACHE_OFF)) && \
		defined(CONFIG_ARM)
	reserve_mmu,
#endif
#ifdef CONFIG_LCD
	reserve_lcd,
#endif
	reserve_trace,
	/* TODO: Why the dependency on CONFIG_8xx? */
#if defined(CONFIG_VIDEO) && (!defined(CONFIG_PPC) || defined(CONFIG_8xx)) && \
		!defined(CONFIG_ARM) && !defined(CONFIG_X86) && \
		!defined(CONFIG_BLACKFIN)
	reserve_video,
#endif
#if !defined(CONFIG_BLACKFIN) && !defined(CONFIG_NIOS2)
	reserve_uboot,
#endif
#ifndef CONFIG_SPL_BUILD
	reserve_malloc,
	reserve_board,
#endif
	setup_machine,
	reserve_global_data,
	reserve_fdt,
	reserve_arch,
    //留出栈空间,先对 gd->start_addr_sp 减去 16,然后做 16 字节对齐
	reserve_stacks,
	setup_dram_config,
	show_dram_config,
#ifdef CONFIG_PPC
	setup_board_part1,
	INIT_FUNC_WATCHDOG_RESET
	setup_board_part2,
#endif
	display_new_sp,
#ifdef CONFIG_SYS_EXTBDINFO
	setup_board_extra,
#endif
	INIT_FUNC_WATCHDOG_RESET
	reloc_fdt,
	setup_reloc,
#ifdef CONFIG_X86
	copy_uboot_to_ram,
	clear_bss,
	do_elf_reloc_fixups,
#endif
#if !defined(CONFIG_ARM) && !defined(CONFIG_SANDBOX)
    //开始执行uboot代码拷贝,拷贝之后调用board_init_r,不返回,开始另一阶段的初始化
	jump_to_copy,
#endif
	NULL,
};

init_sequence_f:

        1.setup_mon_len:更新gd->mon_len,即uboot代码长度

        2.initf_malloc:初始化 gd 中跟 malloc 有关的成员变量,比如 malloc_limit,malloc_limit 表示 malloc内存池大小

        3.get_clocks:获取时钟相关信息,并更新到gd

        4.timer_init:初始化定时器

        5.env_init:获取环境变量的地址,并更新到gd,因为flash还未初始化,一般是将地址指向default_environment

        6.init_baud_rate:从环境变量中读取波特率

        7.serial_init:初始化串口

        8.console_init_f:设置 gd->have_console 为 1,表示有个控制台,此函数也将前面
暂存在缓冲区中的数据通过控制台打印出来

        9.init_func_i2c:初始化i2c接口

        10.初始化spi接口:init_func_spi

        11.init_func_ram:初始化ddr,并获取ddr大小,更新到gd。初始化DDR控制器,涉及片选(地址区间)以及相关时序等。

        12.setup_dest_addr:开始为uboot代码搬运做准备,更新gd->ram_size,gd->ram_top ,gd->relocaddr

        13.reserve_uboot:根据uboot代码段的大小,计算gd->relocaddr

        14.reserve_stacks:留出栈空间,先对 gd->start_addr_sp 减去 16,然后做 16 字节对齐

        15.jump_to_copy:开始执行uboot代码拷贝,拷贝之后调用board_init_r,不返回,开始另一阶段的初始化

你可能感兴趣的:(uboot,uboot)