uboot的那些事兒(以s5pv210為例)

2021-09-19 07:45:23 字數 3419 閱讀 6388

uboot本質是乙個裸機程式,一般在180k-400k之間,主要工作是引導核心的啟動、部署整個計算機系統、操作flash等板子上硬碟的驅動、最後提供乙個命令列介面(shell介面,關於shell介面後面會有講解)供人來操作,

uboot是乙個集大成者,可以在不同架構的不同板子上進行執行,但是功能強大的同時也帶來了很多的弊端,它的**十分的冗餘,十分的龐大,而uboot借助了makefile來實現複雜檔案的聯合配置。 而bootloader是針對uboot的乙個刪減版,它更專一,它僅僅只針對某一款板子實現啟動的任務。

uboot也不是萬能的,他必須和硬體進行相對應的**級別更改和移植,以適配我們的板子的硬體環境,然後才能從相應的啟動介質啟動。當然這也就是我們做uboot移植時最核心的工作。

uboot的會在指定的位置為linux核心準備一些啟動引數,核心啟動時在這個特定的位置去取uboot傳給他的引數,然後再核心之中解析這些引數,指導linux核心的啟動過程。

由於uboot是無條件的從零開始啟動(但是實際是因為晶元內部幫我們完成了啟動載入),而核心的啟動需要一定的條件的,所以核心的啟動需要uboot的幫助,對開發板級別的硬體的初始化、軟體的資料結構進行初始化,為核心提供啟動引數(機器碼,核心在ddr中開始執行的位址),幫助核心實現重定位,將核心從flash(sd/nandflsh)的kernel分割槽中讀取到ddr中,然後再跳轉至ddr之中執行kernel內的程式,啟動核心。

uboot在啟動完後列印出很多的資訊,然後進入倒數bootdelay秒後執行 bootcmd對應的啟動命令。如果使用者沒有進行干涉則會執行bootcmd進入自啟動核心流程(在核心成功啟動之後uboot就無用了),此時使用者可以按下回車鍵打斷uboot的自啟動過程進入uboot的命令列下,然後uboot就會一直工作在命令列下。而uboot的命令列就是乙個死迴圈,迴圈體內不斷地重複:接受命令,解析命令,執行命令。

對於晶元幫我們完成的這部分載入的程式,我們常稱其為bl0階段,之後uboot的啟動過程也被分成bl1  bl2兩個階段。但uboot的啟動不一定是非要分成兩個階段的,如果映象檔案是小於16kb的,那麼就不必分成兩個階段,映象檔案全會在sram中得到執行,而如果映象檔案超過16kb,就必須分成兩個階段進行啟動。這兩個階段就稱為bl1和bl2。bl1階段就是前16kb(有時也會設定為8kb),而bl2階段實際是整個uboot。(關於映象檔案需要說的是:映象檔案可能只是完成乙個簡單的功能,也可能是進行作業系統的載入)

下面分分別介紹一下三個階段:

s5pv210板子在出廠時會在晶元內部的  irom中固化引導uboot啟動的程式bl0;  bl0階段會先確定我們的的啟動方式,然後根據啟動方式的不同(),從特定的記憶體位置讀取uboot的第一階段bl1階段的**,並引導載入bl1階段的程式到sram(s5pv210晶元內自帶的),然後bl0在安全啟動模式下驗證bl1的完整性(16位元組的校驗頭);之後bl1階段將載入bl2階段的程式到sram(s5pv210晶元內自帶的),然後bl1在安全啟動模式下驗證bl2的完整性;最後bl2階段的程式將負責引導核心的啟動,跳轉到作業系統的起始位址。

關於bl0如何讀取uboot的啟動方式(nand/inand/sd),由於我們真正設定uboot的啟動方式的地方是在bl1階段,而此時我們還不知道從哪個位置讀取uboot的**,自然也就不能讀取啟動方式的選擇,進過初步分析我確定這是是根據我們硬體撥碼開關的的狀態對應的乙個暫存器的值來確定的。歡迎大神指教。

1. 禁用看門狗計時器

2. 初始化指令快取

3.初始化堆疊區域

4. 初始化堆區域。

5. 初始化塊裝置複製函式。

6. 初始化鎖相環並設定系統時鐘。

7. 將bl1複製到內部sram區域

8. 驗證bl1的校驗和。如果校驗和失敗,irom將嘗試第二次引導。(sd / mmc通道2)

9. 檢查它是否處於安全啟動模式。如果安全金鑰值是用s5pv210編寫的,那麼它就是secure-boot模式。如果是安全啟動模式,請驗證bl1的完整性。

10.跳轉到bl1的起始位址

在真正的說bl1之前不得不說說uboot的關於bl1和bl2的劃分:uboot在設計之初就將自己分為兩個部分,前8kb/16kb為bl1階段,後面的部分為bl2階段,但是通常我們所說的bl2階段的**包含著整個uboot的**,不僅僅只是對bl2階段的**進行了拷貝。 

通過前一階段bl0的引導,bl0階段成功的將uboot的第一階段的**拷貝至sram中進行執行。執行bl1階段的輕量級**時,先初始化一系列必須的硬體,建立好記憶體條件,然後將bl2階段的所有**搬移至ddr之中執行。此時uboot的程式在sd卡/nand中。

主要的工作: 構建異常向量表;   設定cpu為svc模式;關看門狗,開發板的供電索存;   時鐘的初始化,ddr的初始化(lowlevel.inti.s中完成);   初始化串列埠,並列印出一些除錯資訊;  關閉所有的中斷;設定uboot的啟動方式,  初始化記憶體(nandflash/ddr);  設定三次不同用途的棧;  重定位,並且設定了uboot啟動第二部分(也就是整個uboot的映象)在ddr中的起始位址;   最後將uboot映象載入至 ddr中跳轉至dram中執行 。

注:bl1階段的**有著16位元組的校驗頭作為校驗,mkv210_image.c程式用來實現校驗。

關於bl2執行的位置,samsung給出的官方文件是執行在sram中,與bl1共享sram的記憶體空間,但是由於uboot經過多年的發展,**量很是龐雜,bl2階段實際上已經超過了sram中給bl2階段留下的80kb空間的大小,所以實際在移植時是將bl2階段的**重定位sdram/ddr中進行執行,所以在bl1階段也加入了一些新的功能,例如初始ddr。

如前面所說的,bl2階段的**其實包含真個uboot的整包**,在一些情況下如睡眠喚醒或者熱啟動時不必再次執行bl1階段的**,而是直接執行此階段的**。主要完成如下功能:

硬體的初始化:完成bl1階段的未初始化完的大量的其他硬體的初始化,初始化mmc控制器、網絡卡、控制台、中斷/外部中斷,並使用乙個函式指標陣列 init_sequence  遍歷執行其中的一大堆初始化函式;

核心啟動前的準備:而最重要的還屬為核心啟動前準備大量的預備工作:其中包括 從sd卡的kernel分割槽讀取核心映象到ddr中,規uboot的記憶體使用,環境變數的重定位,進行核心的載入,設定核心在記憶體中的位置(核心的鏈結位址處),核心啟動引數的設定,記憶體引數的設定,命令列引數的設定以及引數結束標著的設定,最後通過乙個函式指標the_kernel跳轉至核心程式,真正的啟動核心。

注:在the_kernel呼叫時uboot直接給linux核心傳遞了三個引數,依次在協處理器r1 2 3中,the_kernel真正的含義是這三個引數所在的暫存器,然後設定的三個引數,相當於給暫存器傳入了三個值,第乙個是0,第二個是機器碼,第三個是大片傳參tag的首位址。

s5pv210 u boot 燒寫過程

linux 下 把 tiny210 u boot.bin 寫入到快閃儲存器卡的第二扇區 需要讀卡器 sudo dd iflag dsync oflag dsync if tiny210 uboot.bin of dev sdb1 seek 1 然後把快閃儲存器卡插入到開發板上,把選擇啟動開關撥向快閃...

對於S5PV210載入u boot過程的理解

本文對整體的載入邏輯進行梳理,不作詳細說明,學習過程主要參考 嵌入式linux學習筆記 基於s5pv210 tq210 上電後最先執行的時irom中的 bl0,由三星固化,不能修改,別人能不能改不一定 對於irom載入的 bl1,存放在sd卡或nand中 有格式要求,不然處理器也不知道載入多長的 這...

S5PV210的記憶體對映

s5pv210是基於arm crotex a8架構32位cpu的微處理器。內部擁有32根位址線和32位資料線,32根位址線決定了cpu的位址空間最大為4g,這4g的記憶體空間如何分配,就是記憶體對映 s5pv210 datasheet中section 01 02章節 memory map有講。記憶體...