[什么?]
很多文章中把寫(xiě)一個(gè)引導(dǎo)程序稱(chēng)作是開(kāi)發(fā)一個(gè)最簡(jiǎn)單的操作系統(tǒng),其實(shí)這是非常片面的,引導(dǎo)程序算不上操作系統(tǒng),雖然此程序可以運(yùn)行在*機(jī)上。所謂引導(dǎo)程序,直觀的說(shuō)就是在系統(tǒng)加電啟動(dòng)時(shí)BIOS第一個(gè)執(zhí)行的程序。
引導(dǎo)程序要想發(fā)揮作用,讓機(jī)器識(shí)別,就必須安置在一個(gè)特別的位置,這個(gè)位置就是磁盤(pán)的第一個(gè)扇區(qū)(0面0磁道1扇區(qū),備注:沒(méi)有0扇區(qū)),而一個(gè)包含引導(dǎo)程序的扇區(qū)叫作引導(dǎo)扇區(qū)。
一個(gè)合法的引導(dǎo)扇區(qū)(1)通常包含512個(gè)字節(jié)(當(dāng)然嘍,一個(gè)扇區(qū)通常本來(lái)就是512個(gè)字節(jié)),(2)并且以0xAA55這樣一個(gè)占用兩個(gè)字節(jié)的數(shù)據(jù)結(jié)尾作為標(biāo)志符。(備注:0x前綴說(shuō)明這是一個(gè)十六進(jìn)制數(shù))。
也就是如果把引導(dǎo)扇區(qū)看成一個(gè)字符數(shù)組的BootSector[]話(huà)(因?yàn)橐粋€(gè)字符,即char,剛好為一個(gè)字節(jié)),那么這個(gè)數(shù)組就擁有512個(gè)元素,如果用C語(yǔ)言申明的話(huà)即為
char BootSector[512];
接著,一個(gè)合法的引導(dǎo)扇區(qū)必須以0xAA55結(jié)束,即
BootSector[510] = 0x55;
BootSector[511] = 0xAA;
除了結(jié)束標(biāo)志必須符合上面的要求之外,中間雖然還有510字節(jié)的空間,但執(zhí)行代碼可以少于510字節(jié),用無(wú)意義字符(通常用0x0)填充剩余空間即可。
[過(guò)程]
PC是通過(guò)BIOS來(lái)啟動(dòng)機(jī)器的,當(dāng)PC機(jī)加電之后BIOS啟動(dòng)相應(yīng)的程序完成機(jī)器的自檢,然后就尋找可以引導(dǎo)的驅(qū)動(dòng)器,即大家通常所說(shuō)的啟動(dòng)盤(pán)。在 BIOS中可以設(shè)置從哪個(gè)盤(pán)啟動(dòng),但通??傄獧z查硬盤(pán),所以當(dāng)BIOS檢查完前面的啟動(dòng)設(shè)備之后,如果沒(méi)有發(fā)現(xiàn)任何引導(dǎo)程序,那么就會(huì)開(kāi)始檢查主硬盤(pán),即 C盤(pán)。如果此時(shí)在C盤(pán)上找到了合法的引導(dǎo)扇區(qū),那么就會(huì)將引導(dǎo)扇區(qū)的內(nèi)容(共512字節(jié))裝載到內(nèi)存0x0000:07C00處。此時(shí)BIOS把控制權(quán)限交給這段引導(dǎo)程序。
那么,接下來(lái),引導(dǎo)程序通常會(huì)簡(jiǎn)單的執(zhí)行一些指令,比如輸出一段文字,顯示一個(gè)啟動(dòng)界面等等,但最重要的,引導(dǎo)程序?qū)?huì)啟動(dòng)一個(gè)更大的程序,然后把權(quán)限交給他,這通常就是我們所說(shuō)的操作系統(tǒng)內(nèi)核。額外補(bǔ)充一句,目前對(duì)操作系統(tǒng)的定義有不少,但筆者比較贊成的觀點(diǎn)如下:
從形式上看,操作系統(tǒng)是:從計(jì)算機(jī)啟動(dòng)到結(jié)束的過(guò)程中始終在運(yùn)行的程序。而這通常就是我們所說(shuō)的操作系統(tǒng)內(nèi)核。從功能上看,操作系統(tǒng):管理和維護(hù)所有的硬件、軟件、數(shù)據(jù)資源,并為上層應(yīng)用或服務(wù)提供一個(gè)抽象的接口。從某種層面上看,第二中定義更接近于虛擬機(jī)。(閑話(huà)一段^_^)
[如何]
現(xiàn)在,已經(jīng)了解了這些基本的概念,那么,如何動(dòng)手制作這樣的引導(dǎo)扇區(qū)呢?這個(gè)過(guò)程十分簡(jiǎn)單,
(1)首先按照要求寫(xiě)一個(gè)合法的引導(dǎo)程序(通常用匯編,機(jī)器碼也可以,呵呵);
(2)然后將其通過(guò)匯編程序,如NASM匯編成二進(jìn)制文件;
(3)最后,將這個(gè)二進(jìn)制文件寫(xiě)入到目標(biāo)盤(pán)的第一個(gè)扇區(qū)。
跟我做:-P]
上面說(shuō)的很簡(jiǎn)單吧?那好,現(xiàn)在我們來(lái)寫(xiě)一個(gè)吧!
第一步:寫(xiě)代碼
; 文件名:boot.asm
; 代碼如下,注意,匯編中通常用“;”來(lái)表示注釋內(nèi)容
; 此段代碼參考《自己動(dòng)手寫(xiě)操作系統(tǒng)》(于淵)
;
; 初始化函數(shù)
org 07c00h ; 告訴編譯器將此段程序加載
; 到內(nèi)存0x0000:07C00處
mov ax, cs
mov ds, ax
mov es, ax
call PrintStr ; 調(diào)用屏幕打印函數(shù)
jmp $ ; 無(wú)限循環(huán)
PrintStr: ; 屏幕打印函數(shù)
mov ax, HelloWorld ; 將字符串拷貝到ax
mov bp, ax ; es:bp = 串地址
mov cx, 24 ; cx = 串長(zhǎng)度
mov ax, 01301h ; ah = 13, al = 01h
mov bx, 000ch ; 頁(yè)號(hào)為0(bh = 0) 黑底紅字(bl = 0ch,高亮)
mov dl, 0
int 10h ; 10h號(hào)中斷
ret
HelloWorld: db "Welcome to Lee's OS *_*" ; 字符串負(fù)值
times 510-($-$$) db 0 ; 用0x0填充剩余的空間使生成
; 的二進(jìn)制代碼剛好為512字節(jié)
dw 0xaa55 ; 結(jié)束標(biāo)志
; 整個(gè)程序結(jié)束!很短吧
很多文章中把寫(xiě)一個(gè)引導(dǎo)程序稱(chēng)作是開(kāi)發(fā)一個(gè)最簡(jiǎn)單的操作系統(tǒng),其實(shí)這是非常片面的,引導(dǎo)程序算不上操作系統(tǒng),雖然此程序可以運(yùn)行在*機(jī)上。所謂引導(dǎo)程序,直觀的說(shuō)就是在系統(tǒng)加電啟動(dòng)時(shí)BIOS第一個(gè)執(zhí)行的程序。
引導(dǎo)程序要想發(fā)揮作用,讓機(jī)器識(shí)別,就必須安置在一個(gè)特別的位置,這個(gè)位置就是磁盤(pán)的第一個(gè)扇區(qū)(0面0磁道1扇區(qū),備注:沒(méi)有0扇區(qū)),而一個(gè)包含引導(dǎo)程序的扇區(qū)叫作引導(dǎo)扇區(qū)。
一個(gè)合法的引導(dǎo)扇區(qū)(1)通常包含512個(gè)字節(jié)(當(dāng)然嘍,一個(gè)扇區(qū)通常本來(lái)就是512個(gè)字節(jié)),(2)并且以0xAA55這樣一個(gè)占用兩個(gè)字節(jié)的數(shù)據(jù)結(jié)尾作為標(biāo)志符。(備注:0x前綴說(shuō)明這是一個(gè)十六進(jìn)制數(shù))。
也就是如果把引導(dǎo)扇區(qū)看成一個(gè)字符數(shù)組的BootSector[]話(huà)(因?yàn)橐粋€(gè)字符,即char,剛好為一個(gè)字節(jié)),那么這個(gè)數(shù)組就擁有512個(gè)元素,如果用C語(yǔ)言申明的話(huà)即為
char BootSector[512];
接著,一個(gè)合法的引導(dǎo)扇區(qū)必須以0xAA55結(jié)束,即
BootSector[510] = 0x55;
BootSector[511] = 0xAA;
除了結(jié)束標(biāo)志必須符合上面的要求之外,中間雖然還有510字節(jié)的空間,但執(zhí)行代碼可以少于510字節(jié),用無(wú)意義字符(通常用0x0)填充剩余空間即可。
[過(guò)程]
PC是通過(guò)BIOS來(lái)啟動(dòng)機(jī)器的,當(dāng)PC機(jī)加電之后BIOS啟動(dòng)相應(yīng)的程序完成機(jī)器的自檢,然后就尋找可以引導(dǎo)的驅(qū)動(dòng)器,即大家通常所說(shuō)的啟動(dòng)盤(pán)。在 BIOS中可以設(shè)置從哪個(gè)盤(pán)啟動(dòng),但通??傄獧z查硬盤(pán),所以當(dāng)BIOS檢查完前面的啟動(dòng)設(shè)備之后,如果沒(méi)有發(fā)現(xiàn)任何引導(dǎo)程序,那么就會(huì)開(kāi)始檢查主硬盤(pán),即 C盤(pán)。如果此時(shí)在C盤(pán)上找到了合法的引導(dǎo)扇區(qū),那么就會(huì)將引導(dǎo)扇區(qū)的內(nèi)容(共512字節(jié))裝載到內(nèi)存0x0000:07C00處。此時(shí)BIOS把控制權(quán)限交給這段引導(dǎo)程序。
那么,接下來(lái),引導(dǎo)程序通常會(huì)簡(jiǎn)單的執(zhí)行一些指令,比如輸出一段文字,顯示一個(gè)啟動(dòng)界面等等,但最重要的,引導(dǎo)程序?qū)?huì)啟動(dòng)一個(gè)更大的程序,然后把權(quán)限交給他,這通常就是我們所說(shuō)的操作系統(tǒng)內(nèi)核。額外補(bǔ)充一句,目前對(duì)操作系統(tǒng)的定義有不少,但筆者比較贊成的觀點(diǎn)如下:
從形式上看,操作系統(tǒng)是:從計(jì)算機(jī)啟動(dòng)到結(jié)束的過(guò)程中始終在運(yùn)行的程序。而這通常就是我們所說(shuō)的操作系統(tǒng)內(nèi)核。從功能上看,操作系統(tǒng):管理和維護(hù)所有的硬件、軟件、數(shù)據(jù)資源,并為上層應(yīng)用或服務(wù)提供一個(gè)抽象的接口。從某種層面上看,第二中定義更接近于虛擬機(jī)。(閑話(huà)一段^_^)
[如何]
現(xiàn)在,已經(jīng)了解了這些基本的概念,那么,如何動(dòng)手制作這樣的引導(dǎo)扇區(qū)呢?這個(gè)過(guò)程十分簡(jiǎn)單,
(1)首先按照要求寫(xiě)一個(gè)合法的引導(dǎo)程序(通常用匯編,機(jī)器碼也可以,呵呵);
(2)然后將其通過(guò)匯編程序,如NASM匯編成二進(jìn)制文件;
(3)最后,將這個(gè)二進(jìn)制文件寫(xiě)入到目標(biāo)盤(pán)的第一個(gè)扇區(qū)。
跟我做:-P]
上面說(shuō)的很簡(jiǎn)單吧?那好,現(xiàn)在我們來(lái)寫(xiě)一個(gè)吧!
第一步:寫(xiě)代碼
; 文件名:boot.asm
; 代碼如下,注意,匯編中通常用“;”來(lái)表示注釋內(nèi)容
; 此段代碼參考《自己動(dòng)手寫(xiě)操作系統(tǒng)》(于淵)
;
; 初始化函數(shù)
org 07c00h ; 告訴編譯器將此段程序加載
; 到內(nèi)存0x0000:07C00處
mov ax, cs
mov ds, ax
mov es, ax
call PrintStr ; 調(diào)用屏幕打印函數(shù)
jmp $ ; 無(wú)限循環(huán)
PrintStr: ; 屏幕打印函數(shù)
mov ax, HelloWorld ; 將字符串拷貝到ax
mov bp, ax ; es:bp = 串地址
mov cx, 24 ; cx = 串長(zhǎng)度
mov ax, 01301h ; ah = 13, al = 01h
mov bx, 000ch ; 頁(yè)號(hào)為0(bh = 0) 黑底紅字(bl = 0ch,高亮)
mov dl, 0
int 10h ; 10h號(hào)中斷
ret
HelloWorld: db "Welcome to Lee's OS *_*" ; 字符串負(fù)值
times 510-($-$$) db 0 ; 用0x0填充剩余的空間使生成
; 的二進(jìn)制代碼剛好為512字節(jié)
dw 0xaa55 ; 結(jié)束標(biāo)志
; 整個(gè)程序結(jié)束!很短吧