30天自制操作系统吧 关注:1,381贴子:4,808
  • 11回复贴,共1

通用mbr引导

只看楼主收藏回复

看完30天很多人都埋怨,这破东西只能用软盘,而且没有分区,太不实用。下面我自己写了一个引导,给那些想自制操作系统的人参考,不过用的是mbr分区结构。
boot_bz equ 0x7dbe;第一分区项引导标志的内存地址
data_fqsj equ 0x7000;保存主引导分区信息的数据段
org 0x7c00
start:;主引导代码
;获取当前引导设备的设备号
mov byte [data_fqsj+4],dl
;获取第一分区项引导标志的地址 [ds:di]
mov bx, boot_bz
mov ch, 1
pd_boot:
cmp ch, 4
jg boot_error;如果没找到主引导分区就抱引导错误
mov di, bx
mov ax, 0x00
mov ds, ax
;判断是否是引导扇区
mov ah, byte [ds:di]
cmp ah, 0x80
je boot_fq;如果是引导分区则引导
jne fq_add;如果不是引导分区则判断下一个分区
jmp boot_error
fq_add:;获取下一个分区项引导标志的内存地址
add bx, 16
add ch, 1
jmp pd_boot
boot_fq:;进入引导,得到了ch存储的是主引导分区的分区项,bx主引导扇区分区项的所在地址
call fqxx;获取分区信息
call hq_xx;获取其他信息
call read;读取分区的第一扇区
jmp 0x00:0x7e00;进入分区引导
read:;读取分区的第一扇区
push ax
push bx
push cx
push dx
push es
push ds
mov ax, 0x07e0
mov es, ax
mov ax, 0x00
mov ds, ax
mov ch, byte [ds:data_fqsj+2]
mov dh, byte [ds:data_fqsj]
mov cl, byte [ds:data_fqsj+1]
mov ah, 0x02
mov al, 1
mov bx, 0x00
mov dl, byte [ds:data_fqsj+4]
int 0x13
pop ds
pop es
pop dx
pop cx
pop bx
pop ax
ret
boot_error:;引导错误
mov ax, 0xb800
mov ds, ax
mov byte [ds:0x00], 'E'
mov byte [ds:0x01], 0x07
mov byte [ds:0x02], 'r'
mov byte [ds:0x03], 0x07
mov byte [ds:0x04], 'r'
mov byte [ds:0x05], 0x07
mov byte [ds:0x06], 'o'
mov byte [ds:0x07], 0x07
mov byte [ds:0x08], 'r'
mov byte [ds:0x09], 0x07
jmp boot_error
fqxx:;读取分区信息
push ax
push bx
push cx
push dx
;段寄存器初始化
mov ax, 0x00
mov ds, ax
;得到分区的起始位置磁头
add bx, 1
mov dl, byte [ds:bx]
mov byte [ds:data_fqsj], dl
;得到分区的起始位置扇区
add bx, 1
mov dl, byte [ds:bx]
mov byte [ds:data_fqsj+1], dl
;得到分区的起始位置柱面
add bx, 1
mov dl, byte [ds:bx]
mov byte [ds:data_fqsj+2], dl
pop dx
pop cx
pop bx
pop ax
ret
hq_xx:;获取其他信息
ret
;mbr分区表
times 446-($-$$) db 0
;第一分区项
db 0x00
db 0x00, 0x00, 0x00
db 0x00
db 0x00, 0x00, 0x00
db 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0x00, 0x00
;第二分区项
db 0x80
db 0x00, 0x07, 0x00
db 0xff
db 0x01, 0xff, 0xff
db 0x00, 0x00, 0x00, 0x06
db 0x00, 0x00, 0xfb, 0xbb
;第三分区项
db 0x00
db 0x00, 0x00, 0x00
db 0x00
db 0x02, 0x00, 0x00
db 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0x00, 0x00
;第四分区项
db 0x02
db 0x05, 0x01, 0x02
db 0x02
db 0x02, 0x01, 0x00
db 0x02, 0x02, 0xfc, 0x05
db 0x02, 0x01, 0xf7, 0x82
;引导扇区有效标志
times 510-($-$$) db 0
db 0x55, 0xaa
之前测试成功,不过后来完善功能修改一下,没有测试,如果有人测试出错误请指出
这个引导可以引导BIOS能支持的所有设备,而且自动检测当前引导设备,有分区功能(虽然是mbr结构),原理有空我在下面回复,先吃饭了。


IP属地:辽宁1楼2016-10-22 11:02回复
    这是一个主引导记录的代码,作用就是检查可引导分区,并把可引导分区的第一扇区加载到内存,然后执行
    检查引导当前引导设备的主要代码就是第一句,保存dl,因为BIOS在加载可引导设备的第一扇区的时候,吧设备号存储在了dl,之后我们一开始就保存dl,然后加载其他扇区的时候就用保存的设备号去加载。


    IP属地:辽宁2楼2016-10-22 11:09
    回复


      IP属地:广东来自Android客户端3楼2016-10-23 13:20
      收起回复
        那如何吧这本书中的系统用mbr引导呢


        5楼2017-02-07 11:19
        收起回复
          能不能再详细的注释一下代码,我有些地方还是看不懂
          谢谢


          6楼2017-02-07 11:22
          回复
            找到了我试试


            IP属地:北京来自Android客户端7楼2017-03-10 15:40
            回复
              先谢谢


              IP属地:北京来自Android客户端8楼2017-03-10 15:41
              回复