天天看點

uboot移植(四)——uboot啟動第一階段

1:BL0 BL1 BL2分别是什麼

(1)BL0:s5pv210的iROM中固化的代碼

   作用:初始化系統時鐘,設定看門狗,初始化棧,加載BL1

(2)BL1:從外部啟動媒體(nand/SD卡)中加載的uboot.bin的前16K代碼

   作用:初始化RAM,關閉Cache,初始化DDR,設定棧,加載BL2

(3)BL2:是指在代碼完成重定位後在DDR中運作的完整的uboot代碼

   作用:初始化其他外設,加載OS核心

三者的關系:開機上電自動運作BL0的代碼,然後加載BL1到SDRAM中,接着通過重定位将BL2加載到DDR中,最終uboot啟動完成,加載核心到DDR中

2:uboot的啟動過程

下圖是三星公司推薦210的啟動過程

uboot移植(四)——uboot啟動第一階段

三星推薦的啟動過程也是開機上電自動加載BL1,然後運作BL2,引導有、核心的啟動,需要注意的三星推薦的啟動過程中BL1和BL2都是放在SDRAM(96K)中的,但是随着uboot的發展uboot的大小已經超過了96K,是以BL2不能再放在SDRAM中,而是通過BL1重定位到DDR中

3:uboot啟動時第一階段做了哪些事情

uboot啟動的入口函數是start.S,是以根據start.S這個檔案中的代碼去分析uboot啟動的第一階段。

(1)通過#include加載相應的頭檔案

(2)通過彙編僞指令.word定義4個4位元組的變量,作用是為後面的計算校驗和填充占位,確定image的頭部有16位元組的頭資訊,如果沒有,則uboot會列印出 SD  checksun Error

(3)建構異常向量表,但是由于uboot的啟動時間很短,異常發生的較少,是以并沒有很細緻地處理各種異常,當異常發生時重新開機即可

(4)通過操作CPSR程式狀态寄存器設定SoC為SVC模式

(5)通過讀取0xE0000004寄存器的值來判斷啟動媒體,0xE0000004寄存器的值會根據OM0-OM5這6 個引腳的電平高低自動設定,通過讀取這個寄存器的值就可以得到uboot從哪裡啟動

(6)設定棧,此時運作的代碼是BL1,是在SDRAM中運作的,還有一點需要注意的是ARM都是滿減棧,也就是入棧時是向下延伸的

(7)調用lowlevel_init函數,這個函數裡面主要是 檢查複位狀态(熱啟動 冷啟動 睡眠喚醒),複位後IO口的儲存和恢複,關看門狗,開發闆供電鎖存,初始化時鐘,初始化DDR,并在傳回start.S之前列印字元'OK',需要注意的是,lowlevel_init函數中有一段代碼用來判斷目前運作位置是在DDR還是SDRAM,其原理是通過比較運作位址和連結位址是否相同,而且它判斷的是運作位址和連結位址的第12位開始的12位是否相同

    ldr    r0, =0xff000fff

    bic    r1, pc, r0        /* r0 <- current base addr of code */

    ldr    r2, _TEXT_BASE        /* r1 <- original base addr in ram */

    bic    r2, r2, r0        /* r0 <- current base addr of code */

    cmp     r1, r2                  /* compare r0, r1 

   beq     1f            /* r0 == r1 then skip sdram init   */

bic    r1, pc, r0 的意思就是把pc中和r0對應的1改為0,0改為1,并存入寄存器r1中,也就是将r0取反在和pc相與  r1 = pc & (~(r0)) 如果相等則說明目前運作在DDR中,那麼就不需要進行時鐘和DDR的初始化,如果不相等則說明目前運作在SDRAM中,就需要進行時鐘和DDR的初始化。

列印出來的字元'OK',是一種調試資訊,如果啟動ubooot看到Ok 則說明是調用lowlevel_init後面的錯誤,如果沒有看到OK則說明是在調用這個函數之前。在進行移植的時候也可以使用類似的方法在函數調用之間通過列印相應的字元來判斷錯誤發的位置。

(8)再次設定開發闆供電鎖存,沒實際意義

(9)在DDR中設定棧,原因是在lowlevel_init函數中已經對DDR進行了初始化,這時候的DDR是可用的

(10)再次判斷目前運作位置是在SDRAM還是DDR,其方法還是一樣,其目的是為了判斷是否需要進行重定位

(11)虛拟位址映射

(12)第三次設定棧,這次設定棧的為了充分合理地使用記憶體(安全,緊湊不浪費記憶體)

(13)清bss段

(14)uboot第一階段的最後一句: ldr  pc, _start_armboot指針指向_start_armboot這個函數,也就是uboot啟動的第二階段的入口函數。

本文轉自 菜鳥養成記 51CTO部落格,原文連結:http://blog.51cto.com/11674570/1834299

繼續閱讀