一個最簡單引導扇區的編寫

一.操作系統的啓動過程
    具體的有關操作系統的啓動過程可參考這篇文章http://jingyan.baidu.com/article/ce09321b3b59442bff858f22.html。在看本文之前,建議讀者先把那篇文章看完。這裏簡單的對操作系統的啓動過程做一個概括。
    從 按下 POWER鍵操作系統可與用戶交互這中間發生了哪些事呢?
1.預引導階段
2.引導階段
3.加載內核階段
4.初始化內核階段
5.用戶登錄階段
    其中第一步(預引導階段)是BIOS自動完成的,我們不要做過多的關心。從第二步(引導階段)開始纔是我們可控的,也就是在這一步我們的代碼得到了執行。

預引導階段:
    這一階段因爲是BIOS自動完成的,我們編寫代碼不會涉及到這一塊,而且剛纔那個鏈接對這一部分介紹得也很詳細,這裏就不做過多介紹了,讀者只要瞭解即可,下面簡單的對預引導階段做個總結,要想詳細瞭解的可參考那個鏈接。
    1)進入系統BIOS
    我們按下了POWER鍵之後,電源就開始給設備供電。穩定供電後(讀者應該猜得到前面還有一個不穩定供電的過程),CPU就會從地址0xffff0處開始執行代碼,這個地址是在系統BIOS的範圍內,在這裏存放的是一條跳轉指令,會跳轉到系統BIOS中真正的啓動代碼處。

    2)POST

POWER ON SELF TEST。這一部分是從第1)步跳轉過來的,主要完成加電自檢的工作。主要檢查一些關鍵設備(內存、顯卡、CPU等)是否存在或能否正常工作。如果檢測到異常(如內存不存在)則會立馬死機。
    3)根據用戶指定的啓動順序從軟盤、硬盤或光驅啓動內核
  
引導階段:
    預引導階段的最後一步是 根據用戶指定的啓動順序從軟盤、硬盤或光驅啓動內核,注意這裏是根據用戶指定的順序,那麼用戶如何指定啓動順序呢?在系統啓動的時候進入BIOS,然後在BIOS裏設置啓動順序。比如我這裏是設置軟盤優先,那麼在啓動時會先判斷軟盤上是否包含啓動代碼,如果有啓動代碼,則把軟盤上的第一個扇區加載到內存0x7c00:0地址處,然後從該地址處開始執行;如果沒有啓動代碼,則會檢查下一個啓動介質(硬盤、光驅等),直到找到了啓動代碼。那麼問題來了,如何判斷出軟盤上有啓動代碼呢?檢查軟盤上的0號扇區,看該扇區的最後兩個字節是否爲0xaa55,如果是的話就認爲該軟盤上有啓動代碼。
    好了,說得比較羅嗦。這裏總結一下,要想自己的啓動扇區(512bytes)能夠被自動識別,我們只要將這個扇區的最後兩個字節設爲0xaa55即可。
    瞭解到這個知識之後,我們就可以編寫我們的引導扇區了。我們直接上代碼:

將它保存爲bootsect.asm
稍微學過x86彙編的人因該都看的懂代碼,而且註釋中也比較詳細。這裏最不好理解的就是綠色框中的那一句了。下面詳細的對這一句進行剖析。 、
在分析之前我們先編譯bootsect.asm
nasm bootsect.asm -o barras.img
我們用hexedit來看看barras.img的二進制是什麼樣子

我們可以看到,可以說整個barras.img文件由三個部分組成,第一個紅線框裏的數字,中間大部分的0以及第二個紅線框裏的數字0x55 0xaa。那麼這些數據是怎麼來的呢?
第一個紅線框裏的數字很明顯是由紅色框裏的代碼編譯後產生的二進制數據,而綠色框裏的代碼就是將中間填充了0,目的就是用0來擴充使得barras.img剛好爲一個扇區(512bytes)的大小,最後的兩個字節55 aa很明顯是黃色框代碼編譯後產生的效果,目的就是告訴BIOS我是啓動扇區。
$就是當前行所在的地址,$$就是當前行 所在的段的起始地址。$-$$其實就表示的是紅色框裏的代碼編譯後的長度,爲什麼要用510而不是512減去這個長度呢?因爲要保留最後兩個字節給0x55,0xaa。

加載到內存中後如圖所示:


 好了,代碼講解完了,下面我們用虛擬機來運行一下看下效果吧!
我們新建一個虛擬機,取名爲barras,用軟盤加載剛纔生成的barras.img,如圖

我們保存然後運行,看到的效果如下:

正如你所看到的,什麼結果也沒有,因爲我們什麼也沒做啊!只是一直在jmp $。不過我們的啓動扇區被BIOS正確識別了,是不是很興奮呢,呵呵。

更詳細的請參考視頻教程:http://www.duobei.com/course/1574348473

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章