我是靠谱客的博主 感动哈密瓜,最近开发中收集的这篇文章主要介绍主引导记录MBR ---- 操作系统真相还原书中的MBR源码编译汇编代码启动bochs测试改进MBR--直接与显卡交互改进MBR---直接操作硬盘,从硬盘中加载内核加载器程序,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

书中的MBR源码

SECTION MBR vstart=0x7c00
mov ax,cs
mov ds,ax
mov es,ax
mov ss,ax
mov fs,ax
mov sp,0x7c00
mov ax,0x600
mov bx,0x700
mov cx,0
mov dx,0x184f
int 0x10
mov ah,3
mov bh,0
int 0x10
mov ax,message
mov bp,ax
mov cx,5
mov ax,0x1301
mov bx,0x2
int 0x10
jmp $
message db "1 MBR"
times 510-($-$$) db 0
db 0x55,0xaa 

    这段代码的功能就是打印”1 MBR“在屏幕上。分为初始化特殊寄存器和栈指针,清除屏幕,获取光标位置,打印字符串,填满MBR占的512B剩余空间

编译汇编代码

nasm -o mbr.bin, mbr.S

将编译生成的mbr.bin写入磁盘 

dd if=mbr.bin of=../hd60M.img bs=512 count=1 conv=notrunc

启动bochs测试

bochs -f bochsrc.disk

正常情况下,在控制台输入字符c后,会在显示器上显示 1 MBR信息。

但是遗憾的是,会有很大可能遇到 Messageata0-0couldnotopen hard driveimagefile hd60M.img 错误

解决方法,修改bochsrc.disk 配置文件 

ata0-master: type=disk, path="/usr/local/bochs/hd60M.img", mode=flat, cylinders=121, heads=16, spt=63, translation=auto

增加了translate参数即可

改进MBR--直接与显卡交互

SECTION MBR vstart=0x7c00
mov ax,cs
mov ds,ax
mov es,ax
mov ss,ax
mov fs,ax
mov sp,0x7c00
mov ax,0xb800
mov gs,ax
mov ax,0x600
mov bx,0x700
mov cx,0
mov dx,0x184f
int 0x10
mov byte [gs:0x00],'1'
mov byte [gs:0x01],0xA4
mov byte [gs:0x02],''
mov byte [gs:0x03],0xA4
mov byte [gs:0x04],'M'
mov byte [gs:0x05],0xA4
mov byte [gs:0x06],'B'
mov byte [gs:0x07],0xA4
mov byte [gs:0x08],'R'
mov byte [gs:0x09],0xA4
jmp $
times 510-($-$$) db 0
db 0x55,0xaa

该段代码通过直接往内存空间 0xb8000 - 0xb8009处写入字符‘1 MBR’,这一段内存空间被地址总线映射到显卡的显存

改进MBR---直接操作硬盘,从硬盘中加载内核加载器程序

boot.inc 文件定义了一些boot配置,在这里定义了两个宏LOADER_BASE_ADDR, LOADER_START_SECTOR, 分别表示加载进内存的起始地址和从硬盘读取数据的起始扇区

%include "boot.inc"
SECTION MBR vstart=0x7c00
mov ax,cs
mov ds,ax
mov es,ax
mov ss,ax
mov fs,ax
mov sp,0x7c00
mov ax,0xb800
mov gs,ax
mov ax,0x600
mov bx,0x700
mov cx,0
mov dx,0x184f
int 0x10
mov byte [gs:0x00],'1'
mov byte [gs:0x01],0xA4
mov byte [gs:0x02],''
mov byte [gs:0x03],0xA4
mov byte [gs:0x04],'M'
mov byte [gs:0x05],0xA4
mov byte [gs:0x06],'B'
mov byte [gs:0x07],0xA4
mov byte [gs:0x08],'R'
mov byte [gs:0x09],0xA4
mov eax,LOADER_START_SECTOR
mov bx,LOADER_BASE_ADDR
mov cx,1
call rd_disk_m_16
jmp LOADER_BASE_ADDR
rd_disk_m_16:
mov esi,eax
mov di,cx
mov dx,0x1f2
mov al,cl
out dx,al
mov eax,esi
mov dx,0x1f3
out dx,al
mov cl,8
shr eax,cl
mov dx,0x1f4
out dx,al
shr eax,cl
mov dx,0x1f5
out dx,al
shr eax,cl
and al,0x0f
out dx,al
shr eax,cl
mov dx,0x1f5
out dx,al
shr eax,cl
and al,0x0f
or al,0xe0
mov dx,0x1f6
out dx,al
mov dx,0x1f7
mov al,0x20
out dx,al
not_ready:
nop
in al,dx
and al,0x88
cmp al,0x08
jnz not_ready
mov ax,di
mov dx,256
mul dx
mov cx,ax
mov dx,0x1f0
go_on_read:
in ax,dx
mov [bx],ax
add bx,2
loop go_on_read
ret
times 510-($-$$) db 0
db 0x55,0xaa

上面这段代码,通过写硬盘控制器端口先告诉硬盘控制器,要读取多少个扇区,读起始扇区地址,等待硬盘控制器准备好数据,最后从loader的存储位置读取loader程序加载进内存,并跳转到loader处开始执行,将接力棒交接给内核加载器

boot.inc的内容

LOADER_BASE_ADDR equ 0x900
LOADER_START_SECTOR equ 0x2

下面是loader.S 的定义 

%include "boot.inc"
SECTION loader vstart=LOADER_BASE_ADDR
mov byte [gs:0x00],'2'
mov byte [gs:0x01],0xA4
mov byte [gs:0x02],''
mov byte [gs:0x03],0xA4
mov byte [gs:0x04],'L'
mov byte [gs:0x05],0xA4
mov byte [gs:0x06],'D'
mov byte [gs:0x07],0xA4
mov byte [gs:0x08],'R'
mov byte [gs:0x09],0xA4
jmp $
于此,完成了从MBR到LOADER的接力,开始加载内核。内核加载器中要完成从实模式到保护模式的过渡




最后

以上就是感动哈密瓜为你收集整理的主引导记录MBR ---- 操作系统真相还原书中的MBR源码编译汇编代码启动bochs测试改进MBR--直接与显卡交互改进MBR---直接操作硬盘,从硬盘中加载内核加载器程序的全部内容,希望文章能够帮你解决主引导记录MBR ---- 操作系统真相还原书中的MBR源码编译汇编代码启动bochs测试改进MBR--直接与显卡交互改进MBR---直接操作硬盘,从硬盘中加载内核加载器程序所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(83)

评论列表共有 0 条评论

立即
投稿
返回
顶部