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