2011年12月15日 星期四

[Embedded] Bootloader


Bootloader

一般的開機流程,主要可分成三個階段:
1.      各家CPU廠商會指定CPU一開始執行的程式位址,例如:ARM0x00000000 MIPS0xBFC00000,而ARM Cortex M3則根據0x00000004所設定的重置向量來決定位址,一旦CPU上電,CPU就會到對應的位址讀取需要執行的程式,此程式即bootloader
2.      由開發板的廠商提供各種初始化周邊的程式,進行初始化流程。
3.      載入作業系統。


Bootloader定義:
所謂的Bootloader就是在載入作業系統之前必須要進行的行為
(CPU執行的第一個程式)。以嵌入式系統而言就是CPU會執行的第一個程式,通常會是一段幾百行的程式碼。
注意的是由於現在open source盛行的關係,例如:Android系統,為了防止系統被 hack, 因此現在的作法會針對 kernel image 加密,並在bootloader載入 image 時,進行檢查,確認是否image已被修改。

Bootloader的主要進行以下幾個動作
l   初始化硬體設置,例如:I/O,記憶體(RAM,ROM),周邊(RS232),設定CPU速度,記憶體mapping¸,stack pointer 等等。
l   基本的監控與除錯功能。
l   載入kernel image及檔案系統。
由上可知,針對不同的硬件就需要不同的bootloader,因此要在嵌入式系統中建立一個共通的bootloader幾乎是不可能的。

Bootloader流程:
1.  PC Boot
上電或復位後,系統會載入 BIOS,並透過BIOS程式讀取CMOS,取得主機上各項硬體設定值,載入硬體資訊並執行硬體的自我測試,並定義可開機的裝置順序。接著系統會主動找到第一個可開機的裝置〔由BIOS設定〕,讀取並執行第一個開機裝置內 MBR(446bytes) bootloader (系統會透過 呼叫 INT13取得bootloader)

在多重作業系統開機的環境下,作法有點不同,安裝作業系統時,作業系統會在 MBR與檔案系統上的boot sector同時安裝 bootloader,當多個作業系統存在時,系統開機後會執行 MBR bootloader,此時會出現多個作業系統的選單,若使用者選擇非預設作業系統,則會由此bootloader找到對應作業系統boot sector 上的bootloader

接著交由bootloader來載入kernel image

2.   Embedded System
嵌入式系統通常沒有 BIOS,此為最大不同點。系統上電或復位後,CPU會從某個特地位址讀取指令,例如:ARM0x00000000 MIPS0xBFC00000 Intel0x7c00,開發者應該要將CPU會執行的第一個程式置於此處。

Bootloader有兩種運作模式:
1.       Boot loading:正常開機模式。
2.       Downloading:下載模式,可以透過UART或網路將kernel imagefilesystem下載至版子,較好的作法是先將資料傳輸至RAM,再由RAM燒錄至FLASH,此處常用的傳輸協定如下:
l   UARTXmodem/ymodem/zmodem,
l   Network protocolTFTP

Bootloader的啟動過程,又可分成兩種實作方式,分為Single stageMulti stage,目前常見的實作方式是分成兩個stage
Stage1: 使用組合語言,撰寫與CPU有關的代碼,例如:設備初始化等程式。
Stage2: 使用 C語言,實現較複雜的功能。

一些有名的boot loader程式碼
l   grub:支持 X86Linux常用的bootloader¸http://www.gnu.org/software/grub/
l   u-boot: 一個通用的bootloader,支持 X86ARM MIPS,此程式碼中可以看到BIOS的作法。http://www.denx.de/wiki/U-Boot
l   blob:
l   spfdisk

接著我將針對u-boot程式碼 (版本2013.04-rc1.tar.bz2) 進行分析,並說明其設計理念與作法。可參考此篇文章