-
讓系統跑起來
要寫一個操作系統,我們首先要有一個儲存系統的介質,原版書似乎是06年出版的,可惜那時候沒有電腦,沒想到作者用的還是軟盤,現在的電腦誰有軟驅?不得已我使用一張128M的SD卡來代替,而事實上你用的是U盤還是軟盤對我們的操作系統沒有影響,缺點是你的U盤刷入系統后容量只能是1440 MB,即當年流行的3.5英寸軟盤的大小,當然不用擔心,再格式化一次(用DiskGeniu),就可以恢復。
我做事情的話,總是怕自己的努力的結果白費了,害怕辛辛苦苦看完這本書但是發現做出來的東西現在根本沒法用,比如你花了大力氣造了一輛火車,發現輪子的間距和現行標准不符,沒軌道可以跑,被標准拋棄的感覺太恐怖,所以我決定試試,作者的系統能不能真正地跑起來。
我選擇了源碼中projects\30_day\harib27f中的haribote.img文件,用ImgWriter寫入到我的儲存卡,
寫入后的大小和預期相符,1.x MB;
重新啟動,開機時狂按Delete,修改啟動項;
F10保存后重啟,心中有些忐忑不安;
… …
但是結果還是如我所願,看,It works!
這是就是我們要完成的東西了,偷窺勝利果實的快感不言而喻,系統甚至支持USB鍵盤,但不支持USB鼠標確實是不能用。我試着輸入了幾個命令:
Bad command. 我也不知道什么是作者指定的command,已知的是,exit能用。
-
用Virtual Box 代替物理機
頻繁地開關電腦來調試我們的系統是不理想的,我們需要Virtual Box來搭把手。
打開VB的控制台,新建虛擬機,操作系統的類型選Other,版本選擇Other\Unknown,
一直點下一步直到虛擬硬盤,選擇不添加虛擬硬盤,我們的虛擬硬盤文件就是img。
選擇虛擬電腦的設置——儲存——儲存樹,添加一個軟盤控制器,原來的IDE控制器可以刪掉了,在軟盤控制器里新增軟盤到控制器,當然選擇剛才的haribote.img,然后大功告成,啟動系統。
啟動系統后一切都顯得那么完美,鼠標能用,鍵盤也是,而且非常方便,輸入的蹩腳英文或許有錯,見笑了。
PS: 這里需要注意的是本來有另一種方案,使用VB安裝目錄下的VBoxManage.exe 執行 VBoxManage convertdd file.img file.vdi
但不知為何,沒辦法轉換上述的haribote.img,只能轉換下面要寫的hello, world。
-
動手寫操作系統
電腦啟動的步驟是簡要部分步驟是:加電——讀取BIOS——自檢——控制權移交操作系統(或者說引導),如此看來,我們的任務就是編寫一段符合規范的代碼,在第四步的時候代碼會被執行。
首先我們需要一個標准的FAT12的啟動扇區(Boot sector)的代碼,我很希望有FAT32 的,無奈這本書給的就是FAT12的,代碼如下:
但是這段完全由數據組成的代碼只是符合了一個軟盤啟動扇區的標准,還沒有任何可執行的代碼:
1 ; OS 0.01 2 ; 標准FAT12軟盤專用代碼 3 4 DB 0xeb, 0x4e,0x90 5 DB "HELLOIPL" ; 啟動扇區(boot sector)的名字 6 DW 512 ; 每個扇區(sector)的大小:512B 7 DB 1 ; 簇(cluster)的大小:一個扇區 8 DW 1 ; FAT的起始位置 9 DB 2 ; FAT的個數 10 DW 224 ; 根目錄大小 11 DW 2880 ; 磁盤大小 2880扇區 12 DB 0xf0 ; 磁盤種類 13 DW 9 ; FAT長度 14 DW 18 ; 一個磁道(track)有18個扇區 15 DW 2 ; 磁頭數 16 DD 0 ; 不使用分區 17 DD 2880 ; 重寫磁盤大小 18 DB 0,0,,0x29 ; 固定 19 DD 0xffffffff ; 意義不明 20 DB "HELLP_OS " ; 磁盤名稱11字節 21 DB "FAT12 " ; 磁盤的格式名稱8字節 22 RESB 18 ; 空出18 Bit
下面添加了可執行的代碼,可以稱作是IPL了。
1 ; hello-os 2 ; TAB=4 3 4 ORG 0x7c00 ;為什么這兩句可以代替前面的 0xeb 0x4e? 5 JMP entry 6 DB 0x90 7 DB "HELLOIPL" 8 DW 512 9 DB 1 10 DW 1 11 DB 2 12 DW 224 13 DW 2880 14 DB 0xf0 15 DW 9 16 DW 18 17 DW 2 18 DD 0 19 DD 2880 20 DB 0,0,0x29 21 DD 0xffffffff 22 DB "HELLO-OS " 23 DB "FAT12 " 24 RESB 18 25 26 entry: 27 MOV AX,0 28 MOV SS,AX ;這里改為 SS,0會出錯 29 MOV SP,0x7c00 30 MOV DS,AX 31 MOV ES,AX 32 MOV SI,msg ;儲存字符串的首地址 33 putloop: 34 35 MOV AL,[SI] 36 ADD SI,1 37 CMP AL,0 38 JE fin 39 MOV AH,0x0e ; int 0x10 的 0x0e號功能 40 MOV BX,0x15 41 INT 0x10 42 JMP putloop 43 fin: 44 HLT 45 JMP fin 46 47 msg: 48 DB 0x0a, 0x0a ; '\n' = #13 = 0x0a 49 DB "LastAvengers's OS" 50 DB 0x0a 51 DB 0 ; 結束標志 52 53 RESB 0x7dfe-$ ; 0x01fe+0x7c00 = 0x7dfe 54 DB 0x55, 0xaa 55 DB 0xf0, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00 56 RESB 4600 57 DB 0xf0, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00 58 RESB 1469432
使用作者提供的nask.exe,執行 nask.exe IPL.asm a.img 可以得到鏡像文件,可以利用VB來啟動了。
-
簡化操作流程:
一開始作者為我們提供了install.bat,!cons_nt.bat,run.bat來安裝和運行系統,后
來又介紹了make.exe,實在是神器,(之前還不解為什么在Linux下編譯包需要make install,現在終於知道了),只需要構造一個不帶擴展名的MakeFile文件,就可以集編譯寫入運行於一身,MakeFile 的基本格式如下:
宏定義 源文件之間的相互依賴關系
任意可執行的Shell命令
作者在這里貿貿然地給出了
1 helloos.img : ipl.bin Makefile 2 ../z_tools/edimg.exe imgin:../z_tools/fdimg0at.tek \ 3 wbinimg src:ipl.bin len:512 from:0 to:0 imgout:helloos.img
先通過nask 生成bin文件再用edimg.exe 轉為img文件,我不知道為什么要這么做,而且生成 .lst 文件的時候也失敗了。
作者給出的makefile中地址都是斜杠,而系統用的是反斜杠,雖然效果一樣,但是看着不爽,vim ":1,$/\//\\/g"可以將所有斜杠轉化為反斜杠,注意這里的\有的是用來做轉義的。
於是我沒有照着他那樣,我的MakeFile改寫如下,同樣正常工作:
1 # nask.exe ipl.asm a.img ipl.lst ::fail NASK: LSTBUF is no enough 2 3 default : 4 tolset\z_tools\make.exe install 5 tolset\z_tools\make.exe run 6 del *.*~ >nul ::刪除臨時文件 7 del *~ >nul 8 9 10 a.img : ipl.asm Makefile 11 tolset\z_tools\nask.exe ipl.asm a.img::直接編譯成img,不知作者的用意是什么 12 13 install : 14 tolset\z_tools\make.exe -r a.img 15 16 run : 17 echo Running... 18 "D:\Program Files\Oracle\VirtualBox\VirtualBox.exe" --comment "OS1" --startvm "a5c4b0e6-e142-4720-98ee-056911204b29" ::虛擬機的快捷方式 19 echo Finished.
另外改寫了!cons_nt.bat,增加了環境變量。
1 @echo off 2 color 0b 3 set PATH=%PATH%;tolset\z_tools\ 4 cmd.exe
之后打開!cons_nt.bat, 輸入make,效果如圖:
- 知識點:
FAT12啟動區的標准:第511個字節開始填充55AA,軟盤大小是2880*512/1024 = 1440 KB;
啟動區的加載地址是 0x7c00—0x7dff;
各種寄存器,只有SI,DI,BX為數不多的幾個寄存器才能放地址;
MakeFile 的用法;
Vim的替換命令;
int 0x10中斷重點是AH=0EH:http://blog.csdn.net/thimin/article/details/2313390。
唉,我真是話嘮。