不知道是否很多人跟我一样,在学习《自己动手写操作系统》 一书时,会有疑问为何需要FAT文件系统,弄个无格式的二进制不行吗?所以我又查看了《一个64位操作系统的设计与实现》 也是如此实现,就觉得是不是绕不过去这道坎了,准备好好看看fat格式elf格式,看着看着突然有了感觉,就自己动手跳过去。目前看是成功了,所以分享给大家。
首先写好内核加载程序。想读几个扇区读几个,第一个扇区bios自己读入内存了。其他的loader部分和内核部分就用这个读入。
;-----------------------------------------------------------------
;读入n个扇区到内存开始内核之旅
;输入:读扇区存入es:bx
;输出:
;-----------------------------------------------------------------
funReadFloppySector:
MOV DL,0 ; A驱动器
MOV CH,0 ; 柱面 0
MOV DH,0 ; 磁头 0
MOV CL,2 ; 扇区 2
MOV AH,0x02 ; 0x02 读磁盘
MOV AL,9 ; 读9个扇区
INT 0x13 ; BIOS 读磁盘功能
;JNC next ; 成功跳转
ret
读入以后,loader部分做一些,检测内存大小、设置显示模式,进入保护模式、开启分页等工作。再跳转到内核,内核大部分用c语言,在linux环境下编译的,出来的格式elf的,我试过各种办法,很难把elf格式提取成,类似nasm 汇编用-o 编译出来的无格式的纯的二进制文件,所以提取纯二进制这个我放弃了,objcopy试过,搜了很多方法要么提前不全,要么提取出来的还是含有一堆空洞。就用elf了,但是我们可以在链接阶段,将所有的代码段合并,如下:
.text :
{
_text = .;
*(.text)
_etext = .;
}
. = ALIGN(4);
.data :
{
_data = .;
*(.data)
_edata = .;
}
.bss :
{
_bss = .;
*(.bss)
_ebss = .;
}
再指定代码段的偏移位置:
ld -xx -xx -Ttext 0x10400,比如你想把内核加载到0x1100的位置就写0x1100
从loader跳转到内核时就是用一个长跳转:
jmp 1000h:400h
进入内核,搞定!!!
哈哈,这个在网上算得上是我首创了,至少目前我是没找到相关的内容。(也许是坐井观天)
不过也是初步不成熟想法,如有大神看到,有什么不对的请大神斧正。
差点忘了,我目前将loader+内核拼接是使用HxD二进制直接复制粘贴的,可以用C语言写个拼接工具,但是目前文件不大,可以简单粗暴点,复制粘贴到引导扇区512字节后面,即55AA后面。
用bochs自带的bximage制作个软盘,1.44MB那种,再网上下载dd软盘写入工作,在cmd中dd if=c:\312.bin of=xxx.img bs=512(扇区字节数 )count=xx(需要写入的扇区数量) conv=notrunc即可