寫一個(gè)PC機(jī)的引導(dǎo)程序比我們想象的容易很多,事實(shí)上所需要了解的只是知道PC機(jī)是怎樣啟動(dòng)的,。在網(wǎng)上看到不少類似的文章,,說的很多,有的很麻煩,,筆者覺得僅僅是寫一個(gè)引導(dǎo)程序完全沒有必要牽涉太多東西,,知道足夠的知識(shí)用于去實(shí)際地寫一個(gè)出來看看是很多人最初的目的,那這篇文章就剛好適合你了,。這篇文章的立足點(diǎn)就是短,、簡(jiǎn)單、一看就懂,,而又不會(huì)看完了什么都不知道就寫出一個(gè)連自己都看不懂的代碼,。 現(xiàn)在,讓我們開始引導(dǎo)程序初探,! 什么是引導(dǎo)程序 很多文章中把寫一個(gè)引導(dǎo)程序稱作是開發(fā)一個(gè)最簡(jiǎn)單的操作系統(tǒng),,其實(shí)這是非常片面的,引導(dǎo)程序算不上操作系統(tǒng),,雖然此程序可以運(yùn)行在裸機(jī)上,。所謂引導(dǎo)程序,直觀的說就是在系統(tǒng)加電啟動(dòng)時(shí)BIOS第一個(gè)執(zhí)行的程序,。 引導(dǎo)程序要想發(fā)揮作用,,讓機(jī)器識(shí)別,,就必須安置在一個(gè)特別的位置,這個(gè)位置就是磁盤的第一個(gè)扇區(qū)(0面0磁道1扇區(qū),,備注:沒有0扇區(qū)),,而一個(gè)包含引導(dǎo)程序的扇區(qū)叫作引導(dǎo)扇區(qū)。 一個(gè)合法的引導(dǎo)扇區(qū)(1)通常包含512個(gè)字節(jié)(當(dāng)然嘍,,一個(gè)扇區(qū)通常本來就是512個(gè)字節(jié)),,(2)并且以0xAA55這樣一個(gè)占用兩個(gè)字節(jié)的數(shù)據(jù)結(jié)尾作為標(biāo)志符。(備注:0x前綴說明這是一個(gè)十六進(jìn)制數(shù)),。 也就是如果把引導(dǎo)扇區(qū)看成一個(gè)字符數(shù)組的BootSector[]話(因?yàn)橐粋€(gè)字符,,即char,剛好為一個(gè)字節(jié)),,那么這個(gè)數(shù)組就擁有512個(gè)元素,,如果用C語(yǔ)言申明的話即為 char BootSector[512]; 接著,一個(gè)合法的引導(dǎo)扇區(qū)必須以0xAA55結(jié)束,,即 BootSector[510] = 0x55; BootSector[511] = 0xAA; 除了結(jié)束標(biāo)志必須符合上面的要求之外,,中間雖然還有510字節(jié)的空間,但執(zhí)行代碼可以少于510字節(jié),,用無意義字符(通常用0x0)填充剩余空間即可,。 過程 PC是通過BIOS來啟動(dòng)機(jī)器的,當(dāng)PC機(jī)加電之后BIOS啟動(dòng)相應(yīng)的程序完成機(jī)器的自檢,,然后就尋找可以引導(dǎo)的驅(qū)動(dòng)器,,即大家通常所說的啟動(dòng)盤。在BIOS中可以設(shè)置從哪個(gè)盤啟動(dòng),,但通??傄獧z查硬盤,所以當(dāng)BIOS檢查完前面的啟動(dòng)設(shè)備之后,,如果沒有發(fā)現(xiàn)任何引導(dǎo)程序,,那么就會(huì)開始檢查主硬盤,即C盤,。如果此時(shí)在C盤上找到了合法的引導(dǎo)扇區(qū),,那么就會(huì)將引導(dǎo)扇區(qū)的內(nèi)容(共512字節(jié))裝載到內(nèi)存0x0000:07C00處。此時(shí)BIOS把控制權(quán)限交給這段引導(dǎo)程序,。 那么,,接下來,引導(dǎo)程序通常會(huì)簡(jiǎn)單的執(zhí)行一些指令,,比如輸出一段文字,,顯示一個(gè)啟動(dòng)界面等等,,但最重要的,,引導(dǎo)程序?qū)?huì)啟動(dòng)一個(gè)更大的程序,,然后把權(quán)限交給他,這通常就是我們所說的操作系統(tǒng)內(nèi)核,。額外補(bǔ)充一句,,目前對(duì)操作系統(tǒng)的定義有不少,但筆者比較贊成的觀點(diǎn)如下: 從形式上看,,操作系統(tǒng)是:從計(jì)算機(jī)啟動(dòng)到結(jié)束的過程中始終在運(yùn)行的程序,。而這通常就是我們所說的操作系統(tǒng)內(nèi)核。從功能上看,,操作系統(tǒng):管理和維護(hù)所有的硬件,、軟件、數(shù)據(jù)資源,,并為上層應(yīng)用或服務(wù)提供一個(gè)抽象的接口,。從某種層面上看,第二中定義更接近于虛擬機(jī),。 如何手制作引導(dǎo)扇區(qū) 現(xiàn)在,,已經(jīng)了解了這些基本的概念,那么,,如何動(dòng)手制作這樣的引導(dǎo)扇區(qū)呢,?這個(gè)過程十分簡(jiǎn)單, ?。?)首先按照要求寫一個(gè)合法的引導(dǎo)程序(通常用匯編,,機(jī)器碼也可以,呵呵),; ?。?)然后將其通過匯編程序,如NASM匯編成二進(jìn)制文件,; ?。?)最后,將這個(gè)二進(jìn)制文件寫入到目標(biāo)盤的第一個(gè)扇區(qū),。 跟我做 上面說的很簡(jiǎn)單吧,?那好,現(xiàn)在我們來寫一個(gè)吧,! 第一步:寫代碼 ; 文件名:boot.asm ; 代碼如下,,注意,匯編中通常用“;”來表示注釋內(nèi)容 ; 此段代碼參考《自己動(dòng)手寫操作系統(tǒng)》(于淵) ; ; 初始化函數(shù) org 07c00h ; 告訴編譯器將此段程序加載 ; 到內(nèi)存0x0000:07C00處 mov ax, cs mov ds, ax mov es, ax call PrintStr ; 調(diào)用屏幕打印函數(shù) jmp $ ; 無限循環(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é)束,!很短吧 第二步:匯編 假設(shè)你已經(jīng)安裝了NASM程序,那么進(jìn)入命令行模式,然后輸入以下命令: C:[PATH]\ nasm boot.asm -o boot.bin 其中“C:[PATH]\”為boot.asm代碼文件所在位置,。 現(xiàn)在如果不出意外的話,,你已經(jīng)擁有了boot.bin二進(jìn)制文件,這個(gè)就是引導(dǎo)程序,! 第三步:制作引導(dǎo)盤 由于不能隨便更改硬盤,,否則系統(tǒng)無法進(jìn)入原來的操作系統(tǒng),所以我們用軟盤來試驗(yàn),。 那么,,我們準(zhǔn)備一張軟盤。 現(xiàn)在,,我們要自己寫一個(gè)程序?qū)⑽覀儏R編得到的二進(jìn)制文件寫到軟盤的第一個(gè)扇區(qū),。 C語(yǔ)言程序代碼如下: /***************START***************/ #include #include int main(void) { FILE *in; unsigned char buffer[520]; if((in = fopen('boot.bin', 'rb'))==NULL) { printf('Error loading file\n'); exit(0); } fread(&buffer, 512, 1, in); while(biosdisk(3, 0, 0, 0, 1, 1, buffer)); fclose(in); return 0; } /****************END****************/ 注意,這個(gè)程序必須同boot.bin文件在同一目錄下,,然后將軟盤放進(jìn)軟驅(qū),,運(yùn)行此程序。 第四步:GOGOGO 好了,,現(xiàn)在你擁有了一張從頭到尾完全自制的引導(dǎo)盤,,由于有了她,你想運(yùn)行你的電腦再也不需要微軟插手了,,而且這很可能是你第一次能在裸機(jī)上運(yùn)行一個(gè)自己的程序哦,,哈哈! 重新啟動(dòng)你的機(jī)器,,記得把軟盤放進(jìn)去,,現(xiàn)在你看見什么了? 一行醒目的紅字: Welcome to Lee's OS *_* 打印在屏幕上,! 寫在后面 本文完整的講述了編寫引導(dǎo)程序的過程,,其中肯定會(huì)有一些不足,歡迎指正,。另外,,對(duì)于有各種其他想法,如希望在虛擬PC上嘗試的人,,那么只需要查找相應(yīng)方法就可以,。 |
|