操作系统加电的瞬间发生了什么
在开机的一瞬间,cpu的cs:ip寄存器会被强制初始化为0xF000:0xFFF0。并且此时cpu处于实模式,故它会运行地址为0xFFFF0处的程序。
实模式下的内存布局
由这张图可以看出来0xFFFF0处存放的是BIOS的代码,并且大小仅仅16B,同时我们也知道BIOS不仅要初始化、检测硬件,还要建立中断向量表,所以此处应该是存放的是一条跳转指令,跳到了BIOS代码真正开始的地方。
BIOS的工作:
①初始化、检测硬件
②建立中断向量表等
③校验启动盘中位于0盘0道1扇区的内容(CHS方法,扇区从1开始),看这个扇区的最后两个数是不是0x55和0xaa
④如果检测最后两个字节是0x55和0xaa,BIOS认为这里存在可执行程序(mbr),就加载到地址0x7c00处,然后跳转到此处,继续执行
1.为什么是0盘0道1扇区?
这个规定,作者的理解是mbr是主引导程序,如果不事先告诉BIOS mbr位于哪里,BIOS会花费时间去检测mbr,而0盘0道1扇区是磁盘的第一个扇区(CHS方法),也是BIOS第一个检测的扇区,如果mbr存放在这里,就能很快找到mbr,然后BIOS就可以把接力棒交给mbr了
为什么是0x7c00这个地址?
mbr的任务是加载内核加载器loader,由loader加载操作系统到指定位置,然后执行加载过来的操作系统。mbr大小为512B,并且最后俩字节为0x55和0xaa。首先,DOS1.0要求的最小内存为32KB,其次mbr大小512B,在为mbr所用的栈分配空间,估计1KB够用,最后mbr要留出足够多的空间,防止自己被破坏,因此放在32KB的最后1KB,即32KB-1KB=0x7c00
编写mbr.S
代码功能
显示myos 1 MBR 的字符在屏幕上
原理
代码逻辑:
①初始化各寄存器的值
②使用bios中断先清屏(06号子功能)
③再获取光标位置(3号子功能)
④再在光标位置打印字符串(13号子功能)
注:该代码一共512字节,且最后两个字节为0x55和0xaa
完成编译后 使用dd命令将该程序写入0盘0道1扇区
参考的BIOS中断
BIOS中断使用用法:https://blog.csdn.net/MENGmei0219/article/details/126785698
编译环境
nasm:sudo apt install nasm
语法:nasm -o mbr mbr.S
dd命令
if=FILE 要读取FILE
of=FILE 把数据输出到FILE
bs 指定块大小
count指定块数
seek指定跳过的块数
conv转换文件方式,追加数据的时候选择不转换
写入0盘0道一扇区的命令:dd if=/home/xxx/Desktop/myos/boot/mbr of=/home/xxx/Desktop/mybochs/hd60M.img bs=512 count=1 conv=notrunc
参考代码
;主引导程序 mbr
;初始化各寄存器值
SECTION MBR vstart=0x7c00
mov ax,cs
mov ss,ax
mov ds,ax
mov es,ax
mov fs,ax
mov sp,0x7c00
;清屏
;输入:
;AH 功能号= 0x06
;AL = 上卷的行数(如果为 0,表示全部)
;BH = 上卷行属性
;(CL,CH) = 窗口左上角的(X,Y)位置
;(DL,DH) = 窗口右下角的(X,Y)位置
;无返回值:
mov ax,0x0600
mov bx,0x700
mov cx,0
mov dx,0x184f
int 0x10
;获取光标位置
;输入: 3 号子功能是获取光标位置,需要存入 ah 寄存器
;bh 寄存器存储的是待获取光标的页号
输出: ch=光标开始行,cl=光标结束 dh=光标所在行号,dl=光标所在列号
mov ah,0x3
mov bh,0
int 0x10
;在光标位置打印字符串
;子功能号 13 显示字符及属性,要存入 ah 寄存器,al 设置写字符方式 ah=01: 显示字符串,光标跟随移动
;bh 存储要显示的页号,此处是第 0 页,bl 中是字符属性,属性黑底绿字(bl = 02h)
;ES:BP=显示字符串的地址
mov ax,message
mov bp,ax
mov ax,0x1301
mov bx,0x2
mov cx,10
int 0x10
jmp $
message db "myos 1 MBR"
;$是指的本行的地址,隐含存在,$$ 是本section的地址
times 510-($-$$) db 0
db 0x55,0xaa
编译并写入磁盘
nasm -o mbr mbr.S
dd if=/home/xxx/Desktop/myos/boot/mbr of=/home/xxx/Desktop/mybochs/hd60M.img bs=512 count=1 conv=notrunc
启动虚拟机查看效果
cd mybochs
bin/bochs -f bochsrc.disk
回车启动之后,输入c即可看见myos 1 MBR