Uboot 2017 01 啟動流程分析

2021-08-11 14:41:03 字數 2960 閱讀 5038

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...