自制操作系统10-自已搭建制作工具
在第三篇文章我想用nasm与c来开发我们的操作系统,但当时最终还是用了作者现成的工具做的镜像文件。在学完汇编语言后,再来尝试。
ipl10.nas与第三天的一样:
haribote.nas源码如下:
这个程序就是定位到内存的0xc200,然后显示个黑屏。int 0x10是显示器中断,关于BIOS基本的中断编号与功能,可参考《汇编语言程序设计-从DOS到Windows》下图:
这三行调用,就是让显示器清屏幕,13是模式号。生成目标文件用以下两句命令:
nasm ipl10.asm -o ipl10.bin
nasm haribote.asm -o haribote.bin
然后我们写一个生成镜像文件的java程序,这两个目标文件作为输入:
gcc bim2hrb.c
这样就生成了bim2hrb.exe
cd 光盘文件/omake/tolsrc/obj2bi4d
gcc -c obj2bim.c
gcc -c autodec_.c
gcc obj2bim.o autodec_.o -o obj2bim.exe
这样就生成了obj2bim.exe
然后,我们处理c语言如何编译与链接的问题。作者的做法如上图,都转成了nas,再用他的nask那一套工具来生成。我尝试成功的方案是这样, 先用gcc生成汇编文件,再用as工具(gcc带的)生成目标文件。
还有对汇编文件的编译,对于ipl10与asmhead,直接用以下命令生成最终机器语言文件即可:
nasm asmhead.asm -o asmhead.bin
nasm ipl10.asm -o ipl10.bin
但对于 naskfunc(一个汇编程序文件),因为c语言要调用他的函数,所以不能直接生成机器语言文件。而要先生成目标文件,才能保留里面的函数名等信息。命令如下:
nasm -f coff naskfunc.asm -o naskfunc.obj
文件都准备好了就可以用obj2bim把c语言与汇编文件链接到一起了,命令如下:
obj2bim.exe @光盘文件\tools\haribote\haribote.rul out:bootpack.bim stack:3136k map:bootpack.map bootpack.obj naskfunc.obj
看到这儿有人可能会问haribote.rul是什么?我打开发现是个配置文件,他依赖了两个lib
harilibc.lib与golibc.lib 。这是两静态连接库文件。有人就要说了,你这搞得不彻底啊,怎么还有未知(无源码)文件?其实我是研究过这两文件的生成的,但c语言功底不行,没有搞定。他的生成依赖了cc1等,如果要彻底搞清楚,先得把cc1编译一下,这个c的编译器太麻烦了。对C语言熟悉的同学相信能搞定的。
之后,再用这两工具:
bim2hrb.exe bootpack.bim bootpack.hrb 0
copy /B asmhead.bin+bootpack.hrb haribote.sys
生成haribote.sys文件
最后是把这ipl10.bin与haribote.sys生成为一软盘映像文件,本来我以为可以用上面写的Java工具做这个事。但事与愿违,对比两个img文件,才想起来32位的寻址方式与16位不一样,还要考虑GDT等东西。edimg.exe这个工具生成:
cd 光盘文件/omake/tolsrc/edimg0j
gcc -c autodec_.c
gcc -c edimg.c
gcc edimg.o autodec_.o -o edimg.exe
效果与第三天的一样:
现在文件已经不少了,可以用make管理起来了,我们用之前介绍的gnumake来打包。
把文件整理一下,工具放进tools文件夹,生成的文件放到bin文件夹:
写如下Makefile文件:
改造的这几天,都是摸着石头过河,说不定那一步就搞不定了。还好,其本都完成了。
这几天踩了一些坑在这记录下,不要在linux下或者windows的Cygwin使用gcc生成汇编文件,他们生成的都是linux风格的。后面再在window的nasm下生成obj文件,就不兼容了。
winxp已经安装不了MinGW了,不过可以用安装好的MinGW打个zip包放到xp里运行。可能win7 32位更适合本书相关代码的学习。
gas2nask工具的笔记,本文没用到,只为记录。
这步作者的工具是gas2nask.exe。这个工具比nask.exe的构建要简单些,于是我用作者提供的源码制作一个gas2nask.exe。
首先进入光盘文件\omake\tolsrc\go_0023s\toolstdc,键入命令:cl gas2nask.c就可以生成gas2nask.exe。这个比较简单,可以把gas2nask.c相关的源码文件转移一个新文件夹来生成。
文/程忠 浏览次数:0次 2020-04-24 21:55:42
1.汇编语言的引导程序。
第二天虽然已经实现了用汇编语言编写hello word,但这个显示只是引导区(0扇区),软盘启动都会读取。第三天我们把引导文件拆成了ipl10.nas与haribote.nas。同样今天我们今天还用这两个文件,不过我们编译工具换成nasm,生成映像文件工具改成我们自己用java写的工具。ipl10.nas与第三天的一样:
; haribote-ipl ; TAB=4 CYLS EQU 10 ; 读取到哪里? ORG 0x7c00 ; 这个程序要读取到哪里? ; 以下是标准FAT 12格式软盘的描述 JMP entry DB 0x90 DB "HARIBOTE" ; 可以自由写启动扇区的名字(8字节) DW 512 ; 一个扇区的大小(必须是512) DB 1 ; 集群大小(必须是一个扇区) DW 1 ; FAT从哪里开始(一般从第一扇区开始) DB 2 ; FAT的个数(必须设为2) DW 224 ; 根目录区域的大小(通常为224个条目,FAT里的概念) DW 2880 ; 该驱动器的大小(必须是2880扇区) DB 0xf0 ; 媒体类型(必须为0xf0) DW 9 ; FAT区域的长度(必须是9个扇区) DW 18 ; 每个柱面上有几个扇区(必须要18个扇区) DW 2 ; 头的数量(必须是2) DD 0 ; 因为没有使用分区,所以这里必须是0 DD 2880 ; 再写一次这个驱动器的大小 DB 0,0,0x29 ; 不清楚,最好是这样 DD 0xffffffff ; 可能是卷序列号 DB "HARIBOTEOS " ; 磁盘名称(11字节) DB "FAT12 " ; 格式名称(8字节) RESB 18 ; 总之先空出18个字节 ; 程序主体 entry: MOV AX,0 ; 寄存器初始化 MOV SS,AX MOV SP,0x7c00 MOV DS,AX ; 读磁盘 MOV AX,0x0820 MOV ES,AX MOV CH,0 ; 柱面0 MOV DH,0 ; 磁头0 MOV CL,2 ; 扇区2 readloop: MOV SI,0 ; 计算失败次数的寄存器 retry: MOV AH,0x02 ; AH=0x02 : 磁盘装入 MOV AL,1 ; 1扇区 MOV BX,0 MOV DL,0x00 ; A型驱动器 INT 0x13 ; 磁盘BIOS调用 JNC next ; 如果不发生错误,请向next发送 ADD SI,1 ; 在SI上加1 CMP SI,5 ; 比较SI和5 JAE error ; SI >= 5 那就去error吧 MOV AH,0x00 MOV DL,0x00 ; A型驱动器 INT 0x13 ; 驱动器复位 JMP retry next: MOV AX,ES ; 使地址进0x200 ADD AX,0x0020 MOV ES,AX ; ADD ES,0x020 没有这样的命令,所以这样做 ADD CL,1 ; 在CL上加1 CMP CL,18 ; 比较CL和18 JBE readloop ; CL <= 18 那就去readloop吧 MOV CL,1 ADD DH,1 CMP DH,2 JB readloop ; DH < 2 那就去readloop吧 MOV DH,0 ADD CH,1 CMP CH,CYLS JB readloop ; CH < CYLS 那就去readloop吧 ; 读完了10柱面,开始读haribote.sys MOV [0x0ff0],CH ; 记下IPL读到哪里了 JMP 0xc200 error: MOV SI,msg putloop: MOV AL,[SI] ADD SI,1 ; 在SI上加1 CMP AL,0 JE fin MOV AH,0x0e ; 单字显示功能 MOV BX,15 ; 彩色代码 INT 0x10 ; 视频BIOS调用 JMP putloop fin: HLT ; 让CPU停止,直到发生什么。 JMP fin ; 无限循环 msg: DB 0x0a, 0x0a ; 两个换行符 DB "load error" DB 0x0a ; 改行 DB 0 ;RESB 0x7dfe-$ ; times 510-($-$$) db 0 ; 以0x00填充到0x7dfe为止的命令 DB 0x55, 0xaa
haribote.nas源码如下:
; haribote-os ; TAB=4 ORG 0xc200 ; このプログラムがどこに読み込まれるのか MOV AL,0x13 ; VGA图形,320x200x8 bit颜色 MOV AH,0x00 INT 0x10 fin: HLT JMP fin
这个程序就是定位到内存的0xc200,然后显示个黑屏。int 0x10是显示器中断,关于BIOS基本的中断编号与功能,可参考《汇编语言程序设计-从DOS到Windows》下图:
这三行调用,就是让显示器清屏幕,13是模式号。生成目标文件用以下两句命令:
nasm ipl10.asm -o ipl10.bin
nasm haribote.asm -o haribote.bin
然后我们写一个生成镜像文件的java程序,这两个目标文件作为输入:
package day3; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; public class CreateOSImg3 { public static void main(String[] args) throws Exception { //写入0磁道,从这里加载 FileInputStream fis=new FileInputStream(new File("/Users/chengzhong/work/30_workspace/03_day/cz_work/ipl10.bin")); //写入0x4200,启动区,系统入口 FileInputStream fis2=new FileInputStream(new File("/Users/chengzhong/work/30_workspace/03_day/cz_work/haribote2.bin")); FileOutputStream fos=new FileOutputStream(new File("/Users/chengzhong/work/30_workspace/03_day/cz_work/javaos3.img")); int totalLen=1474560; byte src[]=new byte[fis.available()]; fis.read(src); //总共有1474560个字节, for(int i=0;i<totalLen;i++){ if(i<src.length) { fos.write(src[i]); }else if(i>=0x4200&&i<(0x4200+fis2.available())) { fos.write(fis2.read()); }else { fos.write(0); } } fis.close(); fis2.close(); fos.close(); } }
运行映像文件,可以看到效果与作者的工具生成的文件效果一样。
2.把c语言的机器码放进软盘
我们现在要做的事,使用通用的开源软件来替换作者提供的cc1,nask等工具.因为这些工具屏蔽了一些操作,且没有文档,不利于我们后面自主开发。当然对于和我一样c语言与汇编开发经验不足的人来说是有些难度。但经过几天的研究,初步实现了这一目标。
首先,我们用gcc生成obj2bim.exe与bim2hrb.exe这两文件。这两个文件涉及链接过程,但我们目前不用了解编译原理及其内部细节也能干活。这两个文件用作者提供的源码和MinGW就可以正常的生成,真是太好了。这里先说明下环境:
win7,64位,MinGW32位,nasm x86安装包。环境变量已配好,可使用gcc,nasm命令。
cd 光盘文件/omake/tolsrc/bim2hrbgcc bim2hrb.c
这样就生成了bim2hrb.exe
cd 光盘文件/omake/tolsrc/obj2bi4d
gcc -c obj2bim.c
gcc -c autodec_.c
gcc obj2bim.o autodec_.o -o obj2bim.exe
这样就生成了obj2bim.exe
然后,我们处理c语言如何编译与链接的问题。作者的做法如上图,都转成了nas,再用他的nask那一套工具来生成。我尝试成功的方案是这样, 先用gcc生成汇编文件,再用as工具(gcc带的)生成目标文件。
还有对汇编文件的编译,对于ipl10与asmhead,直接用以下命令生成最终机器语言文件即可:
nasm asmhead.asm -o asmhead.bin
nasm ipl10.asm -o ipl10.bin
但对于 naskfunc(一个汇编程序文件),因为c语言要调用他的函数,所以不能直接生成机器语言文件。而要先生成目标文件,才能保留里面的函数名等信息。命令如下:
nasm -f coff naskfunc.asm -o naskfunc.obj
文件都准备好了就可以用obj2bim把c语言与汇编文件链接到一起了,命令如下:
obj2bim.exe @光盘文件\tools\haribote\haribote.rul out:bootpack.bim stack:3136k map:bootpack.map bootpack.obj naskfunc.obj
看到这儿有人可能会问haribote.rul是什么?我打开发现是个配置文件,他依赖了两个lib
harilibc.lib与golibc.lib 。这是两静态连接库文件。有人就要说了,你这搞得不彻底啊,怎么还有未知(无源码)文件?其实我是研究过这两文件的生成的,但c语言功底不行,没有搞定。他的生成依赖了cc1等,如果要彻底搞清楚,先得把cc1编译一下,这个c的编译器太麻烦了。对C语言熟悉的同学相信能搞定的。
之后,再用这两工具:
bim2hrb.exe bootpack.bim bootpack.hrb 0
copy /B asmhead.bin+bootpack.hrb haribote.sys
生成haribote.sys文件
最后是把这ipl10.bin与haribote.sys生成为一软盘映像文件,本来我以为可以用上面写的Java工具做这个事。但事与愿违,对比两个img文件,才想起来32位的寻址方式与16位不一样,还要考虑GDT等东西。edimg.exe这个工具生成:
cd 光盘文件/omake/tolsrc/edimg0j
gcc -c autodec_.c
gcc -c edimg.c
gcc edimg.o autodec_.o -o edimg.exe
edimg.exe的使用:
edimg.exe imgin:光盘文件/z_tools/fdimg0at.tek wbinimg src:ipl10.bin len:512 from:0 to:0 copy from:haribote.sys to:@: imgout:haribote.img
效果与第三天的一样:
现在文件已经不少了,可以用make管理起来了,我们用之前介绍的gnumake来打包。
把文件整理一下,工具放进tools文件夹,生成的文件放到bin文件夹:
写如下Makefile文件:
default: gcc -S bootpack.c -o bin/bootpack.s as -o bin/bootpack.obj bin/bootpack.s nasm asmhead.asm -o bin/asmhead.bin nasm -f coff naskfunc.asm -o bin/naskfunc.obj nasm ipl10.asm -o bin/ipl10.bin tools/obj2bim.exe @tools\haribote\haribote.rul out:bin/bootpack.bim stack:3136k map:bin/bootpack.map bin/bootpack.obj bin/naskfunc.obj tools/bim2hrb.exe bin/bootpack.bim bin/bootpack.hrb 0 copy /B bin\asmhead.bin+bin\bootpack.hrb bin\haribote.sys tools/edimg.exe imgin:tools/fdimg0at.tek wbinimg src:bin/ipl10.bin len:512 from:0 to:0 copy from:bin/haribote.sys to:@: imgout:bin/haribote.img clean: -del bin\bootpack.s -del bin\bootpack.obj -del bin\asmhead.bin -del bin\naskfunc.obj -del bin\ipl10.bin -del bin\bootpack.bim -del bin\bootpack.map -del bin\bootpack.hrb -del bin\haribote.sys -del bin\haribote.img
下面用图总结一下,我们改造工具的方法,有颜色的代表对作者的工具还有依赖的步骤:
改造的这几天,都是摸着石头过河,说不定那一步就搞不定了。还好,其本都完成了。
这几天踩了一些坑在这记录下,不要在linux下或者windows的Cygwin使用gcc生成汇编文件,他们生成的都是linux风格的。后面再在window的nasm下生成obj文件,就不兼容了。
winxp已经安装不了MinGW了,不过可以用安装好的MinGW打个zip包放到xp里运行。可能win7 32位更适合本书相关代码的学习。
gas2nask工具的笔记,本文没用到,只为记录。
这步作者的工具是gas2nask.exe。这个工具比nask.exe的构建要简单些,于是我用作者提供的源码制作一个gas2nask.exe。
首先进入光盘文件\omake\tolsrc\go_0023s\toolstdc,键入命令:cl gas2nask.c就可以生成gas2nask.exe。这个比较简单,可以把gas2nask.c相关的源码文件转移一个新文件夹来生成。
相关阅读
评论:
↓ 广告开始-头部带绿为生活 ↓
↑ 广告结束-尾部支持多点击 ↑