文章目录
- board_init_r
- 1. initr_trace
- 2. initr_reloc
- 3. initr_caches
- 4. initr_reloc_global_data
- 5. initr_barrier/initr_console_record
- 6. initr_malloc
- 7. board_init
- 8. stdio_init_tables
- 9. serial_initialize
- 10. initr_announce
- 11. power_init_board
- 12. initr_flash
- 13. initr_nand/initr_mmc
- 14. initr_env
- 15. stdio_add_devices
- 16. initr_jumptable
- 17. console_init_r
- 18. interrupt_init/initr_enable_interrupts
- 19. initr_ethaddr
- 20. board_late_init
- 21. initr_net
- 22. run_main_loop
board_init_r
调用 board_init_r 函数,入参 r0 = gd, r1 = gd->relocaddr
实际上这俩参数未用到!
//路径:arch/arm/lib/crt0.S L166
/* call board_init_r(gd_t *id, ulong dest_addr) */
mov r0, r9 /* gd_t */
ldr r1, [r9, #GD_RELOCADDR] /* dest_addr */
/* call board_init_r */
#if defined(CONFIG_SYS_THUMB_BUILD)
ldr lr, =board_init_r /* this is auto-relocated! */
bx lr
#else
ldr pc, =board_init_r /* this is auto-relocated! */
#endif
/* we should not return here. */
void board_init_r(gd_t *new_gd, ulong dest_addr)
{
if (initcall_run_list(init_sequence_r))
hang();
/* NOTREACHED - run_main_loop() does not return */
hang();
}
删减后的 init_sequence_r 数组(只列举相对重要的项)
init_fnc_t init_sequence_r[] = {
initr_trace,
initr_reloc,
initr_caches,
initr_reloc_global_data,
initr_barrier,
initr_malloc,
initr_console_record,
bootstage_relocate,
initr_bootstage,
board_init, /* Setup chipselects */
stdio_init_tables,
initr_serial,
initr_announce,
power_init_board,
initr_flash,
initr_nand,
initr_mmc,
initr_env,
initr_secondary_cpu,
stdio_add_devices,
initr_jumptable,
console_init_r, /* fully init console as a device */
interrupt_init,
initr_enable_interrupts,
initr_ethaddr,
board_late_init,
initr_net,
run_main_loop,
};
1. initr_trace
如果初始化宏 CONFIG_TRACE 则会调用 trace_init(gd->trace_buff, CONFIG_TRACE_BUFFER_SIZE);
初始化和调试跟踪有关的内容
2. initr_reloc
执行 gd->flags |= GD_FLG_RELOC | GD_FLG_FULL_MALLOC_INIT;
标记重定位操作已经完成
3. initr_caches
使能 catch
4. initr_reloc_global_data
初始化重定位后 gd 的一些成员变量
对于 IMX6ULL 只是设置了 monitor_flash_len
monitor_flash_len 是程序镜像的长度(包括 .code/.data/.rel.dyn)
不包括 .bss
static int initr_reloc_global_data(void)
{
monitor_flash_len = _end - __image_copy_start;
return 0;
}
5. initr_barrier/initr_console_record
IMX6ULL 未使用
6. initr_malloc
初始化 malloc
7. board_init
板卡外设初始化,分为两个阶段
- board_init
- board_late_init
//路径:board/freescale/mx6ull_myboard_nand/mx6ull_myboard_nand.c L693
int board_init(void)
{
/* Address of boot parameters */
gd->bd->bi_boot_params = PHYS_SDRAM + 0x100;
#ifdef CONFIG_SYS_I2C_MXC
setup_i2c(0, CONFIG_SYS_I2C_SPEED, 0x7f, &i2c_pad_info1);
#endif
#ifdef CONFIG_FEC_MXC
setup_fec(CONFIG_FEC_ENET_DEV);
#endif
#ifdef CONFIG_USB_EHCI_MX6
setup_usb();
#endif
#ifdef CONFIG_FSL_QSPI
board_qspi_init();
#endif
#ifdef CONFIG_NAND_MXS
setup_gpmi_nand();
#endif
return 0;
}
8. stdio_init_tables
进行 stdio 相关初始化
9. serial_initialize
初始化串口
10. initr_announce
与调试有关,通知已经在 RAM 中运行
static int initr_announce(void)
{
debug("Now running in RAM - U-Boot at: %08lx\n", gd->relocaddr);
return 0;
}
11. power_init_board
初始化电源芯片
12. initr_flash
IMX6ULL 未使用
13. initr_nand/initr_mmc
初始化 nand/emmc 二选一
同时输出调试信息
14. initr_env
初始化环境变量
15. stdio_add_devices
初始化各种输入/输出设备,如 LCD
路径:common/stdio.c L249
16. initr_jumptable
初始化跳转表
static int initr_jumptable(void)
{
jumptable_init(); //路径:common/exports.c L26
return 0;
}
17. console_init_r
控制台初始化
调用 stdio_print_current_devices 打印当前的控制台设备(In Out Err
)
18. interrupt_init/initr_enable_interrupts
初始化/使能中断
19. initr_ethaddr
从环境变量中获取 MAC 地址,保存到 bd->bi_enetaddr/bi_enet1addr/...
中
并不是初始化 ENET
static int initr_ethaddr(void)
{
bd_t *bd = gd->bd;
/* kept around for legacy kernels only ... ignore the next section */
eth_getenv_enetaddr("ethaddr", bd->bi_enetaddr);
#ifdef CONFIG_HAS_ETH1
eth_getenv_enetaddr("eth1addr", bd->bi_enet1addr);
#endif
#ifdef CONFIG_HAS_ETH2
eth_getenv_enetaddr("eth2addr", bd->bi_enet2addr);
#endif
#ifdef CONFIG_HAS_ETH3
eth_getenv_enetaddr("eth3addr", bd->bi_enet3addr);
#endif
#ifdef CONFIG_HAS_ETH4
eth_getenv_enetaddr("eth4addr", bd->bi_enet4addr);
#endif
#ifdef CONFIG_HAS_ETH5
eth_getenv_enetaddr("eth5addr", bd->bi_enet5addr);
#endif
return 0;
}
20. board_late_init
板卡外设初始化,分为两个阶段
- board_init
- board_late_init
//路径:board/freescale/mx6ull_myboard_nand/mx6ull_myboard_nand.c L731
int board_late_init(void)
{
#ifdef CONFIG_CMD_BMODE
add_board_boot_modes(board_boot_modes);
#endif
#ifdef CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG
if (is_mx6ull_9x9_evk() || is_mx6ull_14x14_evk())
setenv("board_name", "EVK");
else
setenv("board_name", "MYBOARD");
if (is_mx6ull_9x9_evk())
setenv("board_rev", "9X9");
else if (is_mx6ull_14x14_evk())
setenv("board_rev", "14X14");
else
setenv("board_rev", "NAND");
#endif
#ifdef CONFIG_ENV_IS_IN_MMC
board_late_mmc_env_init();
#endif
set_wdog_reset((struct wdog_regs *)WDOG1_BASE_ADDR);
return 0;
}
board_late_init 中完成一些环境变量来那个的设置,因此需要在 emmc/nand 等存储设备初始化完成后才能进行
如果使用的是 emmc/sd 则会调用 board_late_mmc_env_init 来切换当前使用的设备
因此不能合并到 board_init
特别说明: board_init 完成的是芯片内部外设的初始化,不是外部设备的初始化!
21. initr_net
初始化网络
注意,这里的网络指的整个 enet 重点是外部的 phy 芯片的初始化
enet 的 MAC 部分初始化在 board_init 中就完成了,此部分属于芯片的内部外设
initr_net
eth_initialize
board_eth_init
22. run_main_loop
主循环,处理交互命令
run_main_loop 不会返回!
总结:
board_init_r 完成的是外设、设备的初始化操作
- 初始化芯片外设(I2C、SPI)
- 初始化外部设备(存储器、网络等)
- 初始化输入/输出设备(控制台、显示、键盘等)
- 初始化环境变量
- 更新环境变量