从crt0.S的_main跳转至 board_init_r,此时已经在外部的ddr中运行此代码,完整的c语言环境已经建立完毕。
board_init_r接着进行后续外围硬件的初始化。
简介
board_init_r主要做了
1.外围硬件的初始化。
2.跳转至最终的main_loop命令行。
代码注释
void board_init_r(gd_t *id, ulong dest_addr)
{
ulong malloc_start;
#if !defined(CONFIG_SYS_NO_FLASH)
ulong flash_size;
#endif
gd->flags |= GD_FLG_RELOC; /* tell others: relocation done */ //搬运完成
bootstage_mark_name(BOOTSTAGE_ID_START_UBOOT_R, "board_init_r"); //board_init_r mark
monitor_flash_len = (ulong)&__rel_dyn_end - (ulong)_start;
/* Enable caches */
enable_caches();
debug("monitor flash len: %08lX\n", monitor_flash_len);
board_init(); /* Setup chipselects */
/*
* 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
set_cpu_clk_info(); /* Setup clock information */
#endif
serial_initialize(); //串口初始化
debug("Now running in RAM - U-Boot at: %08lx\n", dest_addr);
#ifdef CONFIG_LOGBUFFER
logbuff_init_ptrs(); //logbuff初始化
#endif
#ifdef CONFIG_POST
post_output_backlog();
#endif
/* The Malloc area is immediately below the monitor copy in DRAM */
malloc_start = dest_addr - TOTAL_MALLOC_LEN; // (16 * SZ_1M)
mem_malloc_init (malloc_start, TOTAL_MALLOC_LEN); // malloc初始化
#ifdef CONFIG_ARCH_EARLY_INIT_R
arch_early_init_r(); //
#endif
power_init_board();
#if !defined(CONFIG_SYS_NO_FLASH) //include/configs/*.h
puts("Flash: ");
flash_size = flash_init(); //flash初始化
if (flash_size > 0) {
# ifdef CONFIG_SYS_FLASH_CHECKSUM
print_size(flash_size, "");
/*
* Compute and print flash CRC if flashchecksum is set to 'y'
*
* NOTE: Maybe we should add some WATCHDOG_RESET()? XXX
*/
if (getenv_yesno("flashchecksum") == 1) { //计算flash的checksum
printf(" CRC: %08X", crc32(0,
(const unsigned char *) CONFIG_SYS_FLASH_BASE,
flash_size));
}
putc('\n');
# else /* !CONFIG_SYS_FLASH_CHECKSUM */
print_size(flash_size, "\n");
# endif /* CONFIG_SYS_FLASH_CHECKSUM */
} else { //flash初始化失败
puts(failed);
hang();
}
#endif
#if defined(CONFIG_CMD_NAND) //NAND初始化
puts("NAND: ");
nand_init(); /* go init the NAND */
#endif
#if defined(CONFIG_CMD_ONENAND) //ONE_NAND初始化
onenand_init();
#endif
#ifdef CONFIG_GENERIC_MMC //MMC初始化
puts("MMC: ");
mmc_initialize(gd->bd);
#endif
#ifdef CONFIG_CMD_SCSI //SCSI初始化
puts("SCSI: ");
scsi_init();
#endif
#ifdef CONFIG_HAS_DATAFLASH //DATA_FLASH初始化
AT91F_DataflashInit();
dataflash_print_info();
#endif
/* initialize environment */
if (should_load_env()) //load env
env_relocate();
else
set_default_env(NULL);
#if defined(CONFIG_CMD_PCI) || defined(CONFIG_PCI) //PCI初始化
arm_pci_init();
#endif
stdio_init(); /* get the devices list going. */ //i2c/lcd/video/keyboard/硬件初始化
jumptable_init(); //将函数指针放在malloc所在的堆区
#if defined(CONFIG_API)
/* Initialize API */
api_init(); //api回调函数初始化
#endif
console_init_r(); /* fully init console as a device */ //串口彻底初始化
#ifdef CONFIG_DISPLAY_BOARDINFO_LATE
# ifdef CONFIG_OF_CONTROL
/* Put this here so it appears on the LCD, now it is ready */
display_fdt_model(gd->fdt_blob); //打印fdt的model到lcd屏幕上
# else
checkboard(); //打印板子id
# endif
#endif
#if defined(CONFIG_ARCH_MISC_INIT)
/* miscellaneous arch dependent initialisations */
arch_misc_init(); //MISC 初始化
#endif
#if defined(CONFIG_MISC_INIT_R)
/* miscellaneous platform dependent initialisations */
misc_init_r(); //MISC 相关初始化 自定义
#endif
/* set up exceptions */
interrupt_init(); //初始化中断
/* enable exceptions */
enable_interrupts(); //中断使能
/* Initialize from environment */
load_addr = getenv_ulong("loadaddr", 16, load_addr); //get load_addr
#ifdef CONFIG_BOARD_LATE_INIT
board_late_init(); //board/freescale/board.c
#endif
#ifdef CONFIG_FSL_FASTBOOT
fastboot_setup(); //fastboot安装
#endif
#ifdef CONFIG_BITBANGMII
bb_miiphy_init(); //MII初始化
#endif
#if defined(CONFIG_CMD_NET)
puts("Net: ");
eth_initialize(gd->bd); //网口初始化
#if defined(CONFIG_RESET_PHY_R)
debug("Reset Ethernet PHY\n");
reset_phy(); //reset phy
#endif
#endif
#ifdef CONFIG_POST
post_run(NULL, POST_RAM | post_bootmode_get(0)); //测试含POST_RAM flag的测试项, 以及之前指定的需要测试的部分.
#endif
#if defined(CONFIG_PRAM) || defined(CONFIG_LOGBUFFER)
/*
* Export available size of memory for Linux,
* taking into account the protected RAM at top of memory
*/
{
ulong pram = 0; //pram
uchar memsz[32];
#ifdef CONFIG_PRAM
pram = getenv_ulong("pram", 10, CONFIG_PRAM); //get pram
#endif
#ifdef CONFIG_LOGBUFFER
#ifndef CONFIG_ALT_LB_ADDR
/* Also take the logbuffer into account (pram is in kB) */
pram += (LOGBUFF_LEN + LOGBUFF_OVERHEAD) / 1024; //pram += (LOGBUFF_LEN + LOGBUFF_OVERHEAD) / 1024;
#endif
#endif
sprintf((char *)memsz, "%ldk", (gd->ram_size / 1024) - pram);
setenv("mem", (char *)memsz); //mem = (gd->ram_size / 1024) - pram)
}
#endif
#ifdef CONFIG_FSL_FASTBOOT
check_fastboot(); //run cmd fastboot
#endif
/* main_loop() can return to retry autoboot, if so just run it again. */
for (;;) {
main_loop();
}
/* NOTREACHED - no way out of command loop except booting */
}