序
终于开启了学习自制操作系统的道路,虽然对于笔者来说是一个无比巨大的挑战,但是为了能够打开操作系统这个黑盒子,做一个操作系统应该是最好的方式,讲道理做一个OS应该是很多程序员、工程师的梦想吧,毕竟OS是我们天天都在用的东西,自己能够完全从0开始做一个应该会有不一般地体验。
本系列文章用于记录笔者在阅读书籍并着手开发过程中遇到的各种问题。
1. 先动手操作
刚开始就面临了不小地挑战,虽然是简简单单地按照书本上的图片输入相应的内容,不过还真是 Easier said than done,说起来简单做起来难,在动手敲数据的过程中有敲错的情况,还遇到了软件的使用问题:
再次打开时死活不让改只读模式,按照书本的指示做了几次也失败了,无奈之下只能重新再编一次,第二次有经验了敲得很仔细,敲完之后还一一对照完才肯罢休。
↑这满屏的元素真是麻脑壳QWQ
接着是打开光盘文件,当然了因为用的是pdf的缘故,只好从网上找资源(感谢这位大哥的文件~):
30天自制操作系统光盘
按照书本一番操作,完成下列文件地修改以及拷贝:
输入 install 指令后遇到的问题。
很遗憾,看起来好像因为系统的原因不能够直接将OS安装到磁盘中,正当笔者抱怨时看到了后面的这些内容:
原来可以用模拟器哇,不错奥,针不辍!
↑成功运行~~~
2.究竟做了什么
这里编者用了大量的篇幅向读者说明了一件事情:
CPU是个只能处理电信号的呆瓜,但是智慧的人类通过将电信号(On Off)与数字01联系起来,最后变成了数字计算机的重要组成部分。
3.初次体验汇编程序
在这里编者用汇编程序替换了之前直接用二进制编辑器做好的光盘映像文件 helloos.img:
db(DB) 指令是 “define byte” :用于定义字节型数据,往文件里直接写入1个字节的指令。
RESB指令是"reserve byte"的缩写,RESB 10,意为预定了这10个字节(可以想象成在对号入座的火车里,预订了10个连号座位的情形)。它不仅仅是把指定的地址空出来,它还会在空出来的地址上自动填入0x00(数字前面加上0x,就成了十六进制数,不加0x,就表示十进制数)。
4.加工润色
这一部分将前面的那些看不懂的汇编代码加工成了常见汇编程序的样式:(原文档是日语,这里笔者照着书本的翻译转换过来了)
; hello-os
; TAB=4
; 以下这段是标准FAT12格式软盘专用的代码
DB 0xeb, 0x4e, 0x90
DB "HELLOIPL" ; 启动区的名称可以是任意的字符串(8字节)
DW 512 ; 每个扇区(sector)的大小(必须为512字节)
DB 1 ; 簇(cluster)的大小(必须要为1个扇区)
DW 1 ; FAT的起始位置(一般从第一个扇区开始)
DB 2 ; FAT的个数(必须为2)
DW 224 ; 根目录的大小(一般设成224项)
DW 2880 ; 该磁盘的大小(必须是2880扇区)
DB 0xf0 ; 磁盘的种类(必须是0xf0)
DW 9 ; FAT的长度(必须是9扇区)
DW 18 ; 1个磁道(track)有几个扇区(必须是18)
DW 2 ; 磁头数(必须为2)
DD 0 ; 不使用分区(必须是2)
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 ; 两个换行
DB "hello, world"
DB 0x0a ; 换行
DB 0
RESB 0x1fe-$ ; 填写0x00,直到 0x001fe
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
比较重要的内容是 RESB 0x1fe-$,这个美元符号是一个变量,表示该指令这一行现在的字节数(严格来说,它有时候还有别的意思,作者将其放在了后序章节中)。
在这个程序中,我们已经在前面输出了132个字节:这里可以根据数据类型以及数量计算出来:
- db: define byte,字节型数据(每个占1字节)
- dw: define word, 字型数据(每个占2字节)
- dd: define double word, 双字型数据(每个占4字节)
所以这里 $ 就是132 字节,因此nask先用0x1fe减去132:1fe即510,510 - 132 = 378,得出378这一结果,然后连续输出378个字节的0x00。
修改显示内容
将运行初始界面上的字符串修改为了 “hello, bin’OS”,如下图:
随后,双击 asm.bat 重新载入helloos.img文件,最后双击 run.bat 即可看到修改后的效果:
感受
通过了好几回手敲二进制算是体会到了做工程需要的一种特质:严谨(在编写二进制文件时一直犯些小错误,写了三四回才通过)。
不论多么简单的东西,自己动手尝试了才算是真正将其攻克了。
就像是作者所言:
可能有些人嫌麻烦,懒得自己输入,上来就直接使用光盘里的 helloos.img 文件,不是不可以,但笔者认为这种体验(一点一点输入,再千辛万苦地纠错,最终功夫不负有心人取得成功)本身更难能可贵。