嵌入式Linux的引導加載程序——Bootloader

對於嵌入式Linux系統來說,從開機上電到操作系統啟動需要一個引導過程,引導過程體現在引導程序上,而這個引導程序就叫作Bootloader。


嵌入式Linux的引導加載程序——Bootloader


Bootloader的概念與作用

Bootloader 是嵌入式系統的引導加載程序,它是系統上電後運行(操作系統運行之前)的第一段程序 。通過這段程序可以初始化硬件設備、建立內存空間的映射表,從而建立系統的軟硬件環境,為最終調用Linux操作系統內核做好準備。在完成對系統的初始化任務之後,它會將非易失性存儲器(通常是Flash)中的內核拷貝到RAM中去,然後跳轉到內核的第一條指令處繼續執行,從而啟動Linux內核。另外,幾乎不可能為所有的嵌入式系統建立一個通用的Bootloader,不同的處理器架構都有不同的Bootloader,Bootloader不但依賴於CPU的體系結構,而且依賴於嵌入式系統板級設備的配置。


Bootloader的種類

現在已經有各種各樣的Bootloader,種類劃分也有多種方式。下面就來看一下常用的引導加載程序:

ROLO:從ROM引導Linux而不需要BIOS,支持X86架構,不支持ARM和PowerPC;

Etherboot:通過以太網卡啟動Linux系統的固件,支持X86架構,不支持ARM和PowerPC;

U-boot:通用引導加載程序,支持X86架構,並支持ARM和PowerPC;

RedBoot:基於eCos的引導加載程序,支持X86架構,並支持ARM和PowerPC;

值得指出的是Redboot,它幾乎能夠支持所有的體系結構,包括MIPS、SH、M68K等體系結構。Redboot是以eCos為基礎,採用GPL許可的開源軟件工程。


Bootloader的啟動流程

Bootloader的實現依賴於CPU的體系結構,因此大多數的bootloader一般都是分為兩個階段的,第一個階段使用匯編來實現,它完成一些依賴於CPU體系結構的初始化,並調用第二階段的代碼;第二階段則通常使用C語言來實現,這樣可以實現更復雜的功能,而且代碼會有更好的可讀性和移植性。


Bootloader的第一階段

主要包含以下步驟:

1、一些基本的硬件初始化工作 :主要設置CPU的速度和時鐘頻率、屏蔽所有中斷和清除指令與數據緩存

2、準備RAM空間:所謂準備RAM空間,就是初始化內存芯片,使它可被用

3、設置好堆棧:設置堆棧指針是為執行C語言代碼做準備,棧的設置靈活性很大,只要讓sp寄存器指向一段沒有使用的內存即可

4、跳轉到第二階段的C入口點:在ARM中,通過修改PC寄存器為相應的地址來實現


Bootloader的第二階段

主要包含以下步驟:

1、初始化本階段要使用到的硬件設備:最重要的是設置系統時鐘和初始化串口

2、檢查系統內存映射

3、將內核映像和根文件系統從Flash上讀到RAM空間中:

對於內核映像,一般將其拷貝到從0x30008000這個基地址開始的大約1MB大小的內存範圍內(嵌入式 Linux 的內核一般都不操過 1MB),在這一區域前空出來的32KB內存是為了放置一些全局數據結構

4、為內核設置啟動參數

5、調用內核:BootLoader調用Linux內核的方法是直接跳轉到內核的第 一條指令處,在跳轉時,下列條件要滿足: CPU 寄存器的設置: R0=0; R1=機器類型 ID; R2=啟動參數標記列表在 RAM 中 起始基地址; CPU模式: 必須禁止中斷;CPU必須為SVC模式; Cache 和 MMU 的設置: MMU 必須關閉; 指令 Cache 可以打開也可以關閉; 數據 Cache 必須關閉


結語

嵌入式系統的開發過程除了涉及軟件和硬件,同時還需要結合上層應用綜合考慮,而其中成本約束又是最關鍵的因素之一,嵌入式系統的硬件平臺通常是根據應用量身定製,通常所用的MPU、存儲器、外圍設備等有多種選擇餘地,使系統的引導加載設計變得十分複雜,如果我們從零開始實現的話是非常困難且低效率的,正確的做法應該是從相關的例程中尋找與硬件平臺最接近的作為參考程序,然後根據硬件平臺作相應的修改。


嵌入式Linux的引導加載程序——Bootloader


分享到:


相關文章: