對應書01~27頁
很早之前就想照着《30天自制操作系統》這本書把代碼實現,但是當時匯編部分沒怎么看懂。現在終於能看懂一些了,於是准備重新看這本書。這本書好在大多數代碼都是用C語言寫的,可讀性比較強,光盤里附帶的資料也比較齊全,惟一的不足是代碼的注釋沒有翻譯成中文,那就讓我對着書把中文注釋打上去吧,也能看一遍作者寫了什么。
第0天的內容有些完全是激發讀者的好奇心,但是容易把小白弄得雲里霧里。
-
helloos0:
helloos0直接用二進制編輯器寫了一個img鏡像文件,雖然鏡像文件都是二進制文件沒錯,但是沒有人會用二進制編輯器直接寫,而是將想要的內容交給某個能產生鏡像文件的軟件,交給軟件執行這個枯燥的步驟,因此本人覺得helloos0只需看看即可。
-
helloos1
helloos1把helloos0內容改用匯編語言寫了一遍,可惜都是DB、DW等寫入命令,我們暫且知道這是往內存里寫東西了,但是具體寫啥還是要下回分曉。
注:
DB指令是向內存寫入一個字節(8位)數據;
DW指令是向內存寫入一個字(雙字節,也就是16位)數據;
具體寫什么數據,由指令后面跟的數字決定。
-
helloos2
從這個版本開始我們可以稍稍讀懂作者在這個img文件內寫了些什么,其中";"后面的內容是注釋,編譯器在編譯成機器碼時自動略去這部分內容。
pigz.nas 代碼如下:
; pigz
; TAB=4
; 以下為標准FAT12格式軟盤專用代碼
DB 0xeb, 0x4e, 0x90
DB "HELLOIPL" ; 啟動區的名字可以是任意字符串(8字節)
DW 512 ; 定義每個扇區的大小(必須為512字節)
DB 1 ; 定義簇的大小(必須為1個扇區)
DW 1 ; FAT的起始位置(一般從第一個扇區開始)
DB 2 ; FAT的個數
DW 224 ; 根目錄的大小(一般設成224項)
DW 2880 ; 該磁盤的大小(必須是2880扇區)
DB 0xf0 ; 磁盤的種類(必須是0xf0)
DW 9 ; FAT的長度(必須是9扇區)
DW 18 ; 1個磁道有幾個扇區(必須是18)
DW 2 ; 磁頭數(必須是2)
DD 0 ; 不使用分區(因此是0)
DD 2880 ; 重寫一次磁盤大小
DB 0,0,0x29 ; 意義不明,固定
DD 0xffffffff ; (可能是)卷標號碼
DB "HELLO-OS " ; 磁盤的名稱(11字節)
DB "FAT12 " ; 磁盤格式名稱(8字節)
RESB 18 ; 先空出18字節
; 程序主體
DB 0xb8, 0x00, 0x00, 0x8e, 0xd0, 0xbc, 0x00, 0x7c
DB 0x8e, 0xd8, 0x8e, 0xc0, 0xbe, 0x74, 0x7c, 0x8a
DB 0x04, 0x83, 0xc6, 0x01, 0x3c, 0x00, 0x74, 0x09
DB 0xb4, 0x0e, 0xbb, 0x0f, 0x00, 0xcd, 0x10, 0xeb
DB 0xee, 0xf4, 0xeb, 0xfd
; 信息顯示部分
DB 0x0a, 0x0a ; 換行2次
DB "hello, world"
DB 0x0a ; 換行
DB 0
RESB 0x1fe-$ ; 填寫0x00,直到0x01fe
DB 0x55, 0xaa
; 以下是啟動區以外部分的輸出
DB 0xf0, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00
RESB 4600
DB 0xf0, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00
RESB 1469432
在具體分析這段代碼之前,我們先了解一些FAT12文件系統的知識。這里節選了FAT12文件系統這篇博客的重要部分,有興趣可以全文閱讀。
FAT12介紹
FAT12是DOS時代就開始使用的文件系統(File System),直到現在仍然在軟盤上使用,FAT12軟盤的被格式化后為:有兩個磁頭,每個磁頭80個柱面(磁道),每個柱面有18個扇區,每個扇區512個字節空間。所以標准軟盤的總空間為:
2 * 80 *18 * 512=1474560B=1440K=1.44M
引導扇區
操作系統之所以認識FAT12格式的磁盤,其秘密就在於邏輯0扇區這512B上。如果這512字節的最后兩個字節的內容分別是55和AA(0xAA55低字節在前,高字節在后)的話,BIOS在啟動時會將這個扇區讀取到0x7C00H~0x7DFFH處,然后跳轉到0:7C00h處繼續執行指令,操作系統即用此來達到引導系統的目的,而這個磁盤就稱為引導磁盤。
操作系統標識FAT12文件系統是因為在邏輯0扇區(即引導扇區)處還存儲着一個特定的數據結構,此結構有固定的格式,在操作系統將此磁盤格式化時自動生成,具體數據結構如下表所示:
名稱 開始字節 長度 內容 參考值 在代碼中行號 BS_jmpBOOT 0 3 一個短跳轉指令 jmp short LABEL_STARTnop 6 BS_OEMName 3 8 廠商名 'ZGH' 7 BPB_BytesPerSec 11 2 每扇區字節數(Bytes/Sector) 0x200 8 BPB_SecPerClus 13 1 每簇扇區數(Sector/Cluster) 0x1 9 BPB_ResvdSecCnt 14 2 Boot記錄占用多少扇區 0x1 10 BPB_NumFATs 16 1 共有多少FAT表 0x2 11 BPB_RootEntCnt 17 2 根目錄區文件最大數 0xE0 12 BPB_TotSec16 19 2 扇區總數 0xB40 13 BPB_Media 21 1 介質描述符 0xF0 14 BPB_FATSz16 22 2 每個FAT表所占扇區數 0x9 15 BPB_SecPerTrk 24 2 每磁道扇區數(Sector/track) 0x12 16 BPB_NumHeads 26 2 磁頭數(面數) 0x2 17 BPB_HiddSec 28 4 隱藏扇區數 0 18 BPB_TotSec32 32 4 如果BPB_TotSec16=0,則由這里給出扇區數 0 19 BS_DrvNum 36 1 INT 13H的驅動器號 0 20 BS_Reserved1 37 1 保留,未使用 0 20 BS_BootSig 38 1 擴展引導標記(29h) 0x29 20 BS_VolID 39 4 卷序列號 0 21 BS_VolLab 43 11 卷標 'ZGH' 22 BS_FileSysType 54 8 文件系統類型 'FAT12' 23 引導代碼及其他內容 62 448 引導代碼及其他數據 引導代碼(剩余空間用0填充) 24~42 結束標志0xAA55 510 2 第510字節為0x55,第511字節為0xAA 0xAA55 43
從6~43行內容都是FAT12文件格式的規定的,值得注意的是,當我們使用了軟盤啟動系統時,首先會把軟盤中第一個扇區(512字節)加載到內存,判斷從第510字節開始是否為0xAA55,若是則說明這是一張啟動盤,BIOS會開始從0x7C00H進行引導。
問題清單1:改注釋的時候出現的一些問題
-
notepad++如果出現了中文亂碼怎么辦?
菜單欄-->編碼-->使用UTF-8編碼
如果切換不了編碼就Ctrl+A全選並剪切后切換,切換成功后再粘貼回去。
-
字體有促又粗有粗有細怎么辦?
設置-->語言格式設置
字體選擇Consolas,並勾選使用全局字體,然后保存並關閉