boot loader 的啟動過程分為單階段(single stage)和多階段(multi-stage)兩種,其中,多階段的 boot loader能提供更為複雜的功能,以及具有更好的可移植性。
boot loader的生命週期如下:
初始化硬體,如設定uart(至少設定乙個),檢測儲存器等
設定啟動引數,告訴核心硬體的資訊,如用哪個啟動介面,波特率.
跳轉到作業系統的首位址.消亡
從固態儲存裝置上啟動的 boot loader 大多都是 2 階段的啟動過程,其啟動過程可以分為stage 1和stage 2兩部分 :
stage 1:主要語言:彙編。實現:簡單的硬體初始化。
stage 2:主要語言:c語言。實現:複製資料、設定啟動引數、串列埠通訊等功能。
boot loader 的主要任務:
如果我們假定核心映像與根檔案系統映像都被載入到 ram 中執行的話:
stage1 通常包括以下步驟:
硬體裝置初始化
為載入 boot loader 的 stage2 準備 ram 空間
拷貝 boot loader 的 stage2 到 ram 空間中
設定好堆疊
跳轉到 stage2 的 c 入口點
stage2 通常包括以下步驟:
初始化本階段要使用到的硬體裝置
檢測系統記憶體對映(memory map)
將 kernel 映像和根檔案系統映像從 flash 上讀到 ram 空間中
為核心設定啟動引數
呼叫核心
1. 基本的硬體初始化
目的是為 stage2 的執行以及隨後的 kernel 的執行準備好一些基本的硬體環境 :
遮蔽所有的中斷
為中斷提供服務通常是 os 裝置驅動程式的責任,boot loader 的執行全過程中可以不必響應任何中斷
中斷遮蔽可以通過寫 cpu 的中斷遮蔽暫存器或狀態暫存器(如 arm 的 cpsr 暫存器)來完成
設定 cpu 的速度和時鐘頻率。
ram 初始化
包括正確地設定系統的記憶體控制器的功能暫存器以及各記憶體庫控制暫存器等。
初始化 led
通過 gpio 來驅動 led,其目的是表明系統的狀態是 ok 還是 error
如板子上沒有led,那麼也可以通過初始化 uart 向串列埠列印 boot loader 的 logo 字元資訊
關閉 cpu 內部指令/資料 cache
2. 為載入 stage2 準備 ram 空間
通常把 stage2 載入到 ram 空間中來執行 。
stage2 通常是 c 語言執行**,考慮堆疊空間。
空間大小最好是 memory page 大小(通常是 4kb)的倍數。
一般1m ram 空間已經足夠,位址範圍可以任意安排。
如 blob 就將 stage2 可執行映像從系統 ram 起始位址 0xc0200000 開始的 1m 空間內執行
將 stage2 安排到 ram 空間的最頂 1mb也是一種值得推薦的方法
stage2_end=stage2_start+stage2_size
對所安排的位址範圍進行測試。
必須確保所安排的位址範圍可讀寫的 ram 空間
測試方法可以採用類似於 blob 的方法
以 memory page 為被測試單位,測試每個 page 開始的兩個字是否是可讀寫的
3. 拷貝 stage2 到 ram 中
拷貝時要確定兩點
(1) stage2 的可執行映象在固態儲存裝置的存放起始位址和終止位址
(2) ram 空間的起始位址。
4. 設定堆疊指標 sp
通常把 sp 的值設定為(stage2_end-4)
1mb 的 ram 空間的最頂端(堆疊向下生長)
在設定堆疊指標 sp 之前,也可以關閉 led 燈,以提示使用者我們準備跳轉到 stage2
5. 跳轉到 stage2 的 c 入口點
可以跳轉到 boot loader 的 stage2 去執行
如在 arm系統中,這可以通過修改 pc 暫存器為合適的位址來實現
1.初始化本階段要使用的硬體裝置
初始化至少乙個串列埠,以便終端使用者進行 i/o 輸出資訊
在初始化這些裝置之前,也可以重新把 led 燈點亮,以表明我們已經進入main() 函式執行
裝置初始化完成後,可以輸出一些列印資訊,程式名字字串、版本號等
初始化計時器等
使用volatile
避免編譯器優化
編譯器為了提高程式執行速度,可能對變數進行優化,會將其放在快取中
缺陷是變數的內容可能被誤改,從而與記憶體中實際值不一致
採用volatile 關鍵字可以避免上述問題
2.檢測系統的記憶體對映(memory map)
在 4gb 實體地址空間中哪些位址範圍被分配用來定址系統的ram 單元
如sa-1100 中,從 0xc0000000 開始的 512m空間被用作系統的 ram 空間
在samsung s3c44b0x 中,從0x0c00,0000 到 0x1000,0000之間的 64m 位址空間被用作系統的 ram 位址空間
嵌入式系統往往只把 cpu 預留的全部 ram 位址空間中的一部分對映到 ram 單元上,而讓剩下的那部分預留 ram 位址空間處於未使用狀態
boot loader 的 stage2 必須檢測整個系統的記憶體對映情況
必須知道 cpu 預留的全部 ram 位址空間中的哪些被真正對映到 ram 位址單元,哪些是處於 「unused」 狀態的
檢測流程
3.載入核心映像和根檔案系統映像
規劃記憶體占用的布局
核心映像所占用的記憶體範圍
根檔案系統所占用的記憶體範圍
從 flash 上拷貝核心映像到ram上
4.設定核心的啟動引數
linux 2.4.x 以後的核心都期望以標記列表(tagged list)的形式來傳遞啟動引數
啟動引數標記列表以標記 atag_core 開始,以標記 atag_none 結束
每個標記由標識被傳遞引數的 tag_header 結構以及隨後的引數值資料結構來組成
在嵌入式 linux 系統中,通常需要由 boot loader 設定的常見啟動引數有:atag_core、atag_mem、atag_cmdline、atag_ramdisk、atag_initrd等
5.呼叫核心
直接跳轉到核心的第一條指令處
在跳轉時,下列條件要滿足
1. cpu 暫存器的設定
r0=0;@r1=機器型別 id;@r2=啟動引數標記列表在 ram 中起始基位址
2. cpu 模式
必須禁止中斷(irqs和fiqs);
cpu 必須 svc 模式;
3. cache 和 mmu 的設定
mmu 必須關閉;
指令 cache 可以開啟也可以關閉;
資料 cache 必須關閉
6.串列埠終端的除錯
除錯手段: 列印資訊到串列埠終端
串列埠終端顯示亂碼或根本沒有顯示
boot loader 對串列埠的初始化設定不正確
執行在 host 端的終端**程式對串列埠的設定不正確,這包括:波特率、奇偶校驗、資料位和停止位等方面的設定
bootloader的執行過程中可以正確向串列埠輸出資訊,但bootloader 啟動核心後無法看到核心啟動輸出資訊
確認是否在編譯核心時配置了對串列埠的支援
確認bootloader對串列埠的設定與核心對串列埠的設定一樣
確認bootloader所用的核心基位址與核心映像在編譯時所用的執行基位址一致
嵌入式Bootloader小述
bootloader的概念 bootloader就是在作業系統核心執行之前執行的一段程式,類似於pc機中的bios程式。bootloader的功能就是完成硬體裝置的初始化 建立記憶體空間的對映圖的功能,將系統的軟硬體環境帶到乙個合適的狀態,為最終呼叫系統核心做好準備。嵌入式中的bootloader一...
嵌入式 BootLoader 技術內幕
在專用的嵌入式板子執行 gnu linux 系統已經變得越來越流行。乙個嵌入 式 linux 系統從軟體的角度看通常可以分為四個層次 引導引導程式。包括固化在韌體 firmware 中的 boot 可選 和 boot loader 兩大部分。linux 核心。特定於嵌入式板子的定製核心以及核心的啟動...
嵌入式 Bootloader的作用
關於bootloader的作用,老師教我們把它當作pc的bios來理解,但其實不完全是這麼回事。文章參考 bootloader是系統加電後執行的第一段 一般它只在系統啟動時非常短的時間內執行。在pc中,整個bootloader由bios 主機板上固化的一段程式 位於硬碟mbr區的os loader一...