1. 程式人生 > >U-Boot啟動流程(Linux核心)的分析(一)

U-Boot啟動流程(Linux核心)的分析(一)

       前面一段時間一直在移植U-Boot,Linux核心和構建根檔案系統,其中有些地方還不是很明白,現在回過頭來,理解一下U-boot的啟動流程,以及u-Boot是如何載入引導核心啟動的。這裡的分析也都是以U-Boot-2009.08版本為基礎的,可能會和以前的版本有所不同。在這裡也不打算一句句分析U-Boot的原始碼,只是想把U-Boot一步一步怎麼最終能夠載入Linux核心的過程,分析一下。        首先,我們應該理解Bootloader是什麼?它有什麼作用?其實它就是系統上電後執行的和小段程式。 1 BootLoader的概念        在系統上電後,需要一段程式來進行初始化:關閉WATCHDOG,改變系統時鐘,初始化儲存控制器,將更多的程式碼複製到記憶體中。並將作業系統核心複製到記憶體中執行,這就段程式程式碼就叫做Bootloader。沒有一個Bootloader完全支援所有CPU,所以我們要想使用Bootloaser一般情況下要自己進行修改,我們可以增強Bootloader的功能,讓它具有網路功能,可以通過NFS遠端下載Linux核心和根檔案系統,可以燒寫Linux核心和根檔案系統到NandFlash中,而這些功能對於最終的使用者來說是沒有什麼意義的,它們看到的只是Bootloader引導Linux核心啟動這一個功能,而其餘的功能只對開發人員很有用處。也就是說在開發期間這些功能是必不可少的。
     (1)啟動載入模式:這種模式也稱為“自主”模式。也就是Bootloader從目標機上的某個固態儲存裝置上將作業系統載入到RAM中執行,整個過程並沒有使用者的介入,這種模式是在嵌入式產品釋出裡的通用模式。
    (2)下載模式:在這種模式下,目標機上的Bootloader將通過串列埠連線或網路連線等通訊手段從主機下載檔案,例如:下載核心映像和根檔案系統映像等。從主機下載的檔案 通常首先被Bootloader儲存到目標機的RAM中,然後再被Bootloader寫到目標上的Flash類的固態儲存裝置中,Bootloader的這種模式是在在開發時使用的工作於這種模式的Bootloader通常都 會向它的終端使用者提供一個簡單的命令列介面。
     在嵌入式Linux系統中從軟體的角度通常可以分為4個層次:
   (1)引導載入程式,包括固化在韌體中的boot程式碼(可選)和Bootloader兩大部分。
         有些CPU在執行Bootloader之前執行一段固化的程式 ,比如x86結構的CPU就是先執行BIOS中的韌體,然後才執行硬碟的第一個分割槽中的BootLoader。在大多數的嵌入式系統中並沒有韌體,Bootloader是上電後第一個執行的程式。
(2)Linux核心
       嵌入式定製的核心以及啟動引數,啟動引數可以是Bootloader傳遞給核心的,也可以是核心預設的。
(3)檔案系統
       包括根檔案系統和建立於Flash記憶體裝置之上的檔案系統。裡面包括了Linux系統能夠執行所必要的應用程式和庫檔案等。比如可以給使用者提供操作Linux的控制shell程式。
(4)使用者應用程式
      特定於使用者的應用程式,它們也儲存在檔案系統中,有時在使用者應用程式和核心層之間可以還會包括一個嵌入式圖形使用者介面。
2. Bootloader啟動的兩個階段
      從固態儲存裝置上啟動的Bootloader大多都是兩階段的啟動過程,第一階段使用匯編來實現。它完成一些依賴於CPU體系結構的初始化,並呼叫第二階段的程式碼,第二階段則通常使用C語言來實現,這樣可以實現更復雜的功能,而且程式碼會有更好的可讀性和可移植性。
(1) Bootloader第一階段的功能
          1)硬體裝置初始化
          2)為載入Bootloader的第二階段準備RAM空間。
          3)複製Bootloader的第二階段程式碼到RAM空間中。
          4)設定好棧
          5)跳轉到第二階段程式碼的C入口點。
     在第一階段進行的硬體初始化一般包括:關閉WATCHDOG,關中斷,設定 CPU的速度和時鐘頻率RAM初始化等。這些不都是必需的。
(2)Bootloader第二階段的功能
          1)初始化本階段要使用的硬體裝置
          2)檢測系統記憶體對映
          3)將核心映像和根檔案系映象從Flash望到RAM空間中
          4)為核心設定啟動引數
          5)呼叫核心
         將核心存放在適當的位置後,直接跳到它的入口點即可呼叫核心,呼叫核心之前,下列條件要滿足
(1)CPU暫存器的設定
         R0=0.
         R1=機器型別ID;對於ARM結構的CPU,其機器型別ID在linux/arch/arm/tools/mach-types
         R2=啟動引數標記列表在RAM中起始基地址
(2)CPU工作模式
         必須禁止中斷(IRQs和FIQs)
         CPU必須為SVC模式
(3)Cach和MMU的設定
         MMU必須關閉
         指令Cach可以開啟也可以關閉
         資料Cach必須關閉