【OK210试用体验】u-boot篇 -- u-boot启动流程总结
u-boot跟其他的bootloader类似,启动有两个阶段。对于新版的u-boot来说,重要的两个文件是 u-boot-spl.bin 和 u-boot.bin 。
结合裸机程序前的S5PV210启动流程,可以清晰地分析 S5PV210移植完u-boot 的启动流程。
启动流程简析
从S5PV210启动流程中,我们知道S5PV210上电后,先运行iROM里的 BL0 段代码,执行完对CPU的一系列初始化后,会从SD/MMC/NorFlash/NandFLash...里拷贝扇区1的 u-boot-spl.bin (即BL1)到iRAM中并跳转BL1的起始地址(0xD0020010)运行。
u-boot-spl.bin 除了做一些外设初始化和调整系统时钟外,重要的工作肯定是将外设存储器中的 u-boot.bin (即BL2)DDR等比较小的RAM中并且跳转到起始地址运行。
u-boot.bin 会继续做一些初始化操作,然后是在DDR中从高地址开始计算出内存布局,并且把 u-boot自身拷贝到计算出来的重定位地址上,接着根据 fixup table(.rel.dyn 和 .dynsym)修正重定位后的 u-boot.bin 的链接地址为其运行地址,最后跳转到定位后的 u-boot.bin 去执行。
第一阶段代码分析总结
第一个阶段完成了哪些事情呢?主要是完成了4项功能。
对硬件的初始化。这部分代码主要位于start.S中。主要是初始化异常向量表,设置SVC32模式,关闭中断(FIQ,IRQ),配置cp15,设置异常向量入口,无效L1 I/D,失能MMU、cache,板级初始化,初始化系统时钟(PLL、MUX)(lowlevel_init.S)。
对内存(SDRAM)做初始化,这部分代码主要位于lowlevel_init.S中。
设置系统堆栈。这部分代码主要在crt0.S的_main函数的前面部分。
拷贝BL2代码RAM中并且跳转到起始位置运行,这部分代码也在 start.S和 crt0.S 中。
第二阶段代码分析总结
第二阶段的代码起始在crt0.S中,重点函数当然是board_init_f,重点的两个函数 board_init_f 和 board_init_r 都位于 arch/arm/lib/board.c。
首先先进行硬件初始化。- for (init_fnc_ptr = init_sequence; *init_fnc_ptr; ++init_fnc_ptr) {
- if ((*init_fnc_ptr)() != 0) {
- hang ();
- }
- }
- 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 */
- 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,
- };
然后,是Flash设备与网络设备的初始化,再调用main_loop函数,U_BOOT_CMD定义,最后就是内核启动了。
有错误请指教。。。