2007年10月10日 星期三

OrzMicrokernel boot.asm 啟動磁區定義和程式初始化註解

Standard
OrzMicrokernel 的 boot.asm 是針對 1.44 MB 磁碟片所設計的,採用的是 FAT12 ﹝注意不是 FAT16 或 FAT32﹞的檔案系統,所以,在啟動磁區的部份的定義上比較簡單且單純。另外,這次註解的內容主要是程式一開始的部份,包括初始化、在螢幕上顯示一段文字等。

程式碼與詳細註解:
Base:
jmp short Begin ; 從 Begin 執行
nop ; 空執行

; 啟動磁區格式
oem db 'OrzMicro' ; 廠商軟體名
bytesPerSector dw 0x0200 ; 設每磁區的大小為 512 Bytes
sectPerCluster db 0x02 ; 每磁叢的磁區數
resSectors dw 0x01 ; FAT 前的磁區數
; ﹝開機記錄所佔用的磁區數﹞
fatCopies db 0x02 ; FAT 表總數
rootEntCnt dw 0x0070 ; 根目錄的最大檔案數
totalSectors dw 0x05A0 ; 邏輯磁區總數
media db 0xF9 ; 磁碟種類
sectPerFat dw 0x0003 ; 每個 FAT 表的磁區數
sectPerTrack dw 0x0009 ; 每磁軌的磁區數
heads dw 0x0002 ; 磁頭數﹝面數﹞
hiddenSectors dd 0 ; 隱藏磁區數
sectorHuge dd 0 ; 保留 4 Bytes
drive db 0 ; 中斷 INT13 的磁碟機編號
db 0 ; 保留 1 Byte
extendedBPB db 0x29 ; 開機特徵碼
volumeID dd 0 ; 磁碟序號
volumeLabel db 'Orz Disk ' ; 磁碟標籤(11 Bytes)
fileSys db 'FAT12 ' ; 檔案系統類型﹝必須為 8 Bytes﹞

;------------------------------------------------------------------------

Begin:
; 初始化程式
cli ; 禁用中斷以免干擾初始化
cld ; 設定字串處理時由低住址往高位址
mov ax,cs ; 初始化暫存器
mov ds,ax
mov ss,ax
mov sp,7c00h ; 此程式將在 0000:7c00 執行
sti ; 啟用中斷

mov [curDrive],dl ; 從 BIOS 取得目前使用的裝置

;-----------------------------------------------

; 初始化顯示記憶體並顯示核心訊息
; 函式 Print 的參數:SI = 字串, ES:DI = 顯示記憶體位置, AH = 顏色
mov ax,$03 ; 為中斷設定 AH=03h 以讀取游標位置
int $10 ; 開始中斷 10h

; 設定顯示記憶體位址到 ES:DI
mov ax,$0B800 ; 設定顯示記憶體位址:0xB8000
mov es,ax ; 設定 ES 區段
xor di,di ; 設定 DI:由第零列第零行開始寫入

; 在螢幕上顯示核心訊息
mov si,fname ; 設定 SI:字串為核心檔案名稱
mov ah,$2F ; 設定 AH:字串顏色為白色
call Print ; 呼叫顯示字串函式



而關於螢幕顯示字串的部份,被拉出去做成了一個副程式 Print 方便日後經常使用:

; 顯示字串函式
; SI = 字串, ES:DI = 顯示記憶體位置, AH = 顏色
Print:
mov al,[cs:si] ; 取得 SI 裡的字串
and al,al ; 判斷如果為字串結尾
jz Print0 ; 則顯示字串函式結束返回

mov [es:di],al ; 將字串第一個位置的字元輸出到顯示記憶體
inc di ; 顯示記憶體位置往後移動一位以設定顏色
mov [es:di],ah ; 設定該字元顏色

inc di ; 顯示記憶體位置往後移動一位
inc si ; 設定指向下一個字元
jmp short Print ; 呼叫函式顯示下一個字元
Print0: ret



後記

由於在 blog 上不能顯示 <TAB> ,所以在貼程式碼的時候都要手動將 <TAB> 換成空格,這應該算是最累人的部份。而且一行程式碼或註解如果太長,就會超出顯示範圍消失在邊界之外,讓人要一直不停去檢查,手動做換行的動作。唉,在 Blog 貼程式碼真是一件辛苦的事﹝汗﹞。