uboot啟動(dòng)可分為匯編語言執(zhí)行和C語言執(zhí)行兩個(gè)階段,兩個(gè)階段以_main函數(shù)為分界。
uboot第一階段由_start (arch/arm/lib/vectors.S)進(jìn)入,然后跳轉(zhuǎn)到reset(arch/arm/cpu/armv7/start.S)函數(shù), reset函數(shù)進(jìn)行設(shè)置CPU運(yùn)行模式,關(guān)閉中斷等一系列CPU內(nèi)部環(huán)境初始化后,跳轉(zhuǎn)到_main函數(shù)。
第二階段通過_main函數(shù)進(jìn)入,_main主要做了如下功能:
一、設(shè)置C代碼的運(yùn)行環(huán)境,為調(diào)用board_init_f接口做準(zhǔn)備:
(一)設(shè)置堆棧(C代碼的函數(shù)調(diào)用,堆棧是必須的);
(二)調(diào)用board_init_f接口,從堆棧開始的地方,為u-boot中g(shù)lobal data數(shù)據(jù)結(jié)構(gòu),分配空間;
(三)調(diào)用board_init_f_init_reserve接口,對(duì)gd進(jìn)行初始化;
二、調(diào)用board_init_f函數(shù),完成一些前期的初始化工作,例如:
(一)設(shè)置gd結(jié)構(gòu)體中各成員在內(nèi)存中的地址,包括環(huán)境變量地址、uboot重定位的地址;
(二)串口初始化,打印板卡信息;
三、根據(jù)board_init_f 指定的uboot重定位的地址,執(zhí)行u-boot的relocation重定位操作。
四、清除BSS段。
五、調(diào)用board_init_r函數(shù),執(zhí)行后續(xù)的板級(jí)初始化操作,包括各種外設(shè)接口、中斷、環(huán)境變量等。最后調(diào)用run_main_loop()函數(shù),進(jìn)入倒計(jì)時(shí)等待,等待超時(shí)后執(zhí)行bootcmd啟動(dòng)內(nèi)核。
具體流程如下圖: