U-boot 启动流程分析 4

下面详细介绍board_init_r函数的调用流程

board_init_r主要做一些板级硬件的初始化,会对板子上的各个外设进行初始化配置,最后调用run_main_loop进入下一级boot或者进入boot console。

1、board_init_r函数类似前面的board_init_f,关键就是遍历执行数组init_sequence_r里面的函数来初始化硬件,下面是具体的代码讲解:


/*
 * We hope to remove most of the driver-related init and do it if/when
 * the driver is later used.
 *
 * TODO: perhaps reset the watchdog in the initcall function after each call?
 */
static init_fnc_t init_sequence_r[] = {
	//根据CONFIG_TRACE来初始化trace system
	initr_trace,
	
	//设置gd flags,标记重定向完成,malloc 已经ready
	initr_reloc, 
	
	/* TODO: could x86/PPC have this also perhaps? */
#ifdef CONFIG_ARM
	initr_caches,
	/* Note: For Freescale LS2 SoCs, new MMU table is created in DDR.
	 *	 A temporary mapping of IFC high region is since removed,
	 *	 so environmental variables in NOR flash is not available
	 *	 until board_init() is called below to remap IFC to high
	 *	 region.
	 */
#endif
	initr_reloc_global_data, //获取uboot的大小,赋值到monitor_flash_len里面
#if defined(CONFIG_SYS_INIT_RAM_LOCK) && defined(CONFIG_E500)
	initr_unlock_ram_in_cache,
#endif
	// PPC专用
	initr_barrier,
	
	//初始化malloc使用的内存区域和大小
	initr_malloc,
	
	// 初始化log system, flag设置为GD_FLG_LOG_READY
	log_init,

	//设置启动stage为board_init_r
	initr_bootstage,	/* Needs malloc() but has its own timer */

	//初始化控制台,申请console_out 和console_in buffer
	initr_console_record,
#ifdef CONFIG_SYS_NONCACHED_MEMORY
	//初始化不经过cache的内存,这个需要cpu支持
	initr_noncached,
#endif
	//设置boot stage为of_live,解析传进来设备树,把dtb里面的信息记录下来
	initr_of_live,
#ifdef CONFIG_DM
	//初始化驱动模型的结构并扫描所有的设备
	initr_dm,
#endif
#if defined(CONFIG_ARM) || defined(CONFIG_NDS32) || defined(CONFIG_RISCV) || \
	defined(CONFIG_SANDBOX)
	board_init,	/* Setup chipselects,进行板级的初始化 */
#endif
	/*
	 * TODO: printing of the clock inforamtion of the board is now
	 * implemented as part of bdinfo command. Currently only support for
	 * davinci SOC's is added. Remove this check once all the board
	 * implement this.
	 */
#ifdef CONFIG_CLOCKS
	//获取cpu的clock信息,保存在gd里面
	set_cpu_clk_info, /* Setup clock information */
#endif
#ifdef CONFIG_EFI_LOADER
	efi_memory_init,
#endif
	//分配struct binman_info结构内存,并设置binman相关信息参数
	initr_binman,
#ifdef CONFIG_FSP_VERSION2
	arch_fsp_init_r,
#endif
	
//在系统启动早期初始化定时器,和将多路复用控制初始化为默认状态
	initr_dm_devices,
	
	//用于初始化标准输出设备链表(struct stdio_dev)
	stdio_init_tables,

	//注册串行端口设备
	serial_initialize,

	//打印出运行调试信息
	initr_announce,
#if CONFIG_IS_ENABLED(WDT)
	//初始化看门狗
	initr_watchdog,
#endif
	INIT_FUNC_WATCHDOG_RESET
#if defined(CONFIG_NEEDS_MANUAL_RELOC) && defined(CONFIG_BLOCK_CACHE)
	blkcache_init,
#endif
#ifdef CONFIG_NEEDS_MANUAL_RELOC
	initr_manual_reloc_cmdtable,
#endif
#if defined(CONFIG_PPC) || defined(CONFIG_M68K) || defined(CONFIG_MIPS)
	initr_trap,
#endif
#ifdef CONFIG_ADDR_MAP
	initr_addr_map,
#endif
#if defined(CONFIG_BOARD_EARLY_INIT_R)
	board_early_init_r,
#endif
	INIT_FUNC_WATCHDOG_RESET
#ifdef CONFIG_POST
	initr_post_backlog,
#endif
	INIT_FUNC_WATCHDOG_RESET
#if defined(CONFIG_PCI) && defined(CONFIG_SYS_EARLY_PCI_INIT)
	/*
	 * Do early PCI configuration _before_ the flash gets initialised,
	 * because PCU resources are crucial for flash access on some boards.
	 */
	 //初始化pci
	initr_pci,
#endif
#ifdef CONFIG_ARCH_EARLY_INIT_R
	//cpu相关的初始化,自己实现
	arch_early_init_r,
#endif
	//初始化电源管理,和具体的cpu和板子有关,自己实现
	power_init_board,
#ifdef CONFIG_MTD_NOR_FLASH
	//NOR flash的初始化
	initr_flash,
#endif
	INIT_FUNC_WATCHDOG_RESET
#if defined(CONFIG_PPC) || defined(CONFIG_M68K) || defined(CONFIG_X86)
	/* initialize higher level parts of CPU like time base and timers */
	cpu_init_r,
#endif
#ifdef CONFIG_CMD_NAND
	//NAND flash的初始化
	initr_nand,
#endif
#ifdef CONFIG_CMD_ONENAND
	//onenand flash的初始化
	initr_onenand,
#endif
#ifdef CONFIG_MMC
	//mmc的初始化
	initr_mmc,
#endif
#ifdef CONFIG_XEN
	initr_xen,
#endif
#ifdef CONFIG_PVBLOCK
	initr_pvblock,
#endif
	//初始化环境变量,找到load address
	initr_env,
#ifdef CONFIG_SYS_BOOTPARAMS_LEN
	//为boot参数分配地址
	initr_malloc_bootparams,
#endif
	INIT_FUNC_WATCHDOG_RESET
	initr_secondary_cpu, //weak函数,cpu的初始化
#if defined(CONFIG_ID_EEPROM) || defined(CONFIG_SYS_I2C_MAC_OFFSET)
	mac_read_from_eeprom,
#endif
	INIT_FUNC_WATCHDOG_RESET
#if defined(CONFIG_PCI) && !defined(CONFIG_SYS_EARLY_PCI_INIT)
	/*
	 * Do pci configuration
	 */
	initr_pci,
#endif
	//添加stdio设备到设备表中,iic 串口,lcd,video等等都属于stdio设备
	stdio_add_devices,
	//为gd的jt申请memory
	initr_jumptable,
	
	//下面都是为各种外设进行初始化,太多了,不去一一看了,用到哪个具体分析
#ifdef CONFIG_API
	initr_api,
#endif
	console_init_r,		/* fully init console as a device */
#ifdef CONFIG_DISPLAY_BOARDINFO_LATE
	console_announce_r,
	show_board_info,
#endif
#ifdef CONFIG_ARCH_MISC_INIT
	arch_misc_init,		/* miscellaneous arch-dependent init */
#endif
#ifdef CONFIG_MISC_INIT_R
	misc_init_r,		/* miscellaneous platform-dependent init */
#endif
	INIT_FUNC_WATCHDOG_RESET
#ifdef CONFIG_CMD_KGDB
	initr_kgdb,
#endif
	interrupt_init,
#if defined(CONFIG_MICROBLAZE) || defined(CONFIG_M68K)
	timer_init,		/* initialize timer */
#endif
#if defined(CONFIG_LED_STATUS)
	initr_status_led,
#endif
	/* PPC has a udelay(20) here dating from 2002. Why? */
#ifdef CONFIG_CMD_NET
	initr_ethaddr,
#endif
#if defined(CONFIG_GPIO_HOG)
	gpio_hog_probe_all,
#endif
#ifdef CONFIG_BOARD_LATE_INIT
	board_late_init,
#endif
#if defined(CONFIG_SCSI) && !defined(CONFIG_DM_SCSI)
	INIT_FUNC_WATCHDOG_RESET
	initr_scsi,
#endif
#ifdef CONFIG_BITBANGMII
	initr_bbmii,
#endif
#ifdef CONFIG_PCI_ENDPOINT
	initr_pci_ep,
#endif
#ifdef CONFIG_CMD_NET
	INIT_FUNC_WATCHDOG_RESET
	initr_net,
#endif
#ifdef CONFIG_POST
	initr_post,
#endif
#if defined(CONFIG_IDE) && !defined(CONFIG_BLK)
	initr_ide,
#endif
#ifdef CONFIG_LAST_STAGE_INIT
	INIT_FUNC_WATCHDOG_RESET
	/*
	 * Some parts can be only initialized if all others (like
	 * Interrupts) are up and running (i.e. the PC-style ISA
	 * keyboard).
	 */
	last_stage_init,
#endif
#ifdef CONFIG_CMD_BEDBUG
	INIT_FUNC_WATCHDOG_RESET
	bedbug_init,
#endif
#if defined(CONFIG_PRAM)
	initr_mem,
#endif
#ifdef CONFIG_EFI_SETUP_EARLY
	(init_fnc_t)efi_init_obj_list,
#endif
	//这个是关键的关键,board_int_r最后调用的函数,死循环在main_loop里面,后门分析main_loop
	run_main_loop,
};

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值