2017.01 uboot包含兩個階段的啟動,乙個是spl啟動,乙個是正常的啟動我們稱為第二階段uboot。當然,我們也可以選擇使用spl和不使用。
在編譯的過程中,是先編譯第二階段uboot,然後在編譯spl的。這兩個階段的編譯時分離的。
擁有不同的配置,所以許多地方的巨集是和spl的不一樣。而且鏈結的檔案也不一致。
所以接下來,我們也會分為兩個部分進行分析。
在am437x平台中,實際的spl啟動就是mlo啟動階段。其執行空間為片內dram,所以對其大小有較為嚴格的限制。
通常使用spl初始化基本裝置後,將第二階段uboot載入進行sdram中執行。
其原始碼位於arch/arm/cpu/armv7/start.s中。
其中關鍵的呼叫關係如下:
呼叫:cpu_init_crit
b lowlevel_init
==>arch/arm/cpu/armv7/lowlevel_init.s
b s_init
在第一階段初始化完成後,便呼叫了s_init函式,其實現的原始碼是arch/arm/mach-omap2/an33xx/borad.c。
該函式就呼叫了乙個函式rtc_only();然後便返回到lowlevel_init函式中。
此時,lowlevel_init也已經完成他的任務,就返回到cpu_init_crit中。
然而,cpu_init_crit這個函式的工作也全都幹完了,便回到start.s中,然後便是
b _main
而這個_main函式位於:
arch/arm/lib/crt0.s中
在_main函式中,就呼叫了乙個跨時代的函式。
board_init_f (arch/arm/mach-omap2/am33xx/borad.c)
第三階段:板級初始化
void board_init_f(ulong dummy)
其中的sdram_ini(); 便是初始化sdram的關鍵**,所以,如果我們有自己的板子,我們也可以實現sdram_init函式來完成我們板子的sdram的初始化。
其呼叫關係如下:
board_init_f
==>early_system_init()
==>set_uart_mux_conf(); // 設定相應的pin為串列埠
==>board_early_init_f(); // 不同的板子可以實現這個函式
==>
==>sdram_init(); // 初始化sdram
執行完borad_init_f後,回到_main
這個時候,會去執行spl_relocate_stack_gd
重新定位在棧中的global_data。
如果定義了config_spl_stack_r,那麼就將之前在片內記憶體中的global_data物件重定位到sdram中,並且將棧指標指向sdram中的某一位址
最後,就會呼叫borad_init_r函式:
borad_init_r(common/spl/spl.c)
==>spl_board_init(); // 初始化串列埠
==> if (boot_from_devices(&spl_image, spl_boot_list,
array_size(spl_boot_list)))
=>遍歷loader,看哪個loader和裝置匹配。
==> spl_load_image
==>spl_mmc_load_image
==>spl_mmc_do_fs_boot
==>spl_load_image_fat(uboot.img) // 將uboot.img載入到記憶體,並進行解析
將映象載入到記憶體的時候,此時spl進行判斷,載入的映象是uboot還是kernel然後便跳轉到映象的入口中進行執行。此時,spl的使命便完成了
==>jump_to_image_no_args(&spl_image);
此階段的uboot是在記憶體中的了,記憶體已經初始化完畢,並且許多的引腳復用在上乙個階段就已經復用完畢了。
在編譯的過程中,是先編譯第二階段uboot,然後在編譯spl的。這兩個階段的編譯時分離的。擁有不同的配置,所以許多地方的巨集是和spl的不一樣。而且
鏈結的檔案也不一致。
通過驗證,就board_init_r函式而言,在spl中是鏈結向spl.c中的board_init_r函式,而在uboot中,是鏈結向board_r.c中的borad_init_r函式。
那麼,我們就從borad_init_r函式入手,看看第二階段的uboot是怎麼啟動的。
在分析的過程中,
我們直接在board_init_r函式實現成乙個死迴圈,但是發現還是有資訊能夠輸出,說明在board_init_r還進行了初始化的工作。
u-boot 2017.01-g03781bc-dirty (jul 14 2017 - 13:55:58 +0800)
cpu : am437x-gp rev 1.2
model: ti am437x gp evm
i2c: ready
dram: 1 gib
我們發現,其實在board_init_f中都已經鏈結在別的檔案中了,他是位於board_f.c檔案中
其中關鍵的函式就是 initcall_run_list(init_sequence_f);
我們來看看init_sequence_f是個什麼東西。
static init_fnc_t init_sequence_f = ;
我們發現這個是個類似陣列的玩意。通過函式名,我們大概可以知道,就是乙個個按順序去呼叫這個陣列裡面的函式。
uboot 2017 01初次編譯
首先配置makefile 中的交叉編譯工具 ch arch cross compile 這裡加 進行注釋掉 endif 新增後面兩句 arch arm cross compile usr local arm arm 2009q3 bin arm none linux gnueabi 首先需要配置,配...
uboot啟動流程概述 uboot啟動流程
u boot系統啟動流程 大多數bootloader都分為stage1和stage2兩大部分,u boot也不例外。依賴於cpu體系結構的 如裝置初始化 等 通常都放在stage1,且可以用組合語言來實現,而stage2則通常用c語言來實現,這樣可以實現複雜的功能,而且有更好的可讀性和移植性。2.1...
01 uboot2017 01啟動過程概述
u boot2017.01啟動過程分析pdf u boot2017.01原始碼分析及啟動命令解析 啟動過程6部分內容如下 01 u boot2017.01 啟動過程概述 02 u boot2017.01 spl階段分析 03 u boot2017.01 u boot階段分析 04 u boot201...