<dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><small id="yhprb"></small><dfn id="yhprb"></dfn><small id="yhprb"><delect id="yhprb"></delect></small><small id="yhprb"></small><small id="yhprb"></small> <delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"></dfn><dfn id="yhprb"></dfn><s id="yhprb"><noframes id="yhprb"><small id="yhprb"><dfn id="yhprb"></dfn></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><small id="yhprb"></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn> <small id="yhprb"></small><delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn>

新聞中心

EEPW首頁(yè) > 嵌入式系統 > 設計應用 > Linux bootloader 編寫(xiě)方法

Linux bootloader 編寫(xiě)方法

作者: 時(shí)間:2011-02-25 來(lái)源:網(wǎng)絡(luò ) 收藏

對于移植 linux 到其它開(kāi)發(fā)板的人來(lái)說(shuō),編寫(xiě) boot loader 是一個(gè)不可避免的過(guò)程。對于學(xué)習linux的人來(lái)講,編寫(xiě) bootloader 也是一個(gè)很有挑戰性的工作。本文通過(guò)對 linux引導協(xié)議進(jìn)行分析,詳細闡述了如何編寫(xiě)一個(gè)可以在 i386 機器上引導 2.4.20內核的基本的bootloader。


1.概述

linux運行在保護模式下,但是當機器啟動(dòng)復位的時(shí)候卻處于實(shí)模式下。所以寫(xiě)bootloader做的工作也是在實(shí)模式之下的。

linux的內核有多種格式,老式的zImage和新型的bzImage。它們之間最大的差別是對于內核體積大小的限制。由于zImage內核需要放在實(shí)模式1MB的內存之內,所以其體積受到了限制。目前采用的內核格式大多為bzImage,這種格式?jīng)]有1MB內存限制。本文以下部分主要以bzImage為例進(jìn)行分析。

2.bzImage格式內核的結構

bzImage內核從前向后分為3個(gè)部分,前512字節被稱(chēng)為bootsect,這就是軟盤(pán)引導linux時(shí)用到的bootloader,如果不從軟盤(pán)引導,這部分就沒(méi)有用,其中存儲了一些編譯時(shí)生成的內核啟動(dòng)選項的默認值。從512個(gè)字節開(kāi)始的512*n個(gè)字節稱(chēng)為setup部分,這是linux內核的實(shí)模式部分,這部分在實(shí)模式下運行,主要功能是為保護模式的linux內核啟動(dòng)準備環(huán)境。這個(gè)部分最后會(huì )切換進(jìn)入保護模式,跳轉到保護模式的內核執行。最后的部分就是保護模式的內核,也就是真正意義上的linux內核。其中n的大小可以從bootsect后半部得到,詳細地址可以參閱linux boot protocol。

3.引導過(guò)程概述

第一步,打開(kāi)冰箱門(mén);第二步把大象放到冰箱里……不要笑,過(guò)程就是這么簡(jiǎn)單。首先需要把linux內核的setup部分拷貝到9020H:0開(kāi)始的地址,然后把保護模式內核拷貝到1MB開(kāi)始的地址,然后根據Linux Boot Protocol 2.03的內容設定參數區的內容,基地址就是9000H:0,最后使用一條ljmp $0x9020,$0跳轉到setup段,剩下的事情就是linux自己的了^_^,果然簡(jiǎn)單吧!

4.THE LINUX/I386 BOOT PROTOCOL

這個(gè)就是我們引導linux所使用的協(xié)議,它的位置在:Documetation/i386/boot.txt中。里面詳細的寫(xiě)了引導linux所需要知道的一切知識,對于其它體系結構的CPU,也一定存在著(zhù)類(lèi)似的東東,仿照本文的方法就可以了。

5.細節一:基本引導參數

當然我們不指定任何參數linux內核也可以啟動(dòng),但是這樣有可能啟動(dòng)進(jìn)入一個(gè)我們不支持的framebuffer模式,導致沒(méi)有任何屏幕顯示;也可能mount了錯誤的根分區失敗,導致No Init Found的kernel panic。所以我們必須要指定一些東西。

如果你像我一樣是一個(gè)懶人,那么可以直接把bootsect拷到9000H:0的位置,使用軟盤(pán)引導時(shí)它會(huì )把自己復制到這個(gè)地方的,這里面有些默認的設置,詳情請見(jiàn)boot.txt。

首先是root的位置,這里bootsect_pos指向的是9000H:0的地址。


bootsect_pos[0x1fc] = root_minor;
bootsect_pos[0x1fd] = root_major;


其中root_minor和root_major分別是root的主設備號和次設備號。

當前顯示模式:


bootsect_pos[0x1fa] = 0xff;
bootsect_pos[0x1fb] = 0xff;


這兩個(gè)數值相當于引導參數vga=0xHHH的值,兩個(gè)0xff代表文本模式。


bootsect_pos[0x210] = 0xff;


這是在設定你的bootloader的類(lèi)型,其實(shí)只要不是0就行,因為0代表的loader太舊無(wú)法引導新的內核,setup發(fā)現這個(gè)后就會(huì )停下來(lái)。按照規范你應該寫(xiě)成0xff,這表示未知的boot loader,如果你的bootloader已經(jīng)得到了一個(gè)官方分配的type id,那就寫(xiě)上自己的數值。

6.細節二:如何加載內核

如果你現在的環(huán)境是一無(wú)所有,那么必須使用bios中斷或者ATA指令去讀硬盤(pán)了,不過(guò)如果你手中如果有基本的DOS系統,那么就可以使用DOS的程序了。為了能夠操作整個(gè)4GB的地址空間,我使用了WATCOM C寫(xiě)了個(gè)小程序讀內核,不過(guò)你可以仿照bootsect里面的做法,在實(shí)模式中讀一部分,然后進(jìn)入到保護模式拷貝到1MB以上,然后再從實(shí)模式讀一部分……需要注意1:9000H:0也是DOS占用的地址空間,所以讀完內核后就不要返回DOS了,否則會(huì )有問(wèn)題;

注意2:一定保證是純DOS,不要加載HIMEM或者EMM386這樣的東西,它們會(huì )使上面的引導過(guò)程失敗。loadlin倒是可以來(lái)者通吃幾乎所有的DOS,不過(guò)它的作者也是這方面的大牛,對DOS下的內存管理非常的熟悉。我們現在研究這些古老的東西很難找資料了,況且我們是在寫(xiě)bootloader,不是DOS killer^_^。

7.引導時(shí)的高級功能

1)initrd

initrd是啟動(dòng)時(shí)的一個(gè)小虛擬盤(pán),一般用它來(lái)實(shí)現模塊化的內核。引導initrd的方法主要有兩個(gè)要點(diǎn):
第一,把initrd讀入內存,我們可以仿照大多數boot loader的方法把它放在內存的最高端;
第二,設定initrd的起始位置和長(cháng)度

bootsect_pos[0x218]開(kāi)始的4個(gè)字節放的是起始物理地址,bootsect_pos[0x21c]開(kāi)始的4個(gè)字節放的是initrd的長(cháng)度。

2)command_line支持

用command_line你可以給內核傳一些參數,自己定制內核的行為。我是這樣做的,首先把command_line放在9900H:0的地址里,然后把9900H:0的物理地址存放在bootsect_pos[0x228]開(kāi)始的4個(gè)字節里面。注意一定是物理地址,所以你應該放99000H這個(gè)數,然后內核就會(huì )識別你的command_line了。

8.結束語(yǔ)

寫(xiě)本文的目的主要是為了用最少的語(yǔ)言和最短的時(shí)間說(shuō)明bootloader的原理,真正的權威資料還是要看linux內核源碼和boot.txt文件。我曾經(jīng)寫(xiě)過(guò)一個(gè)例子loaderx,使用WATCOM C和TASM,WATCOM C是一個(gè)可以在DOS下生成能訪(fǎng)問(wèn)4GB物理地址程序的C編譯器,里面也有詳細的注釋和文檔說(shuō)明??梢詮南旅娴牡刂废螺d:loaderx.tar.gz

linux操作系統文章專(zhuān)題:linux操作系統詳解(linux不再難懂)


評論


相關(guān)推薦

技術(shù)專(zhuān)區

關(guān)閉
国产精品自在自线亚洲|国产精品无圣光一区二区|国产日产欧洲无码视频|久久久一本精品99久久K精品66|欧美人与动牲交片免费播放
<dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><small id="yhprb"></small><dfn id="yhprb"></dfn><small id="yhprb"><delect id="yhprb"></delect></small><small id="yhprb"></small><small id="yhprb"></small> <delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"></dfn><dfn id="yhprb"></dfn><s id="yhprb"><noframes id="yhprb"><small id="yhprb"><dfn id="yhprb"></dfn></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><small id="yhprb"></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn> <small id="yhprb"></small><delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn>