30天自制操作系统——第二天
今天是该系列的第二天,继续昨天的开发,今天的任务主要有以下几项: 1、进一步的加工一下汇编程序(去除昨天的二进制代码) 2、对启动区进行制作 3、利用makefile简化bat文件数量
一、进一步加工汇编程序
这里我使用的是vscode 进行书写汇编程序(也可以使用其他的文本编辑器)。其主要代码(这里与原作者给出的代码相比我进行了自己的加工以及添上了我个人的理解的注释)如下:
;hello-os
;TAB=4
ORG 0x7c00 ;启动程序的装载地址一般为0x7c00~0x7dff
jmp entry
;标准的FAT12格式软盘的必备专用的代码 Stand FAT12 format floppy code,即书写在开头的文件描述系统
DB 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扇区1440*1024/512)
DB 0xf0 ; 磁盘类型(必须为0xf0)
DW 9 ; FAT的长度(必须是9扇区)
DW 18 ; 一个磁道(track)有几个扇区(必须为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字节
;程序主主体
entry:
;将启动区的初始段地址(0000)设置给以及将启动扇区的偏移地址(7c00)进行设置到栈和数据段中
mov ax,0
mov ss,ax
mov sp,0x7c00
mov ds,ax
mov es,ax
mov si,msg
;程序启动后我们想要显示的内容
putloop:
mov al,[si]
add si,1 ; 给SI加1,循环打印
cmp al,0
je fin ;若数据内存该处的值为零,则该程序终止
mov ah,0x0e ; 显示一个文字,调用0x0e号子中断程序
mov bh,0 ;第0页
mov bl,11001010B ; 指定字符颜色
int 0x10 ; 设置中断程序。10h号中断代表显示字符串,调用bios的中断
jmp putloop
fin:
HLT ;cpu停止运行,等待指令,节约资源
jmp fin ; 无限循环
msg:
DB 0x0a, 0x0a ; 换行两次
DB "hello, world"
DB 0x0a
DB "OS made by GXU yuan"
DB 0x0a ; 换行
DB 0
RESB 0x7dfe-$ ; 填写0x00直到0x001fe
DB 0x55, 0xaa ;这里标志着有启动程序,因为计算机一般先读最后两字节进行判断是否含启动程序的!!
ORG 这个指令,意思是告诉计算机再执行时将以下的这些代码装载到内存的哪个地址。
HLT 这个指令,则让cpu停止动作的指令,当然如果有外唤醒,cpu将继续执行的。这里使用这一个指令,就是不想让cpu无意义的空转,浪费资源。
至于中断程序,那就参考第零天里的汇编知识了。当然,我这里利用bl设置了颜色,但是最后结果依旧没有出现色彩,因此我推测可能是在当前这个页面下,不能这么简单的指定色彩吧??
补充一些小知识: 内存当中的第0号地址以及在0xf0000号附件可能都存在着BIOS程序本身,因此我们在开发操作系统的过程中,要注意避免使用这些区域,以免使得系统崩溃。然后,一般来说,会将启动区的内容装载到0x00007c00~0x00007dff 共512字节的内存区域当中(至于为什么是这里,着我也不知道,是之前的大佬们设计之处定下的) 因此,我们前面的汇编程序要使用org定位到7c00的内存地址当中。
好了,这里我加工完毕后(以上的只是包含了软盘中操作系统的启动区),我们接下来开始将这个汇编代码编译连接,然后制作映像文件。
二、制作启动区
这里我们继续利用前面的启动区(512字节)的汇编代码,来启动我们的程序。首先将asm文件里的内容进行修改,以方便我们输出.bin 以及 .list文件。bin是用于我们后续制作光盘的,list是为了给我们看每一步指令产生的对应的机器指令。
asm.bat
..\..\z_tools\nask.exe yuan-hello-os.nas yuan-hello-os.bin yuan-hello-os.list
除此之外,还需要做一个文件makeimg.bat 将bin文件转化为磁盘映像文的:
makeimg.bat:
..\..\z_tools\edimg.exe imgin:../../z_tools/fdimg0at.tek wbinimg src:yuan-hello-os.bin len:512 from:0 to:0 imgout:yuan-hello-os.img
以上需要注意以下相对路径哈!!!
然后在!const打开的cmd中,依次输入:asm->makeimg->run即可。
三、利用makefile
以上呢,我们要使用各种bat文件来进行批处理命令,十分的麻烦,因此为了简化上述的操作,我们利用makefile文件来同一进行处理:
1、建立一个makefile文件(不要后缀);
2、输入以下内容:
img :
../../z_tools/make.exe -r yuan-hello-os.img
asm:
../../z_tools/make.exe -r yuan-hello-os.bin
run:
../../z_tools/make.exe img
copy yuan-hello-os.img ..\..\z_tools\qemu\fdimage0.bin
../../z_tools/make.exe -C ../../z_tools/qemu
install:
../../z_tools/make.exe img
../../z_tools/imgtol.com w a: yuan-hello-os.img
yuan-hello-os.bin : yuan-hello-os.nas Makefile
../../z_tools/nask.exe yuan-hello-os.nas yuan-hello-os.bin yuan-hello-os.list
yuan-hello-os.img : yuan-hello-os.bin Makefile
../../z_tools/edimg.exe imgin:../../z_tools/fdimg0at.tek wbinimg src:yuan-hello-os.bin len:512 from:0 to:0 imgout:yuan-hello-os.img
clean :
-del ipl.bin
-del ipl.lst
src_only :
../z_tools/make.exe clean
-del helloos.img
# 代表注释;
yuan-hello-os.bin : yuan-hello-os.nas Makefile 意思是如果想要制作yuan-hello-os.bin 文件需要先检查是否已经有 yuan-hello-os.nas Makefile这两个文件了,如果有则执行下面的命令! 这里面的yuan-hello-os.bin 这一个则是相当于告诉make.exe程序,我要制作的是这一个程序,然后将要执行这下面的命令了。。因此我们只需在cmd中输入make yuan-hello-os.bin 就会自动执行下面的命令从而生成bin文件。
要注意的一点是:命令与上述的名字即yuan-hello-os.bin:的间距需要输入一个tab键进行空行出来。
3、制作make启动的批处理文件:
make.bat
..\..\z_tools\make.exe %1 %2 %3 %4 %5 %6 %7 %8 %9
这时就已经全部制作完成了,我们只需在!const打开的命令行输入make+对应的名字即可(名字即makefile文件里:前的那串字符)
解释上述命令中的 clean: 是指删除处.img 外的所有中间产生的文件。
**src_only:**是删除源程序以外的文件。
四、给大家展示一下list文件:
也就是说我们写的汇编和我们之前的那些二进制代码其实是语言的,cpu并不会识别我们需要处理的数据,只会傻傻的处理传入的电信号而已。
总结
以上就是Day2的内容,今天进一步的完善了汇编的代码,使得我们极大的减少了二进制的编辑,并且利用了makefile简化了文件的数量(之前的bat可以删掉了)。