来吧。第三天。
制作真正的IPL:
作者又是那样,一上来就甩一堆代码,用他的话猜测,下面这段代码应该是用来装载下一个512字节的内容的。
MOV AX,0x0820 MOV ES,AX MOV CH,0 ; 柱面0 MOV DH,0 ; 磁头0 MOV CL,2 ; 扇区2 MOV AH,0x02 ; AH=0x02 : 读盘 MOV AL,1 ; 1个扇区 MOV BX,0 MOV DL,0x00 ; A驱动器 INT 0x13 ; 调用磁盘bios JC error
好吧,作者在代码后面稍微解释了一下:
调用了13号中断,mov入ch,dh等寄存器的数据原来就是这个个断函数需要传递进入的参数。
那么什么是扇区,什么是柱头呢? 看图吧!
含有IPL的启动区,位于C0-H0-S1(柱面0,磁头0,扇区1),下一个扇区是C0-H0-S2
所以上面那段程序就是装载这个扇区。
既然读取了数据,那就要放到内存里啊,否则读取出来有什么用?但是我们怎么指定放入哪里呢?其实这个地址已经指明了。 ES:BX 就是要载入的地址。也就是0x8200-0x83ff
但是为什么不放入0x8000呢,作者说是留给启动区的(启动区不是7c00-7dff吗?什么鬼!)
作者又添加了循环写入的代码。
利用bios程序错误时在flags里返回的数据。
看注释吧。。
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 fin ;如果没有出错就跳转到next ADD SI,1 ;错误次数加一 CMP SI,5 ;和5对比 JAE error ;大于等于5就跳转 MOV AH,0x00 ;这一句不懂 MOV DL,0X00 INT 0X13 JMP retry
Omg,这一章难道全是汇编代码了吗?
作者一鼓作气读了10个柱头。
总于开始着手操作系统的开发了吗?
Fin:
HTL
JMP fin
什么,,难道这只是一个只会待机的操作系统???
但是怎么运行他呢?
让我们来看看makefile里面的修改吧:
haribote.img : ipl.bin haribote.sys Makefile
$(EDIMG) imgin:../z_tools/fdimg0at.tek
wbinimg src:ipl.bin len:512 from:0 to:0
copy from:haribote.sys to:@:
imgout:haribote.img
其中haribote.sys就是 haribote.nas经过nask编译后的文件。
虽然不是很懂makefile里面的这些代码,但应该就是将系统保存到了我们的img磁盘映像里了。
或许这样太抽象那就理解为这样好了:
我将磁盘映像写入到了硬盘了。然后将haribote.sys复制到硬盘里了,然后我又把硬盘做成了硬盘镜像。
作者说 0x002600保存的是文件名
0x002400保存的是文件内容。那就相信他吧。
那么启动这个操作系统就简单了。
我们根据计算,磁盘上的内容加载到0x8000那么磁盘0x4200处就对应着内存里的0xc200.
但是我又不懂了。
不是只需要在IPL里jmp一下就好了吗?
为什么又来个ORG 0xc200??
好吧,博主表示搞不懂这里。
索性不管它了。
作者自称现在程序的前半部分是用汇编写的,后半部分是C语言写的。
所以啊,又来了一次大跳跃,扔给我们一个 asmhead.nas
这到底是什么鬼。
不管了,先来看看C语言这个部分吧。
那么C语言怎么变成机器语言呢?
好麻烦。。。。。还好他把一系列过程写到了makefile里面。
体系结构好像有点复杂啊。博主盗了一张图:
好像放着naskfunc不讲,有点过不去啊,其实就是有些东西C语言实现不了,使用汇编写,然后编译的时候,把naskfunc链接到一起。
;naskfunc
;TAB=4
[FORMAT "WCOFF"] ;制作目标文件的模式
[BITS 32] ;制作32位模式用的机械语言
;制作目标文件的信息
[FILE "naskfunc.nas"] ;源文件名信息
GLOBAL _io_hlt;程序中包含的函数名 想在C语言中使用必须用global声明
;以下是实际的函数
[SECTION .text] ;目标文件中写了这些之后再写程序
_io_hlt: ;void io_hlt(void); 要用_开头
HLT
RET