歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
您现在的位置: Linux教程網 >> UnixLinux >  >> Linux綜合 >> Linux資訊 >> 更多Linux

嵌入式系統BootLoader技術內幕

  1. 引言  在專用的嵌入式板子運行 GNU/Linux 系統已經變得越來越流行。一個嵌入式 Linux 系統從軟件的角度看通常可以分為四個層次:     1. 引導加載程序。包括固化在固件(firmware)中的 boot 代碼(可選),和 Boot Loader 兩大部分。     2. Linux 內核。特定於嵌入式板子的定制內核以及內核的啟動參數。     3. 文件系統。包括根文件系統和建立於 Flash 內存設備之上文件系統。通常用 ram disk 來作為 root fs。     4. 用戶應用程序。特定於用戶的應用程序。有時在用戶應用程序和內核層之間可能還會包括一個嵌入式圖形用戶界面。常用的嵌入式 GUI 有:MicroWindows 和 MiniGUI 懂。     引導加載程序是系統加電後運行的第一段軟件代碼。回憶一下 PC 的體系結構我們可以知道,PC 機中的引導加載程序由 BIOS(其本質就是一段固件程序)和位於硬盤 MBR 中的 OS Boot Loader(比如,LILO 和 GRUB 等)一起組成。BIOS 在完成硬件檢測和資源分配後,將硬盤 MBR 中的 Boot Loader 讀到系統的 RAM 中,然後將控制權交給 OS Boot Loader。Boot Loader 的主要運行任務就是將內核映象從硬盤上讀到 RAM 中,然後跳轉到內核的入口點去運行,也即開始啟動操作系統。     而在嵌入式系統中,通常並沒有像 BIOS 那樣的固件程序(注,有的嵌入式 CPU 也會內嵌一段短小的啟動程序),因此整個系統的加載啟動任務就完全由 Boot Loader 來完成。比如在一個基於 ARM7TDMI core 的嵌入式系統中,系統在上電或復位時通常都從地址 0x00000000 處開始執行,而在這個地址處安排的通常就是系統的 Boot Loader 程序。     本文將從 Boot Loader 的概念、Boot Loader 的主要任務、Boot Loader 的框架結構以及 Boot Loader 的安裝等四個方面來討論嵌入式系統的 Boot Loader。     2. Boot Loader 的概念  簡單地說,Boot Loader 就是在操作系統內核運行之前運行的一段小程序。通過這段小程序,我們可以初始化硬件設備、建立內存空間的映射圖,從而將系統的軟硬件環境帶到一個合適的狀態,以便為最終調用操作系統內核准備好正確的環境。     通常,Boot Loader 是嚴重地依賴於硬件而實現的,特別是在嵌入式世界。因此,在嵌入式世界裡建立一個通用的 Boot Loader 幾乎是不可能的。盡管如此,我們仍然可以對 Boot Loader 歸納出一些通用的概念來,以指導用戶特定的 Boot Loader 設計與實現。     1. Boot Loader 所支持的 CPU 和嵌入式板     每種不同的 CPU 體系結構都有不同的 Boot Loader。有些 Boot Loader 也支持多種體系結構的 CPU,比如 U-Boot 就同時支持 ARM 體系結構和MIPS 體系結構。除了依賴於 CPU 的體系結構外,Boot Loader 實際上也依賴於具體的嵌入式板級設備的配置。這也就是說,對於兩塊不同的嵌入式板而言,即使它們是基於同一種 CPU 而構建的,要想讓運行在一塊板子上的 Boot Loader 程序也能運行在另一塊板子上,通常也都需要修改 Boot Loader 的源程序。     2. Boot Loader 的安裝媒介(Installation Medium)     系統加電或復位後,所有的 CPU 通常都從某個由 CPU 制造商預先安排的地址上取指令。比如,基於 ARM7TDMI core 的 CPU 在復位時通常都從地址 0x00000000 取它的第一條指令。而基於 CPU 構建的嵌入式系統通常都有某種類型的固態存儲設備(比如:ROM、EEPROM 或 FLASH 等)被映射到這個預先安排的地址上。因此在系統加電後,CPU 將首先執行 Boot Loader 程序。     下圖1就是一個同時裝有 Boot Loader、內核的啟動參數、內核映像和根文件系統映像的固態存儲設備的典型空間分配結構圖。     圖1 固態存儲設備的典型空間分配結構     3. 用來控制 Boot Loader 的設備或機制    主機和目標機之間一般通過串口建立連接,Boot Loader 軟件在執行時通常會通過串口來進行 I/O,比如:輸出打印信息到串口,從串口讀取用戶控制字符等。     4. Boot Loader 的啟動過程是單階段(Single Stage)還是多階段(Multi-Stage)     通常多階段的 Boot Loader 能提供更為復雜的功能,以及更好的可移植性。從固態存儲設備上啟動的 Boot Loader 大多都是 2 階段的啟動過程,也即啟動過程可以分為 stage 1 和 stage 2 兩部分。而至於在 stage 1 和 stage 2 具體完成哪些任務將在下面討論。     5. Boot Loader 的操作模式 (Operation Mode)    大多數 Boot Loader 都包含兩種不同的操作模式:"啟動加載"模式和"下載"模式,這種區別僅對於開發人員才有意義。


但從最終用戶的角度看,Boot Loader 的作用就是用來加載操作系統,而並不存在所謂的啟動加載模式與下載工作模式的區別。     啟動加載(Boot loading)模式:這種模式也稱為"自主"(Autonomous)模式。也即 Boot Loader 從目標機上的某個固態存儲設備上將操作系統加載到 RAM 中運行,整個過程並沒有用戶的介入。這種模式是 Boot Loader 的正常工作模式,因此在嵌入式產品發布的時侯,Boot Loader 顯然必須工作在這種模式下。     下載(Downloading)模式:在這種模式下,目標機上的 Boot Loader 將通過串口連接或網絡連接等通信手段從主機(Host)下載文件,比如:下載內核映像和根文件系統映像等。從主機下載的文件通常首先被 Boot Loader 保存到目標機的 RAM 中,然後再被 Boot Loader 寫到目標機上的FLASH 類固態存儲設備中。Boot Loader 的這種模式通常在第一次安裝內核與根文件系統時被使用;此外,以後的系統更新也會使用 Boot Loader 的這種工作模式。工作於這種模式下的 Boot Loader 通常都會向它的終端用戶提供一個簡單的命令行接口。     像 Blob 或 U-Boot 等這樣功能強大的 Boot Loader 通常同時支持這兩種工作模式,而且允許用戶在這兩種工作模式之間進行切換。比如,Blob 在啟動時處於正常的啟動加載模式,但是它會延時 10 秒等待終端用戶按下任意鍵而將 blob 切換到下載模式。如果在 10 秒內沒有用戶按鍵,則 blob 繼續啟動 Linux 內核。     6. BootLoader 與主機之間進行文件傳輸所用的通信設備及協議     最常見的情況就是,目標機上的 Boot Loader 通過串口與主機之間進行文件傳輸,傳輸協議通常是 xmodem/ymodem/zmodem 協議中的一種。但是,串口傳輸的速度是有限的,因此通過以太網連接並借助 TFTP 協議來下載文件是個更好的選擇。     此外,在論及這個話題時,主機方所用的軟件也要考慮。比如,在通過以太網連接和 TFTP 協議來下載文件時,主機方必須有一個軟件用來的提供 TFTP 服務。     在討論了 BootLoader 的上述概念後,下面我們來具體看看 BootLoader 的應該完成哪些任務。     3. Boot Loader 的主要任務與典型結構框架  在繼續本節的討論之前,首先我們做一個假定,那就是:假定內核映像與根文件系統映像都被加載到 RAM 中運行。之所以提出這樣一個假設前提是因為,在嵌入式系統中內核映像與根文件系統映像也可以直接在 ROM 或 Flash 這樣的固態存儲設備中直接運行。但這種做法無疑是以運行速度的犧牲為代價的。     從操作系統的角度看,Boot Loader 的總目標就是正確地調用內核來執行。     另外,由於 Boot Loader 的實現依賴於 CPU 的體系結構,因此大多數 Boot Loader 都分為 stage1 和 stage2 兩大部分。依賴於 CPU 體系結構的代碼,比如設備初始化代碼等,通常都放在 stage1 中,而且通常都用匯編語言來實現,以達到短小精悍的目的。而 stage2 則通常用C語言來實現,這樣可以實現給復雜的功能,而且代碼會具有更好的可讀性和可移植性。     Boot Loader 的 stage1 通常包括以下步驟(以執行的先後順序):     硬件設備初始化。    為加載 Boot Loader 的 stage2 准備 RAM 空間。     拷貝 Boot Loader 的 stage2 到 RAM 空間中。     設置好堆棧。     跳轉到 stage2 的 C 入口點。     Boot Loader 的 stage2 通常包括以下步驟(以執行的先後順序):     初始化本階段要使用到的硬件設備。    檢測系統內存映射(memory map)。     將 kernel 映像和根文件系統映像從 flash 上讀到 RAM 空間中。     為內核設置啟動參數。     調用內核。   3.1 Boot Loader 的 stage1    3.1.1 基本的硬件初始化    這是 Boot Loader 一開始就執行的操作,其目的是為 stage2 的執行以及隨後的 kernel 的執行准備好一些基本的硬件環境。它通常包括以下步驟(以執行的先後順序):     1. 屏蔽所有的中斷。為中斷提供服務通常是 OS 設備驅動程序的責任,因此在 Boot Loader 的執行全過程中可以不必響應任何中斷。中斷屏蔽可以通過寫 CPU 的中斷屏蔽寄存器或狀態寄存器(比如 ARM 的 CPSR 寄存器)來完成。     2. 設置 CPU 的速度和時鐘頻率。     3. RAM 初始化。包括正確地設置系統的內存控制器的功能寄存器以及各內存庫控制寄存器等。     4. 初始化 LED。典型地,通過 GPIO 來驅動 LED,其目的是表明系統的狀態是 OK 還是 Error。如果板子上沒有 LED,那麼也可以通過初始化 UART 向串口打印 Boot Loader 的 Logo 字符信息來完成這一點。     5. 關閉 CPU 內部指令/數據 cache。    3.1.2 為加載 stage2 准備 RAM 空間    為了獲得更快的執行速度,通常把 stage2 加載到 RAM 空間中來執行,因此必須為加載



    為內核設置啟動參數。     調用內核。   3.1 Boot Loader 的 stage1    3.1.1 基本的硬件初始化    這是 Boot Loader 一開始就執行的操作,其目的是為 stage2 的執行以及隨後的 kernel 的執行准備好一些基本的硬件環境。它通常包括以下步驟(以執行的先後順序):     1. 屏蔽所有的中斷。為中斷提供服務通常是 OS 設備驅動程序的責任,因此在 Boot Loader 的執行全過程中可以不必響應任何中斷。中斷屏蔽可以通過寫 CPU 的中斷屏蔽寄存器或狀態寄存器(比如 ARM 的 CPSR 寄存器)來完成。     2. 設置 CPU 的速度和時鐘頻率。     3. RAM 初始化。包括正確地設置系統的內存控制器的功能寄存器以及各內存庫控制寄存器等。     4. 初始化 LED。典型地,通過 GPIO 來驅動 LED,其目的是表明系統的狀態是 OK 還是 Error。如果板子上沒有 LED,那麼也可以通過初始化 UART 向串口打印 Boot Loader 的 Logo 字符信息來完成這一點。     5. 關閉 CPU 內部指令/數據 cache。    3.1.2 為加載 stage2 准備 RAM 空間    為了獲得更快的執行速度,通常把 stage2 加載到 RAM 空間中來執行,因此必須為加載



Copyright © Linux教程網 All Rights Reserved