系統引導載入器的簡單實現

2022-07-09 22:03:16 字數 3942 閱讀 3651

在實現引導載入器之前,首先我們先了解下在開機之後系統是怎麼被引導的,這對於實現引導載入器來說是很重要的。只有知道原理,才能更好的實現嘛。

1 引導過程

1.1 當電源按鈕按下時

當我們按下電源按鈕是到底發生了什麼?當這個按鈕被按下後,連線到這個按鈕的線纜會向主機板傳送乙個電訊號,主機板簡單的把這個訊號**給電源(psu )。這個訊號只包含

1位元資訊。如果是

0,表示沒電(計算機關閉,主機板不活動)。如果是

1(活動訊號),意味著系統已經加電。

當psu 收到這個活動訊號,它開始向系統的其餘部分供電。當所有裝置都得到正確數量的供電時,就可以確定psu會持續向它們供電而不發生大的問題。psu會傳送乙個「供電正常(power_good )」的訊號到主機板的基本輸入輸出系統 (bios) 。

1.2 bios自檢

到那個bios 接收到「power_good 」訊號,bios 開始乙個稱為post(power on self test 加電自檢) 的初始化過程。post 通過測試確保供電正確,裝置已安裝 ( 如:鍵盤、滑鼠、usb 、串列埠等) ,並確保記憶體狀態良好 ( 通過檢測記憶體損傷) 。post 向bios 交出控制權。post 將bios 載入到記憶體的末尾( 可能是0xfffff0) 並且在記憶體的第乙個位元組處放置乙個跳轉指令。處理器指令指標 (cs:ip) 被設定為0 ,然後處理器得到控制權。什麼意思呢?處理器會在位址0x0 處開始執行指令。這裡,它是一條post 程式放置的跳轉指令,這條指令跳轉到0xfffff0 處( 或者其他bios 被載入到的位址) ,然後處理器開始執行bios 。bios 得到控制權……

1.3 bios

基本輸入輸出系統(bios) 會做一些工作。它建立乙個中斷向量表 (ivt), 並提供基本的中斷服務。bios 然後會做一些檢查以確保沒有硬體問題。bios 也提供乙個設定的功能。bios 需要找到乙個作業系統。根據您在bios設定中指定的引導順序,bios 執行0x19 號中斷來找出乙個可引導裝置。如果沒有找到可引導裝置 (int 0x19 返回了) ,bios 會嘗試引導順序列表中的下乙個裝置。如果再沒有可供嘗試的裝置,bios 會列印乙個類似於「作業系統未找到」的資訊,並停止系統的執行。

1.4 中斷與中斷向量表(ivt)

乙個中斷是可以被許多不同的程式呼叫的子程式。這些中斷被儲存在從位址0x0 開始的被稱為中斷向量表的空間中。比如,乙個常見的中斷int 0x21被用於dos 系統。

注意:這兒沒有dos !「只有」bios 設定的中斷才有效,沒有其他的!使用其他的中斷會導致系統執行不存在的程式,這將導致你的系統崩潰。

注意:如果切換處理器模式到保護模式,ivt 會變得無效。這意味著,任何的中斷(無論軟硬體,包括bios )全都無效。 對於32 位作業系統,我們不得不這樣做

1.5 bios 0x19 中斷

該中斷由bios 執行。它讀入磁碟的第乙個扇區( 扇區(sector ) 1, 磁頭(head ) 0, 磁軌(track ) 0) 。如果磁碟可引導,則引導扇區會被載入到0x7c00,int 0x19 會跳轉到那裡,將控制權交給引導載入器。

1.6 引導扇區

由0x19中斷讀取的第乙個扇區正是引導扇區,裡面存放了引導載入器的**。當被讀入記憶體0x7c00後,引導載入器就得到了控制權,開始執行載入系統。

1.7 為什麼要引導載入器

為什麼不把作業系統的**直接寫到第乙個扇區,還要這麼麻煩先執行個引導載入器,再把系統載入到記憶體中,開始我也覺得直接把系統寫到第乙個扇區更好,可後來發現其實不然。第二種方法就方便了,就像我們在操作檔案一樣的,可以隨時修改系統程式,而第一中我們還要再每次對系統程式修改後用dd命令寫入扇區,而且還要好好的計算大小,所以比較的麻煩,也比較容易出錯。

2 引導載入器的實現

我的簡單引導載入器實現的**比較簡單,就是從裝有fat12檔案系統的軟盤(軟盤映象檔案)中讀取乙個叫setup的可執行檔案,並最終執行這個setup程式,setup程式會在螢幕上列印preparing to load operating system...,如下圖所示:

2.1 製作裝有fat12檔案系統的軟盤映象檔案

首先製作乙個空的1.44m的軟盤映象檔案:

dd if=/dev/zero of=bootsect.img bs=512 count=2880
然後用「mkfs.msdos -f 12」命令格式化軟盤映象檔案為fat12檔案系統

mkfs.msdos -f 12 bootsect.img
2.2 拷貝setup程式到軟盤映象中這個程式很簡單,就列印一條語句,主要是為了測試引導引導程式是否成功載入了setup程式,編譯可執行檔案後怎樣把它拷貝到軟盤映象中呢?這個其實很簡單,就像其它的檔案系統一樣,fat12也可以掛載到linux中的某個目錄下,然後將setup程式拷貝到這個目錄下就可以了。具體操作為:

losetup /dev/loop5 bootsect.img 

mount /dev/loop5 floppy/cp setup floppy/umount floppy/losetup -d /dev/loop5

不過在我系統裡losetup -d /dev/loop5命令執行總是失敗,總是提示loop: can't delete device /dev/loop5: device or resource busy,網上有人說是bug,具體什麼原因還不知道。

2.3 編寫引導引導程式

引導載入器的思路其實很簡單,就是先載入fat12檔案系統的根目錄所在的扇區到記憶體中,然後在根目錄中查詢檔案名為setup的目錄項,找到後獲得setup所在的族號。再載入fat12的fat表。根據找到的族號來獲得setup在軟盤中的具體位置,並將其載入到記憶體中,如果setup檔案較大,乙個族不夠,可以通過fat表查詢乙個族,再將下乙個族載入到記憶體...,等全部載入setup到記憶體後,將控制權交給setup程式,然後setup程式就開始執行了,也就出現了上面圖中的內容。這裡的難點可能就是計算目錄項在軟盤中的位置、setup程式在軟盤中的位置。

2.4 拷貝引導引導程式到軟盤映象的第乙個扇區

對於編譯好了的引導引導程式怎樣拷貝到軟盤映象的第乙個扇區來作為引導扇區呢?還是用linux的好工具dd,具體如下:

dd if=bootsect.img of=bootloader skip=1 seek=1 bs=512 count=2879
bootsect.img為我們前面製作好的軟盤映象,bootloader為我們編譯好的引導引導程式。這條命令執行後bootloader就是我們的包含引導載入器的軟盤映象檔案了,可以作為虛擬機器的映象檔案來引導系統了(相當於我們這裡的setup程式)。在bochs中執行的畫面就是上面給出的圖,當然也可以在其他虛擬機器上執行,像wmware。

3 總結

實現這個引導載入器,讓我學到了很多關於系統啟動的東西,如引導扇區的載入過程,fat12檔案系統,軟盤映象的製作等。不過也發現了很多問題,特別是對彙編的不熟練,寫這個程式中間一直出現問題,但開始自己也不會除錯匯程式設計序,所以不知所措,後來才慢慢通過學習debug除錯,bochs除錯來慢慢解決的。不過深感還有很多東西要學習。

附件:bootloader和setup程式源**

簡單理解類載入器

虛擬機器設計團隊把類的載入階段中的 通過類的全限定名來獲取描述此類的二進位制檔案 這個操作放到虛擬機器外部去實現,以便讓程式自己去決定去實現如何載入乙個類,實現這一功能的就是 類載入器 對於任意乙個類,都需要由載入它的類載入器和這個類本身一同確定它在jvm中的唯一性。在比較兩個類是否相等的時候,只有...

配置載入 簡單工廠實現

程序對多個配置進行reload,reload前判斷配置的版本號是否有公升級 使用簡單工廠思想進行實現。include include include typedef void pfunc 用於指向具體載入配置檔案的函式 using namespace std enum type struct con...

簡單實現網頁載入動畫

今天自己實現了這個功能,記錄一下 效果 進入網頁時先出現載入動畫,載入完畢後顯示網頁 實現原理 在html上方放乙個div,用來顯示載入動畫,js判斷載入完畢事件,將div隱藏即可。知識點整理 偽元素實現垂直居中 awesome字型動畫 js判斷html載入是否完成 css body loading...