其他分享
首页 > 其他分享> > Gos ——BIOS与继承者MBR

Gos ——BIOS与继承者MBR

作者:互联网

文章目录

写在前面:自制操作系统Gos 第二章第二篇:主要内容是CPU中权力的移交,如何控制BIOS和MBR

BIOS

有过操作系统基础的同学都知道,当操作系统通电之后,会先加载BIOS,之后BIOS将会加载操作系统。说起来这个过程好像很简单一样,但是其实其中有很多细节是我们并不了解的,而这些细节正式掌握操作系统的屠龙技。

什么是BIOS

BIOS的全程是Base Input Output System,即基本输入输入系统。可以看到有这么几个关键词哈:基本、输入输出、系统。

不禁有这么几个疑问了:

我们先来看基本的意思哈。

8086的实模式内存布局 重点!!!

在Intel 8086中总共有20根地址,那么其实CPU可以访问到的地址范围也就是220 = 1M的范围。而这宝贵的1M空间又被划分为以下区域:

起始结束大小用途
FFFF0FFFFF16BBIOS的入口地址,此处的内容主要是jmp f000:e05b
F0000FFFEF64KB-16BBIOS的其他地址
C8000EFFFF160KB映射硬件适配器ROM或者内存映射 I/O
C0000C7FFF32KB显示适配器BIOS
B8000BFFFF32KB用于文本模式显示适配器
B0000B7FFF32KB用于黑白显示适配器
A0000AFFFF64KB用于彩色显示适配器
9FC009FFFF1KBEBDA扩展BIOS数据区
7E007DFF512BMBR加载区
5004FF256BBIOS数据区
0003FF1KB中断向量表

这个表很重要,它相当于我们屠龙技的剑谱,如何屠龙都得依着他来。

我们看一开始的0xFFFF0 ~ 0xFFFFF 这段区域,这64KB内存是ROM,里面存储的就是BIOS代码。BIOS的主要工作就是检测、初始化硬件。这个过程放大来看就是BIOS调用硬件驱动提供的硬件驱动函数。除此之外,BIOS做的另一件事情就是初始化中断向量表,这样就可以通过 int 中断号这个汇编指令来调用中断函数了。

而为什么称之为基本输入输出呢,因为BIOS是工作在实模式下面的,其不用做所有工作,只用完成基本的初始化工作就好了,真正广阔的星辰大海在保护模式呢!

BIOS启动

从我们整篇文章的开头我们知道,BIOS可以说是整个计算机第一个启动的软件了,那么它又是被谁启动的呢?是自举么?

其实是硬件啦。实模式下x86的CPU通过段基址寄存器cs和段偏移寄存器ip来实现对内存的访问。在开机的一瞬间,CPU的cs:ip便被初始化为0xF000:0xFFF0,此地址便是BIOS的入口地址。


在x86模式下面有个约定,为了让16位的寄存器能够访问20位大小的内存空间,需要段基地址左移4位,那么这里0xF000:0xFFF0其实等价于0xFFFF0

之后,BIOS执行指令jmp f000:e05b,跳转到BIOS真正开始执行的地方。之后BIOS就开始检测内存、显卡等外设信息,当检测通过的时候并初始化硬件之后,BIOS会在0x000~0x3FF处建立中断向量表并填写中断例程。

MBR

当BIOS初始化成功之后,他就完成了他的工作。之后他就会把权力交给MBR。他是我们能够掌控的第一个程序。

什么是MBR

MBR即Main Boot Record,它位于整个硬盘最开始的扇区,即0盘0道1扇区,这扇区便被成为MBR引导扇区。而这个引导扇区的内容如下:

:
关于权力是怎么交接的,则是BIOS做完工作之后,从磁盘的一开始检测0x550xaa这两个标记,当检测到了,他就认为这个是继任者MBR。
之后呢,BIOS将这512字节加载到0x7c00这个位置,然后jmp过去,这样就完成了权力的交接工作了,开始执行MBR中的代码了。

MBR的内容

终于到硬菜了,我们开始掌控操作系统了,从我们的MBR程序开始。以下代码是程序的内容,看不懂评论区留言。

;主引导程序
SECTION MBR vstart=0x7c00
    mov ax,cs           ;用cs寄存器去初始化其他寄存器
    mov ds,ax
    mov es,ax
    mov ss,ax
    mov fs,ax
    mov sp,0x7c00       ;初始化栈指针

; 清屏利用0x06号功能,上卷全部行,进行清屏
; int 0x10  功能号:0x60    功能描述:上卷窗口
; 输入:
; AH 功能号: 0x06
; AL = 上卷的行数(0代表全部)
; BH = 上卷的行属性
; (CL,CH) = 窗口左上角(x,y) 的位置
; (DL,DH) = 窗口右下角(x,y)的位置
; 无返回值!
    mov ax,0x600
    mov bx,0x700
    mov cx,0        ;左上角(0,0)
    mov dx,0x184f   ;右下角(80,25)
                    ;VAG文本模式中,一行只能容纳80个字符,总共25行
                    ;下标从0开始,所以0x18=24,0x4f=79
    int 0x10        ;系统调用号10

;下面三行汇编代码获取光标位置
; .get_cursor获取当前光标的位置,在光标位置处打印字符
    mov ah,3        ;输入:3号的子功能是获取光标位置,需要存入ah寄存器
    mov bh,0        ;bh寄存器存储的是待获取光标的页号

    int 0x10        ;输出:ch=光标开始行,cl=光标结束行
                    ;dh=光标所在行号,dl=光标所在列号

;打印字符串
;还是10h中断,不过这次调用13号子功能打印字符串
    mov ax,message
    mov bp,ax       ;es:bp 为串的首地址,es此时同cs一致,开头时已经为sreg初始化

;光标位置要用到寄存器dx中内容,cs中的光标位置可以忽略
    mov cx,12        ;cx为串长度,不包括结束符0的字符个数
    mov ax,0x1301   ;子功能号13是现实字符及属性,要存入ah寄存器
                    ;al设置写字符方式al=01:显示字符串,光标跟随移动
    mov bx,0x2      ;bh存储要显示的页号,此处是第0页
                    ;bl中是字符属性,属性黑底绿字(bl=02h)
    int 0x10        ;执行BIOS 0x10号中断

;程序悬停至此处
    jmp $

    message db "hello,world!"
    times 510-($-$$) db 0		;扩充成510字节
    db 0x55,0xaa

之后,我们调用nasm编译这段汇编代码:

# 编译命令
nasm -o mbr.bin mbr.S

然后使用dd工具将其写入我们之前创建的hd60M.img这个磁盘的第一个扇区中:

# 生成的可执行文件写入 hd60M.img 这个虚拟硬盘的 0盘 0道 1扇区中
# 记得 of后面换成自己的 bochs地址
sudo dd if=/home/ik/workspace/mbr.bin of=/bochs/bo_tmp/bin/hd60M.img bs=512 count=1 conv=notrunc

之后转到自己安装bochs的地方,执行以下命令运行,我们看一下结果:
在这里插入图片描述

参考文献

[1] 深入理解计算机系统
[2] 操作系统真相还原

标签:寄存器,mov,BIOS,Gos,MBR,ax,光标
来源: https://blog.csdn.net/shenmingxueIT/article/details/120513938