。LILO有詳細的文檔,例如LILO套件中附帶使用手冊和參考手冊。此外,還可以在LDP的“LILO mini-HOWTO”中找到LILO的使用指南。
GRUB是
GNU計劃的主要bootloader。GRUB最初是由Erich Boleyn為GNU Mach操作系統撰寫的引導程序。後來有Gordon Matzigkeit和Okuji Yoshinori接替Erich的工作,繼續維護和開發GRUB。GRUB的網站http://www.gnu.org/software/grub/上有對套件使用的說明文件,叫作《GRUB manual》。GRUB能夠使用TFTP和BOOTP或者DHCP通過網路啟動,這種功能對於系統開發過程很有用。除了傳統的Linux系統上的引導程序以外,還有其他一些引導程序,也可以支持磁碟引導啟動。例如:LoadLin可以從DOS下啟動Linux;還有ROLO、LinuxBIOS,U-Boot也支持這種功能。
3、Flash啟動方式
大多數嵌入式系統上都使用Flash存儲介質。Flash有很多類型,包括NOR Flash、NAND Flash和其他半導體盤。其中,NOR Flash(也就是線性Flash)使用最為普遍。NOR Flash可以支持隨機訪問,所以代碼是可以直接在Flash上執行的。Bootloader一般是存儲在Flash晶元上的。另外,Linux內核映像和RAMDISK也可以存儲在Flash上。通常需要把Flash分區使用,每個區的大小應該是Flash擦除塊大小的整數倍。
Bootloader一般放在Flash的底端或者頂端,這要根據處理器的複位向量設置。要使Bootloader的入口位於處理器上電執行第一條指令的位置。
接下來分配參數區,這裡可以作為Bootloader的參數保存區域。再下來內核映像區。Bootloader引導Linux內核,就是要從這個地方把內核映像解壓到RAM中去,然後跳轉到內核映像入口執行。然後是文件系統區。如果使用Ramdisk文件系統,則需要Bootloader把它解壓到RAM中。如果使用JFFS2文件系統,將直接掛接為根文件系統。最後還可以分出一些數據區,這要根據實際需要和Flash大小來考慮了。
這些分區是開發者定義的,Bootloader一般直接讀寫對應的偏移地址。到了
Linux內核空間,可以配置成MTD設備來訪問Flash分區。但是,有的Bootloader也支持分區的功能,例如:Redboot可以創建Flash分區表,並且內核MTD驅動可以解析出redboot的分區表。除了NOR Flash,還有
NAND Flash、Compact Flash、DiskOnChip等。這些Flash具有晶元價格低,存儲容量大的特點。但是這些晶元一般通過專用控制器的I/O方式來訪問,不能隨機訪問,因此引導方式跟NOR Flash也不同。在這些晶元上,需要配置專用的引導程序。通常,這種引導程序起始的一段代碼就把整個引導程序複製到RAM中運行,從而實現自舉啟動,這跟從磁碟上啟動有些相似。
大多數BootLoader都包含兩種不同的操作模式。“啟動載入”模式和“下載”模式,這種區別僅對於開發人員才有意義。但從最終用戶的角度看,BootLoader的作用就是用來載入操作系統,而並不存在所謂的啟動載入模式與下載工作模式的區別。
啟動載入(Boot loading)模式:這種模式也稱為“自主”(Autonomous)模式,也即BootLoader從目標機上的某個固態存儲設備上將操作系統載入到RAM中運行,整個過程並沒有用戶的介入。這種模式是BootLoader的正常工作模式。因此在嵌入式產品發布的時候,BootLoader顯然必須工作在這種模式下。
下載(Down loading)模式:在這種模式下 目標機上的BootLoader將通過串口連接或網路連接等通信手段從主機下載文件,比如:下載應用程序、數據文件、內核映像等.從主機下載的文件通常首先被BootLoader保存到目標機的RAM中然後再被BootLoader寫到目標機上的固態存儲設備中。BootLoader的這種模式通常在系統更新時使用。工作於這種模式下的BootLoader通常都會向它的終端用戶提供一個簡單的命令行介面。
在教學系統中提供的BootLoader中沒有實現自主模式,可以通過修改代碼來實現該功能。 BootLoader與主機之間進行文件傳輸所用的通信設備及協議。
最常見的情況就是,目標機上的BootLoader通過串口與主機之間進行文件傳輸,傳輸可以簡單的採用直接數據收發,當然在串口上也可以採用xmode/ymode/zmode協議以及在乙太網上採用TPTP協議。
此外,在論及這個話題時,主機方所用的軟體也要考慮。比如,在通過乙太網連接和TFTP協議來下載文件時,主機方必須有一個軟體用來提供TFTP服務。
引導載入程序是系統加電后運行的第一段代碼。我們熟悉的PC中的引導程序一般由BIOS和位於MBR的OS bootloader(例如LILO或者GRUB)一起組成。然而在嵌入式系統中通常沒有像BIOS那樣的固件程序(有的嵌入式CPU有),因此整個系統的載入啟動任務就完全由bootloader來完成。在
嵌入式Linux中,引導載入程序即等效為bootloader。
Boot loader 就是在操作系統內核運行之前運行的一段小程序。通過這段小程序,可以初始化硬體設備、建立內存空間的映射圖,從而將系統的軟硬體環境帶到一個合適的狀態,以便為最終調用操作系統內核準備好正確的環境。
系統加電或複位后,所有的CPU 通常都從某個預先安排的地址上取指令。例如,基於ARM7TDMI core 的CPU 在複位時通常都從地址0x00000000取它的第一條指令。而基於CPU 構建的嵌入式系統通常都有某種類型的固態存儲設備(比如:ROM、EEPROM、或 Flash 等)被映射到這個預先安排的地址上。因此在系統加電后,CPU 將首先執行 Bootloader 程序。通常總是將Boot Loader 安裝在嵌入式系統的存儲設備的最前端。
固態存儲設備的空間劃分(地址從低到高順序):Bootloader,Bootloader參數,內核映像,根文件系統映像。
bootloader是依賴於硬體而實現的,特別是在嵌入式系統中。不同的體系結構需求的bootloader是不同的;除了體系結構,bootloader還依賴於具體的嵌入式板級設備的配置。也就是說,對於兩塊不同的嵌入式板而言,即使它們基於相同的CPU構建,運行在其中一塊電路板上的bootloader,未必能夠運行在另一塊電路開發板上。
Bootloader的啟動過程可以是單階段的,也可以是多階段的。通常多階段的bootloader能提供更為複雜的功能,以及更好的可移植性。從固態存儲設備上啟動的bootloader大多數是二階段的啟動過程,也即啟動過程可以分為stage 1和stage 2兩部分。
第一步:要進行相關硬體的初使化,比如在at91rm9200這塊嵌入式板子上(以後都使用這一款晶元,主要是我對這款晶元比較熟悉,嘿嘿),大概要做接下來的幾方面的工作,其一:將CPU
CPU
CPU也稱為中央處理器,是電子計算機的主要設備之一。其功能主要是解釋計算機指令以及處理計算機軟體中的數據。所謂的計算機的可編程性主要是指對CPU的編程。CPU是計算機中的核心配件,只有火柴盒那麼大,幾十張紙那麼厚,但它卻是一台計算機的運算核心和控制核心。計算機中所有操作都由CPU負責讀取指令,對指令解碼並執行指令的核心部件。CPU、內部存儲器和輸入/輸出設備是電子計算機的三大核心部件。
模式切換進系統模式,關閉系統中斷,關閉看門狗,根據具體情況進行內存內存內存的正式叫法是內存儲器,以此來與外存儲器區分開。物理上它安裝在計算機內部,通常安裝在主板上,所以稱為內存。它的作用是供暫時存儲處理器需要處理的數據或處理后的結果,可見內存是計算機處理器的工作空間。它是處理器運行的程序和數據必須駐留於其中的一個臨時存儲區域,是計算機十分重要的部件。區域映射,初始化內存控制區,包括所使用的內存條的相關參數,刷新頻率等,其二:設定系統運行頻率,包括使用外部
晶振晶振晶振:即所謂石英晶體諧振器和石英晶體時鐘振蕩器的統稱。不過由於在消費類電子產品中,
諧振器用的更多,所以一般的概念中把晶振就等同於諧振器理解了。
後者就是通常所指鍾振,設置CPU頻率,設置
匯流排匯流排匯流排是將信息以一個或多個源部件傳送到一個或多個目的部件的一組傳輸線。通俗的說,就是多個部件間的公共連線,用於在各個部件之間傳輸信息。人們常常以MHz表示的速度來描述匯流排頻率。頻率,設置外部設備所採用的頻率等。其三:設置系統中斷相關,包括定時器,定時器是裝有時段或時刻控制機構的開關裝置。它有一個頻率穩定的振蕩源,通過齒輪傳動或集成電路分頻計數,當將時間累加到預置數值時,或指示到預置的時刻處,定時器即發送信號控制執行機構。
中斷,是否使用FIQ中斷,外部中斷等,還有就是中斷優先順序設置,這裡只實現兩個優先順序,只有時鐘中斷高一級,其它都一樣,而
中斷向量初始化時都將這些中斷向量指向0x18處,並關閉這裡的所有中斷,如果板子還接有諸如FLASH設備的話,還需要設置諸如FLASH相關操制寄存器,其四:需要關閉
CACHE,到此為止,晶元相關內容就完成初始化了。
第二步:中斷向量表,ARM的中斷與PC機晶元的中斷向量表有一點差異,嵌入式設備為了簡單,當發生中斷時,由CPU直接跳入由0x0開始的一部分區域(ARM晶元自身決定了它中斷時就會跳入0x0開始的一片區域內,具體跳到哪個地址是由中斷的模式決定的,一般用到的就是複位中斷,FIQ,IRQ中斷,SWI中斷,指令異常中斷,數據異常中斷,預取指令異常中斷),而當CPU進入相應的由0x0開始的向量表中時,這就需要用戶自己編程接管中斷處理程序了,這就是需要用戶自己編寫
中斷向量表,中斷向量表裡存放的就是一些跳轉指令,比如當CPU發生一個IRQ中斷時,就會自動跳入到0x18處,這裡就是用戶自己編寫的一個跳轉指令,假如用戶在此編寫了一條跳轉到0x20010000處的指令,那麼這個地址就是一個總的IRQ中斷處理入口,一個CPU可能有多個IRQ中斷,在這個總的入口處如何區分不同的中斷呢?就由用戶編程來決定了,具體實現請參見以後相關部分,中斷向量表的一般用一個vector.S文件,當然,如何命名那是你自己的喜愛,但有一點需要聲明,那就是在鏈接時一定要將它定位在0x0處。
第三步:設置
堆棧,一般使用三個棧,一個是IRQ棧,一個是系統模式下的棧(系統模式下和用戶模式共享寄存器和內存空間,這主要是為了簡單),設置棧的目的主要是為了進行函數調用和局部變數的存放,不可能全用彙編,也不可能不用局部變數
第四步:將自己以後的代碼段和數據段全部拷貝至內存,並將BSS段清零
第五步:進行串口,串口是計算機上一種非常通用的設備通信協議,大多數計算機包含兩個基於RS232的串口。串口同時也是儀器儀錶設備的通信協議,並可用於獲取遠程採集設備的數據的初始化(主要是為了與用戶交互,進行與PC機的文件傳輸),FLASH的初始化這裡在FLASH中存放BOOT和內核),FLASH驅動的編寫(這裡的驅動有別於平常所說的驅動,由於FLASH不像SDRAM,只要設定了相關控制器之後就可以直接讀寫指定地址的數據,對FLASH的寫操作是一塊一塊數據進行,而不是一個位元組一個位元組地寫,具體請查閱相關資料)
第六步:等待一定的秒數,來接收用戶進行輸入,如果在指定的秒數內用戶未輸入任何字元,那麼BOOT就開始在FLASH中的指定位置(可以由自己指定,這麼做主要是為了簡單)讀取內核的所有數據到內存中(具體是內存中的什麼位置由自己指定,也可以採用Linux之類的做法,就是在內存的起始位置加上一個0x8000處),將跳轉到內核的第一條代碼處);如果用戶在指定的秒數內鍵入了字元(這主要是為了方便開發,如果開發定型之後完全可以不要這段代碼),那麼就在串口與用戶進行交互,接受用戶在串口輸入的命令,比如用戶要求下載文件在FLASH中指定的位置等,具體內容可參考U-BOOT之類的開源項目到這裡為止,BOOT部分已完成,這個BOOT非常簡單,僅僅只是將PC機上傳下來的文件固化到FLASH中,然後再將FLASH中的操作系統內核部分載入進內存中,並將CPU的控制權交給操作系統。
Bootloader廣泛用於有操作系統的手持終端設備、智能家電及機頂盒等嵌入式設備上,它負責完成硬體初始化、操作系統引導和系統配製等,相當於PC機上的BIOS對於一個嵌入式的Linux系統而言,Bootloader是整個系統運行的基礎。但是對於不同的ARM平台而言所使用的Bootloader都會有所不同。完成 Bootloader的移植是在特定的硬體平台上實現系統構建和運行的至關重要的一個步驟。