这次直接写用boot加载setup模块,
文件系统就先不弄了,以后再说,
咱先整个转简单的加载器,
我把软盘引导改成硬盘了,因为硬盘的读扇区函数简单一些。
这里没有做硬盘的mbr区,我觉得在现在我的这个系统里面,mbr区还不是必须的。
好了,不废话了,贴代码。
这个是bootasm.S的代码:
.globl start
start: # 入口地址
.code16
cld # 字符串运算方向,(具体的,百度吧,基础)
# 初始化各个段寄存器
xorw %ax, %ax
movw %ax, %ds
movw %ax, %es
movw %ax, %ss
movw $start, %sp
# 保存引导驱动器号
movb %dl, (bootdrv)
# 清屏
movw $0x02, %ax
int $0x10
# 显示信息
movw $str, %si
call puts
# 读第二个扇区,到内存的0x80000(0x8000:0x0000)处, 两个扇区
movl $1, %eax # 扇区号
movw $2, %cx # 扇区数
movw $0x8000, %bx # buffer 地址
movw %bx, %es
xorw %bx, %bx
call readdisk
# 跳转到刚刚加载到内存中的SETUP模块
ljmp $0x8000, $0x0000
#
# 字符串显示函数(这个网上不少,自己看着理解吧)
# 输入:
# ds:si = 字符串地址
#
puts:
movw $0x07, %bx
movb $0x0E, %ah
1:
lodsb
orb %al, %al
jz 1f
int $0x10
jmp 1b
1:
ret
#
# 读磁盘扇区(这个是用0x13的0x42号扩展中断,具体的中断参数,自己百度去吧。。。)
#
# 输入: eax = 要读LBA扇区号
# cx = 扇区数(一次读入的字节数不能大于64KB)
# es:bx = 数据缓存区
#
readdisk:
pushal
movb (bootdrv), %dl
pushl $0
pushl %eax
pushw %es
pushw %bx
pushw %cx
pushw $0x0010
movb $0x42, %ah
movw %sp, %si
int $0x13
addw $0x10, %sp
popal
ret
bootdrv: # 这个定义了一个byte型的变量,用来保存当前引导驱动器号
.byte 0
str: # 这个是字符串,昨天看linux源码发现的,
.string "in the boot code\n\r"
然后是setupasm.S的代码
.globl start
start: # 入口地址
.code16
cld # 字符串运算方向,(具体的,百度吧,基础)
# 初始化各个段寄存器
movw %cs, %ax
movw %ax, %ds
movw %ax, %es
movw %ax, %ss
movw $start, %sp
# 显示信息
movw $str, %si
call puts
# 死循环,停机
1:
hlt
jmp 1b
#
# 字符串显示函数
# 输入:
# ds:si = 字符串地址
#
puts:
movw $0x07, %bx
movb $0x0E, %ah
1:
lodsb
orb %al, %al
jz 1f
int $0x10
jmp 1b
1:
ret
str:
.string "in the setup code!!!\n\r"
setup模块现在写的很简单,主要就是用来测试boot的加载代码写的是否正确。。。。下一节会对setup模块进行填充完善,具体做什么功能我想大家也知道了。
就不多说了。。。。。。
具体的构建文件和源码在群里面,我会传上去的。。。。。