首页 > 移动平台 > 详细

操作系统开发:BIOS/MBR 引导

时间:2020-07-21 13:11:51      阅读:117      评论:0      收藏:0      [点我收藏+]

BIOS 软件接力第一棒

万丈高楼平地起,BIOS,嗯,太香了,这次复习,我要把笔记做好,开机第一弹,BIOS...

BIOS 基本输入输出系统,BIOS代码所做的工作是一成不变的,所以他是被固化到ROM中的一块只读区域中,在开机时此ROM会被映射到低端1MB内存的顶部,原因是系统在开启时默认是实地址模式(该模式最大寻址范围0-fffff),所以其寻址范围也就被限制在了0xF0000-x0xFFFFF区域中,这64KB的内存就是BIOS的执行代码.

在开机的一瞬间,CPU的CS:IP寄存器会被强制初始化为0xF000:0xFFF0,在实地址模式下该地址需要乘以16也就是左移四位加上偏移地址得到,于是0xF000:0xFFF0就等效于0xFFFF0此处的地址距离0xFFFFF只有16个字节的空间,里面存放着一条jmp far f000:e05b = fe05b的汇编指令,该指令将跳转到真正的BIOS开始的位置.

接着BIOS将会通过自身的代码对硬件进行自检测,在初始化硬件后,则开始向内存0x000-0x3ff中初始化数据结构以及拷贝中断向量表,紧接着BIOS将会通过调用int 19h中断,此中断用以检测计算机中的硬盘,如果检测到0盘0道1扇区末尾的两个字节是0x55,0xaa则认为此扇区确实存在,于是就会将此区域中的内容,加载到内存7c00的位置,并通过一条jmp far 0:0x7c00h的指令跳转到该位置执行,这样BIOS就将CPU控制权交给了MBR了,而BIOS将会再次睡去.

MBR 继续执行任务

此处的7c000就是MBR代码的开始位置,之所以是7C00是因为,DOS中要求最小内存是32KB,而MBR大小必须是512字节(1KB),所以选择32kB中的最后1KB的位置最为合适,32KB(0x8000)-1KB(0x400)=>0x7c00,这就是7C00的由来,同时还需要保证第510-511字节必须为0x55,0xaa才可以.

保存以下汇编代码,并使用 nasm -o mbr.bin mbr.asm编译简易版MBR文件.

SECTION MBR vstart=0x7c00     ; 告诉编译器加载到7c00内存处
	mov ax,cs
	mov ds,ax
	mov es,ax
	mov ss,ax
	mov fs,ax
	mov sp,0x7c00

	mov ax,Message
	mov bp,ax         ; 保存字符串地址
	mov cx,15         ; 保存字符串长度
	mov ax,01301h     ; 子功能号13是显示字符及属性
	mov bx,000ch      ; 页号位0,使用黑色为背景色,红色为字体颜色
	mov dl,0
	int 10h           ; 10h中断,用来显示字符
	ret

Message: db "hello lyshark !"
times 510-($-$$) db 0  ; 填充510字节为0
db 0x55,0xaa           ; mbr的结束标志

进入Bochs目录下执行bximage.exe生成一个映像文件,默认是a.img,并将编译好的mbr.bin写入到镜像中

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

在Bochs目录下新建并编辑bosh.src保存,然后执行bochs.exe -f bosh.src模拟执行MBR代码.

megs:32
romimage:file=$BXSHARE/BIOS-bochs-latest
vgaromimage:file=$BXSHARE/VGABIOS-lgpl-latest
floppya:1_44=a.img,status=inserted
boot:floppy
log:bochsout.txt
mouse:enabled=0
keyboard: keymap=$BXSHARE/keymaps/x11-pc-de.map

技术分享图片

上方屏幕会比较混乱,这里我们先来进行清屏操作,清屏中断调用也是int10

SECTION MBR vstart=0x7c00     ; 告诉编译器加载到7c00内存处
        mov ax,cs
        mov ds,ax
        mov es,ax
        mov ss,ax
        mov fs,ax
        mov sp,0x7c00

        mov ax,0x600      ; 清屏范围,也就是宽度
        mov bx,0x0
        mov cx,0x0        ; 清屏 左上角(0,0)
        mov dx,0x184f     ; 清屏 右下角(80=0x4f,25=0x18)
        int 0x10
        mov ax,Message
        mov bp,ax         ; 保存字符串地址
        mov cx,15         ; 保存字符串长度
        mov ax,01301h     ; 子功能号13是显示字符及属性
        mov bx,000ch      ; 页号位0,使用黑色为背景色,红色为字体颜色
        mov dl,0
        int 10h           ; 调用10h号中断,用来显示字符
        ret

Message: db "hello lyshark !"
times 510-($-$$) db 0  ; 填充510字节为0
db 0x55,0xaa           ; mbr的结束标志

执行结果,如下,但是,打印字符串,在底部,因为光标在底部。

技术分享图片

设置光标到顶部,这里百度一下光标中断,发现了。

技术分享图片

接着改进代码

SECTION MBR vstart=0x7c00     ; 告诉编译器加载到7c00内存处
        mov ax,cs
        mov ds,ax
        mov es,ax
        mov ss,ax
        mov fs,ax
        mov sp,0x7c00

        mov ax,0x600      ; 清屏范围,也就是宽度
        mov bx,0x0
        mov cx,0x0        ; 清屏 左上角(0,0)
        mov dx,0x184f     ; 清屏 右下角(80=0x4f,25=0x18)
        int 0x10
        mov dh,0x0        ; 设置光标列号
        mov dl,0x0        ; 设置光标行号
        mov bh,0x0        ; 页码
        int 0x10
        mov ax,Message
        mov bp,ax         ; 保存字符串地址
        mov cx,15         ; 保存字符串长度
        mov ax,01301h     ; 子功能号13是显示字符及属性
        mov bx,000ch      ; 页号位0,使用黑色为背景色,红色为字体颜色
        mov dl,0
        int 10h           ; 调用10h号中断,用来显示字符
        ret

Message: db "hello lyshark !"
times 510-($-$$) db 0  ; 填充剩余的510字节的空间为0
db 0x55,0xaa           ; mbr的结束标志

完美结果。

技术分享图片

操作系统开发:BIOS/MBR 引导

原文:https://www.cnblogs.com/LyShark/p/13353400.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!