在存儲介質(硬盤、軟盤、光盤)中有一塊特殊的區域,叫做引導區。在計算機啟動后,BIOS會讀取引導區內的代碼到內存中去,然后將執行這些代碼。引導區的位置和大小與計算機的平台有關,對於IBM-PC兼容機,引導區位於存儲介質的第一個扇區,大小為512字節。位於引導區內的代碼就稱為引導程序。引導區內是否含有引導程序由引導區內的標記標識。對於IBM-PC兼容機,如果引導區內的最后兩個字節為0x55,0xAA,則BIOS檢測程序認為引導區內包含引導程序。引導程序並不一定要實現加載操作的功能,它可以是任何程序。
IBM-PC兼容機的具體啟動過程如下:
1.按下計算機的電源鍵后,x86 CPU就開始在實模式下運行位於物理地址0xFFFFFFF0(通常這個地址是指向的是位於ROM中的BIOS的入口點)處的指令,這個指令是一個跳轉指令,跳轉到BIOS的啟動程序。啟動程序運行硬件檢測和初始化操作。
2.在初始化所需要的硬件后,BIOS就依據設定的啟動順序遍歷存儲設備,直到找到一個可引導的設備。一個可引導的存儲設備是引導區內包含引導程序。BIOS通過檢查引導區的最后兩個字節是否為0x55,0xAA來判斷引導區內是否包含引導程序。
3.一旦BIOS找到了可引導的設備,它就加載引導區代碼到內存物理地址的0x7C00(通常是Segment:Offset 0000h:7C00h,也有些BIOS為07C0h:0000h),之后BIOS將控制權交給引導程序,CPU開始執行引導程序,引導程序開始加載操作系統內核或者其他。
在格式化硬盤安裝好Windows后,硬盤第一個扇區(引導區)包含MBR引導代碼,BIOS在加載MBR代碼后,MBR開始檢查硬盤中是否存在活動分區(含引導程序的分區),如果存在活動分區,則加載位於那個分區的引導程序(通常稱為VBR,與操作系統相關),然后執行它。VBR的主要功能是加載操作系統的內核。
了解了相關知識,我們如何編寫一個打印Hello World的引導程序呢?
需要准備的工具:
文本編輯軟件、MASM編譯器(我采用的是VS2008自帶的ML 9.0)、16位Link程序、VMWare、PE(用於格式化VMWare創建的虛擬磁盤)、NtExplorer
具體步驟:
1. 打開你習慣使用的文本編輯器,編寫下面代碼。因為BIOS會將我們的引導程序加載到內存地址的7C00h處,所以我們需要org指令設置我們代碼指令的地址值。
;------------------------------------------------------------ .286 ; CPU type ;------------------------------------------------------------ .model TINY ; memory of model ;------------------------------------------------------------ ;----------------------- CODE SEGMENT ----------------------- .code org 07c00h ; for BootSector main: jmp short start ; go to main nop ;--------------------- Print a char on the screen ------------ PrintChar PROC mov ah, 0Eh ;Tell BIOS that we need to print one charater on screen. mov bh, 0h ;Page no. mov bl, 07h ;Text attribute 0x07 is lightgrey font on black background int 10h ;Call video interrupt ret PrintChar ENDP ;------------------- Print a String on the screen ------------- PrintStr PROC next_character: ;Lable to fetch next character from string mov al, [si] ;Get a byte from string and store in AL register inc si ;Increment SI pointer or al, al ;Check if value in AL is zero (end of string) jz exit_function ;If end then return call PrintChar ;Else print the character which is in AL register jmp next_character ;Fetch next character from string exit_function: ;End label ret PrintStr ENDP start: cli ; Clear interrupt flags mov ax,cs ; Setup segment registers mov ds,ax ; Make DS correct mov es,ax ; Make ES correct mov ss,ax ; Make SS correct mov bp,7c00h mov sp,7c00h ; Setup a stack sti helloString BYTE 'Hello World!', 0 mov si, offset helloString call PrintStr ; Print the 'Hello World!' string ret BYTE 510 - ($ - main) DUP(0) ; Fill the reminder of the first sector with zeros BYTE 55h, 0AAh ; Fill the last two bytes with 55h, 0AAh int the first sector END main ; End of program
2. 假設第一步中的代碼保存為BootLoader.asm,在BootLoader.asm的目錄下按住Shift,點擊鼠標右鍵,選擇在此處打開命令行(Windows 7系統,其他系統請通過CD指令轉到BootLoader.asm文件的目錄)。鍵入下面命令:
ml /AT /omf /Fl /Fm /c BootLoader.asm
C:\Irvine\link6.exe /T /NOD BootLoader.obj
如果提示找不到ml,請添加其路徑到環境變量(我的路徑為C:\Program Files\Microsoft Visual Studio 9.0\VC\bin\ml.exe)。執行完后,我們將得到BootLoader.com文件。

3. 使用VMware創建一個虛擬機,並新建一塊虛擬磁盤(大小1G,預先分配磁盤空間,存儲為單文件格式)。將新建的虛擬磁盤格式化為NTFS格式(使用PE或者其他工具)。右擊VMWare界面左邊的我們新建的虛擬機,進入設置->選中我們新建的磁盤->工具->映射(或者也可以通過菜單的文件->映射虛擬磁盤->映射),出現下面的對話框。去掉read-only的選項,然后點擊OK。

4. 打開NtExplorer軟件,先進入Tools->Options,將安全模式改為Virtual Write。然后點擊菜單File->Drive,選擇Z盤。按F3鍵,進入16進制編輯模式。可以看到扇區0已經有MBR代碼了。

將光標位於00位置處,然后選擇菜單Edit->Paste from file,選擇我們之前生成的BootLoader.com文件。然后選擇Tools->Options,點擊Write->OK。

5. 再次選擇我們新建的虛擬機,進入設置,取消磁盤的映射。然后點擊啟動虛擬機,你就可以看到Hello World了!

相關資料:
1. How to develop your own Boot Loader
2. Writing Hello World Bootloader
3. Boot sector
