c语言自制驱动程序,自制操作系统10-自已搭建制作工具

在第三篇文章我想用nasm与c来开发我们的操作系统,但当时最终还是用了作者现成的工具做的镜像文件。在学完汇编语言后,再来尝试。

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》下图:

1612b03c50886d19697500229fb31bba.png

这三行调用,就是让显示器清屏幕,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

if(i

fos.write(src[i]);

}else if(i>=0x4200&&i

fos.write(fis2.read());

}else {

fos.write(0);

}

}

fis.close();

fis2.close();

fos.close();

}

}

运行映像文件,可以看到效果与作者的工具生成的文件效果一样。

2.把c语言的机器码放进软盘c语言生成的文件放到映像文件的过程比较复杂,《30天自制操作系统》是这样做的:

97fcc2d2baef9befc4e9a1d18f5ddedb.png

我们现在要做的事,使用通用的开源软件来替换作者提供的cc1,nask等工具.因为这些工具屏蔽了一些操作,且没有文档,不利于我们后面自主开发。当然对于和我一样c语言与汇编开发经验不足的人来说是有些难度。但经过几天的研究,初步实现了这一目标。首先,我们用gcc生成obj2bim.exe与bim2hrb.exe这两文件。这两个文件涉及链接过程,但我们目前不用了解编译原理及其内部细节也能干活。这两个文件用作者提供的源码和MinGW就可以正常的生成,真是太好了。

这里先说明下环境:

win7,64位,MinGW32位,nasm x86安装包。环境变量已配好,可使用gcc,nasm命令。cd 光盘文件/omake/tolsrc/bim2hrb

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

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

效果与第三天的一样:

f980d040780f2a582cf4014dc78ab4ff.png

现在文件已经不少了,可以用make管理起来了,我们用之前介绍的gnumake来打包。

把文件整理一下,工具放进tools文件夹,生成的文件放到bin文件夹:

d69e41c18e23d94e88df245479498731.png

写如下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

下面用图总结一下,我们改造工具的方法,有颜色的代表对作者的工具还有依赖的步骤:

cb44eb51c088fe265918af226d041d52.png

改造的这几天,都是摸着石头过河,说不定那一步就搞不定了。还好,其本都完成了。

这几天踩了一些坑在这记录下,不要在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相关的源码文件转移一个新文件夹来生成。

  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值