一、啓動流程
系統完整啓動流程分爲4個階段:ROM Code---àx-loader---àu-boot---àLinux系統。
二、各階段詳細分析
2. 1 ROM Code
該階段代碼固化在芯片內部ROM中,TI不開源。AM3517支持多種方式的啓動,並且可以設置啓動順序,設置功能是通過7個引腳sys_boot0~sys_boot6電平來控制的,其中sys_boot6控制選擇時鐘,sys_boot0~sysboot5設置啓動順序。如0b10101首先從NANDFLASH啓動,0b10010首先從MMC1即SD卡啓動。
2.2一級啓動代碼x-loader
x-loader是u-boot的精簡版本,其主要功能是配置DPLL時鐘,初始化外部RAM,然後從NADFLASH或SD卡讀取u-boot並運行。其啓動過程如下:
(1)x-loader第一個運行文件是位於/cpu/omap3/下的彙編程序start.S。
(2)在start.S中會調用 /board/am3517evm/platform.S中的lowlevel_init函數,該函數又會調用C語言函數s_init(位於/board/am3517evm/Am3517evm.c中),該函數會依次完成下列工作:
(a)關閉看門狗2(watchdog_init()函數);
(b)解鎖存儲器(try_unlock_memory()函數),這是OMAP系列MPU的保護機制,不解鎖的話將無法寫一些寄存器;
(c)配置相關資源引腳的模式(set_muxconf_regs());
(d)配置各個模塊時鐘(prcm_init()):Core_DPLL:332MHz;MPU_DPLL:380MHz;PER_DPLL: 432MHz;
(e)配置外部RAM(config_emif4_ddr()):
(3)之後x-loader進入第二階段,入口函數是/lib/board.c程序中的start_armboot();
(4)x-loader第二階段的主要功能是通過讀取sys_boot~-sys_boot0引腳的值判斷是從NANDFLASH還是從SD卡啓動,並從判斷結果中拷貝u-boot到RAM中並運行。
2.3二級啓動代碼u-boot
u-boot是二級引導程序,分爲stage1和stage2兩個階段,第一階段爲彙編代碼,位於/cpu/arm_cortexa8/start.S中,啓動過程同x-loader;第二階段爲C語言代碼,位於/lib_arm/board.c中的start_armboot(void)函數,它是整個啓動代碼的C語言的主函數,同時也是整個u-boot的主函數。下面重點分析void start_armboot(void)函數。
進入start_armboot()函數後,首先定義了一個函數指針數組init_fnc_t *init_sequence[],通過這個數組,程序按順序執行初始化工作。
board_init:初始化GPMC控制器(NANDFLASH);
timer_init:初始化定時器Gptimer2,在這個地方就是空跑,沒有其他意義;/** Nothing really to do with interrupts, just starts up a counter. We run the counter with 13MHz, divided by 8, resulting in timer frequency of 1.625MHz. With 32bit counter register, counter overflows in ~44min*/
console_init_f;控制檯前期初始化(common/console.c)由於標準設備還沒有初始化(gd->flags & GD_FLG_DEVINIT=0),這時控制檯使用串口作爲控制檯,函數只有一句:gd->have_console = 1;
init_func_i2c:初始化I2C控制器;
dram_init:DDR BANKS配置信息,起始地址和長度;
如果函數指針數組內部任一初始化函數失敗,u-boot將終止運行,導致啓動失敗。成功初始化完該函數指針數組成員後,通過操作兩個數據結構(gd_t和bd_t)繼續運行u-boot.
nand_init:NADN FLASH配置信息,起始地址、容量等;
stdio_init:初始化標準輸入輸出設備,該函數又調用了以下函數:drv_video_init初始化DSS控制器(LCD),並顯示特定LOGO;
console_init_r():控制檯設備完整的初始化,stdio_init()函數中註冊了LCD爲標準輸入輸出設備,因此可以將LCD屏作爲顯示控制檯;
eth_initialize(gd->bd):初始化以太網卡設備。