30天自制操作系统(第01天)

来源:互联网 发布:用js做九九乘法表 编辑:程序博客网 时间:2024/06/08 03:12

第一天开始就正式制作操作系统了。

计算机运行的原理

计算机实质上只接受二进制的指令。由0和1拼凑成的一长串数字传送给CPU之后,CPU就会进行识别,然后逐个执行。
操作系统的运行也是如此,在开启的时候,CPU从存储数据中读取指令,然后执行。因而,只要有合适的指令存储在硬盘中,在启动的时候
CPU读取后依次执行即可。
所以一开始,书中让你在二进制编辑器中输入一大段数据,然后通过QEMU模拟就可以在屏幕中打印出Hello World。
第一个系统启动画面

汇编语言

其实在生成的那个IMG文件中(即二进制编辑器输入的数据),都是CPU相关的一些指令。但这些指令都是二进制(或十六进制)数字晦涩难
懂,也不便于记忆。因而,我们采用汇编语言,将这些指令用一些单词表示。在第一天中,我们学会了4个基本的指令:
- DB
Data Byte,也就是写一个字节的数据。
DB可以写文本,十六进制数,十进制数。如果有多个值要写,可以用逗号隔开。
- DW。
Data Word,Word在计算机里面是一个双字节的数据。
- DD。
Data Double-Word,双Word数据,也就是4个字节。
- RESB。
Reserve Byte,保留一个字节的空数据。

完整的汇编程序

完整程序如下:

; 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          ; 因为不使用分区,所以必须是0,4字?    DD 2880       ; 重写一次磁盘大小,4字节    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!Beauty!"    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

别惊奇这段程序,其实它也只是把之前用二进制编码输入的内容,用汇编语言再次输出一遍而已。本段程序也是加入了一些注释,说明了每段代码的含义。
可以看到,这里大多数都是在固定的位置写入固定的东西,这些内容都是事先定义好的,我们也不好多变。唯一没有解释的是程序主体那部分,会在后面几天详细解释。
这里需要指出的是0x1fe-$,这里的$符号是一个变量,表示当前所在的位置,0x1fe-$就是0x1fe这个地址的位置减去当前位置,也就是在这段区域里面用RESB指令进行填补空白的操作。

系统模拟

对于汇编语言编写的程序而言,需要多一个步骤。就是首先要编译这段程序,将其变为二进制代码,也就是变为之前用二进制编辑器所编写的那个文件。这里用了作者所写的一个nask.exe将这段程序编译,其实就是执行,这里的所有操作都是写数据,也就是执行后将这些数据写入一个文件。代码如下:

..\z_tools\nask.exe helloos.nas helloos.img

然后使用了一个QEMU的模拟软件将该文件进行加载,模拟了自己编写的系统的启动。代码如下:

copy helloos.img ..\z_tools\qemu\fdimage0.bin..\z_tools\make.exe -C ../z_tools/qemu

然后细心的你一定发现这个系统启动后与之前的有所不同。