背景介紹
Bootloader是嵌入式系統在加電後執行的第一段代碼,在它完成CPU和相關硬體的初始化之後,再將作業系統映像或固化的嵌入式應用程式裝在到記憶體中然後跳轉到作業系統所在的空間,啟動作業系統運行。
對於嵌入式系統,Bootloader是基於特定硬體平台來實現的。因此,幾乎不可能為所有的嵌入式系統建立一個通用的Bootloader,不同的處理器架構都有不同的Bootloader。Bootloader不但依賴於CPU的體系結構,而且依賴於嵌入式系統板級設備的配置。對於2塊不同的嵌入式板而言,即使它們使用同一種處理器,要想讓運行在一塊板子上的Bootloader程式也能運行在另一塊板子上,一般也都需要修改Bootloader的源程式。
反過來,大部分Bootloader仍然具有很多共性,某些Bootloader也能夠支持多種體系結構的嵌入式系統。例如,U-Boot就同時支持PowerPC、ARM、MIPS和X86等體系結構,支持的板子有上百種。通常,它們都能夠自動從存儲介質上啟動,都能夠引導作業系統啟動,並且大部分都可以支持串口和乙太網接口。
在專用的嵌入式板子運行GNU/Linux系統已經變得越來越流行。一個嵌入式Linux系統從軟體的角度看通常可以分為四個層次:
1、 引導載入程式。包括固化在固件(firmware)中的boot代碼(可選),和BootLoader兩大部分。
2、Linux核心。特定於嵌入式板子的定製核心以及核心的啟動參數。
3、 檔案系統。包括根檔案系統和建立於Flash記憶體設備之上檔案系統。通常用ramdisk來作為rootfs。
4、 用戶應用程式。特定於用戶的應用程式。有時在用戶應用程式和核心層之間可能還會包括一個嵌入式圖形用戶界面。常用的嵌入式GUI有:MicroWindows和MiniGUI等。
通常,BootLoader是嚴重地依賴於硬體而實現的,特別是在嵌入式世界。因此,在嵌入式世界裡建立一個通用的BootLoader幾乎是不可能的。儘管如此,我們仍然可以對bootloader歸納出一些通用的概念來,以指導用戶特定的BootLoader設計與實現。
操作模式
1.自啟動模式:在這種模式下,bootloader從目標機上的某個固態存儲設備上將作業系統載入到RAM中運行,整個過程並沒有用戶的介入。
2.互動模式:在這種模式下,目標機上的bootloader將通過串口或網路等通行手段從開發主機(Host)上下載核心映像等到RAM中。可以被bootloader寫到目標機上的固態存儲媒質中,或者直接進入系統的引導。也可以通過串口接收用戶的命令。
啟動過程
Bootloader啟動大多數都分為兩個階段。第一階段主要包含依賴於CPU的體系結構硬體初始化的代碼,通常都用彙編語言來實現。這個階段的任務有:
基本的硬體設備初始化(禁止所有的中斷、關閉處理器內部指令/數據Cache等)。
為第二階段準備RAM空間。
如果是從某個固態存儲媒質中,則複製Bootloader的第二階段代碼到RAM。
設定堆疊。
在第一階段中為什麼要關閉Cache?通常使用Cache以及寫緩衝是為了提高系統性能,但由於Cache的使用可能改變訪問主存的數量、類型和時間,因此Bootloader通常是不需要的。
跳轉到第二階段的C程式入口點。
第二階段通常用C語言完成,以便實現更複雜的功能,也使程式有更好的可讀性和可移植性。這個階段的任務有:
初始化本階段要使用到的硬體設備。
檢測系統記憶體映射。
將核心映像和根檔案系統映像從Flash讀到RAM。
為核心設定啟動參數。
調用核心。
常見的Bootloader
Redboot
Redboot是Redhat公司隨eCos發布的一個BOOT方案,是一個開源項目。
當前Redboot的最新版本是Redboot-2.0.1,Redhat公司將會繼續支持該項目。
Redboot支持的處理器構架有ARM,MIPS,MN10300,PowerPC, Renesas SHx,v850,x86等,是一個完善的嵌入式系統Boot Loader。
Redboot是在ECOS的基礎上剝離出來的,繼承了ECOS的簡潔、輕巧、可靈活配置、穩定可靠等品質優點。它可以使用X-modem或Y-modem協定經由串口下載,也可以經由乙太網口通過BOOTP/DHCP服務獲得IP參數,使用TFTP方式下載程式映像檔案,常用於調試支持和系統初始化(Flash下載更新和網路啟動)。Redboot可以通過串口和乙太網口與GDB進行通信,調試應用程式,甚至能中斷被GDB運行的應用程式。Redboot為管理FLASH映像,映像下載,Redboot配置以及其他如串口、乙太網口提供了一個互動式命令行接口,自動啟動後,REDBOOT用來從TFTP伺服器或者從Flash下載映像檔案載入系統的引導腳本檔案保存在Flash上。當前支持單板機的移植版特性有:
- 支持ECOS,Linux作業系統引導
- 線上讀寫Flash
- 支持串列口kermit,S-record下載代碼
- 監控(minitor)命令集:讀寫I/O,記憶體,暫存器、 記憶體、外設測試功能等
Redboot是標準的嵌入式調試和引導解決方案,支持幾乎所有的處理器構架以及大量的外圍硬體接口,並且還在不斷地完善過程中。
ARMboot
ARMboot是一個ARM平台的開源固件項目,它特別基於PPCBoot,一個為PowerPC平台上的系統提供類似功能的姊妹項目。鑒於對PPCBoot的嚴重依賴性,已經與PPCBoot項目合併,新的項目為U-Boot。
ARMboot發布的最後版本為ARMboot-1.1.0,2002年ARMboot終止了維護。
ARMboot支持的處理器構架有StrongARM ,ARM720T ,PXA250 等,是為基於ARM或者StrongARM CPU的嵌入式系統所設計的。
ARMboot的目標是成為通用的、容易使用和移植的引導程式,非常輕便地運用於新的平台上。ARMboot是GPL下的ARM固件項目中唯一支持Flash快閃記憶體,BOOTP、DHCP、TFTP網路下載,PCMCLA尋線機等多種類型來引導系統的。特性為:
-支持多種類型的FLASH;
-允許映像檔案經由BOOTP、DHCP、TFTP從網路傳輸;
-支持串列口下載S-record或者binary檔案;
-允許記憶體的顯示及修改;
-支持jffs2檔案系統等。
Armboot對S3C44B0板的移植相對簡單,在經過刪減完整代碼中的一部分後,僅僅需要完成初始化、串口收發數據、啟動計數器和FLASH操作等步驟,就可以下載引導uClinux核心完成板上系統的載入。總得來說,ARMboot介於大、小型Boot Loader之間,相對輕便,基本功能完備,缺點是缺乏後續支持。
U-Boot
U-Boot是由開源項目PPCBoot發展起來的,ARMboot併入了PPCBoot,和其他一些arch的Loader合稱U-Boot。2002年12月17日第一個版本U-Boot-0.2.0發布,同時PPCBoot和ARMboot停止維護。
U-Boot自發布以後已更新6次,最新版本為U-Boot-1.1.1,U-Boot的支持是持續性的。
U-Boot支持的處理器構架包括PowerPC (MPC5xx,MPC8xx,MPC82xx,MPC7xx,MPC74xx,4xx), ARM (ARM7,ARM9,StrongARM,Xscale),MIPS (4Kc,5Kc),x86等等, U-Boot(Universal Bootloader)從名字就可以看出,它是在GPL下資原始碼最完整的一個通用Boot Loader。
U-Boot提供兩種操作模式:啟動載入(Boot loading)模式和下載(Downloading)模式,並具有大型Boot Loader的全部功能。主要特性為:
-SCC/FEC乙太網支持
-BOOTP/TFTP引導
-IP,MAC預置功能
-線上讀寫FLASH,DOC, IDE,IIC,EEROM,RTC
-支持串列口kermit,S-record下載代碼
-識別二進制、ELF32、pImage格式的Image,對Linux引導有特別的支持
-監控(minitor)命令集:讀寫I/O,記憶體,暫存器、記憶體、外設測試功能等
-腳本語言支持(類似BASH腳本)
-支持WatchDog,LCD logo,狀態指示功能等
U-Boot的功能是如此之強大,涵蓋了絕大部分處理器構架,提供大量外設驅動,支持多個檔案系統,附帶調試、腳本、引導等工具,特別支持Linux,為板級移植做了大量的工作。U-Boot1.1.1版本特別包含了對SA1100和44B0晶片的移植,所以44B0移植主要是針對Board 的移植,包括FLASH、記憶體配置以及串口波特率等等。U-Boot的完整功能性和後續不斷的支持,使系統的升級維護變得十分方便。
Blob
Blob(Boot Loader Object)是由Jan-Derk Bakker and Erik Mouw發布的,是專門為StrongARM 構架下的LART設計的Boot Loader。
Blob的最後版本是blob-2.0.5。
Blob支持SA1100的LART主機板,但用戶也可以自行修改移植。
Blob也提供兩種工作模式,在啟動時處於正常的啟動載入模式,但是它會延時 10 秒等待終端用戶按下任意鍵而將 Blob 切換到下載模式。如果在 10 秒內沒有用戶按鍵,則 Blob 繼續啟動 Linux核心。其基本功能為:
初始化硬體(CPU速度,存儲器,中斷,RS232串口)
-引導Linux核心並提供ramdisk
- 給LART下載一個核心或者ramdisk
-給FLASH片更新核心或者ramdisk
-測定存儲配置並通知核心
-給核心提供一個命令行
Blob功能比較齊全,代碼較少,比較適合做修改移植,用來引導Liunx,目前大部分S3C44B0板都用Blob修改移植後來載入uClinux。
Bios-lt
Bios-lt是專門支持三星(Samsung)公司ARM構架處理器S3C4510B的Loader,可以設定CPU/ROM/SDRAM/EXTIO,管理並燒寫FLASH,裝載引導uClinux核心。這是國內工程師申請GNU通用公共許可發布的。
Bios-lt的最新版本是Bios-lt-0.74,另外還提供了S3C4510B的一些外圍驅動。
Bootldr
Bootldr是康柏(Compaq)公司發布的,類似於compaq iPAQ Pocket PC,支持SA1100晶片。它被推薦用來引導Llinux,支持串口Y-modem協定以及jffs檔案系統。
Bootldr的最後版本為Bootldr-2.19。
vivi
vivi是韓國mizi 公司開發的bootloader, 適用於ARM9處理器。Vivi有兩種工作模式:啟動載入模式和下載模式。啟動載入模式可以在一段時間後(這個時間可更改)自行啟動linux核心,這是vivi的默認模式。在下載模式下,vivi為用戶提供一個命令行接口,通過接口可以使用vivi提供的一些命令,如下:
命令
功能
Load 把二進制檔案載入Flash或RAM
Part 操作MTD分區信息。顯示、增加、刪除、復位、保存MTD分區
Param 設定參數
Boot 啟動系統
Flash 管理Flash,如刪除Flash的數據
vivi代碼分析 vivi的代碼包括arch,init,lib,drivers和include等幾個目錄,共200多條檔案。
Vivi主要包括下面幾個目錄:
arch:此目錄包括了所有vivi支持的目標板的子目錄,例如s3c2410目錄。
drivers:其中包括了引導核心需要的設備的驅動程式(MTD和串口)。
MTD目錄下分map、nand和nor三個目錄。
init:這個目錄只有main.c和version.c兩個檔案。和普通的C程式一樣,vivi將從main函式開始執行。
lib:一些平台公共的接口代碼,比如time.c里的udelay()和mdelay()。
include:頭檔案的公共目錄,其中的s3c2410.h定義了這塊處理器的一些暫存器。Platform/smdk2410.h定義了與開發板相關的資源配置參數,我們往往只需要修改這個檔案就可以配置目標板的參數,如波特率、引導參數、物理記憶體映射等。
DSP的BootLoader
一般 的DSP都採用常見的BootLoader程式工作方式來實現用戶程式的上電自舉:
1.處理器通信口(主連線埠)HPI方式
--通過DSP晶片與PC機或DSP晶片與其它DSP晶片之間的主機通信連線埠實現上電自舉;
2.8位或16位並行EPROM方式
--通過DSP核心的DMA通道實現上電自舉;
3.8位或16位並行I/O方式
--通過DSP晶片的片外並行I/O接口實現上電自舉;
4.8位或16位串列口方式
--通過DSP晶片的串列連線埠實現上電自舉。
在以上四種工作方式中,最常用的是16位並行EPROM方式。即在DSP晶片上電或復位時,通過DMA通道將存儲在核外EPROM中的程式以16位形式存儲到核內的程式空間中。
各種方式的BootLoader程式都有其固定格式的Boot表,用來實現用戶程式的上電自舉。16位並行EPROM方式的Boot表如表所示:
項1:存放BootLoader
程式工作方式控制字,用於DS晶片上電或復位時確認該Boot表是否為16位並行EPROM工作方式的Boot表。該表項內容為10AAH,表示DSP核心認為該Boot表是16位並行EPROM工作方式的BootLoader程式的Boot表;否則DSP核心認為該Boot表不是16位並行EPROM的方式的Boot表;
Boot表
項2:
存放DSP特殊暫存器SWWSR在上電或復位時被賦予的初始化數值;
項3:
存放DSP特殊暫存器BSCR在上電或復位時被賦予的初始化數值;
項4:
存放用戶程式將要被存放在DSP核內程式空間的頁地址;
項5:
存放用戶程式將要被存放到DSP核內程式空間的頁內偏移地址;
項6:
開始依次存放用戶程式第m段代碼的長度N。用戶程式第m段代碼將要被存放到DSP核內程式空間的頁地址,用戶程式第m段代碼將要被存放到DSP核內程式空間的頁內偏移地址,用戶程式第m段代碼的第1個字,第2個字,……,第N個字;Boot表的最後表項存放Boot表結束字0000H,表示Boot表到此結束。因此DSP核心要實現BootLoader程式,在上電復位後首先要申請到片外數據、地址匯流排的控制權,然後再根據Boot表完成用戶程式上電自舉過程。
多核DSP的BootLoader程式的實現
在實現多核DSP上電自舉時,每一個子核都需要申請片外匯流排的控制權。對於單核DSP
而言,只有一個DSP核心,對應一個BootLoader程式,DSP核可以永遠擁有片外匯流排的控制權。但對於多核DSP而言,由於只有一套片外匯流排,所以片外匯流排的控制權不允許也不可能永遠被其中的某一個DSP子核所擁有。因此,多核DSP需要片外匯流排仲裁機制,以避免片外匯流排衝突。DSP核的BootLoader程式總是在DSP核上電或復位時啟動,且一啟動
BootLoader程式,對應的DSP核就要申請核外的匯流排控制權。因此為了避免多核DSP的各個DSP子核啟動BootLoader程式時引起的片外匯流排衝突,可通過控制每個DSP子核的復位過程,使每個DSP子核在不同的時間內啟動自身的BootLoader程式來解決片外匯流排衝突的問題。