[自制操作系统] 第02回 初识MBR

目录
一、前景回顾
二、写一个粗略的MBR
三、运行测试

 

一、前景回顾

  上回说到,开机的启动过程就是当时Intel和BIOS等硬件厂商所制定的规则,现在我们来回顾一下有如下三点:

  1、按下开机键后,CPU将cs:ip寄存器初始化为0xf000:0xfff0,这个位置是BIOS程序的入口处,这个位置存放的代码是jmp far f000:e05b,通过这行代码CPU又将cs:ip寄存器初始化为0xf000:0xe05b,这里才是BIOS真正开始执行的地方。

  2、BIOS执行了一系列的硬件检测工作和创建中断向量表IVT后,将MBR(主引导记录)加载到内存0x7c00处,并且跳转到该位置,也就是将cs:ip寄存器初始化为0x0000:0x7c00。

  3、MBR的工作是加载操作系统内核,最后跳转到操作系统内核中,随后便是熟悉的启动动画,也就完成了开机过程。

二、写一个粗略的MBR

  新建一个mbr.S的文件,键入如下代码:

 1     SECTION MBR vstart=0x7c00
 2         mov ax,cs
 3         mov ds,ax
 4         mov es,ax
 5         mov ss,ax
 6         mov fs,ax
 7         mov sp,0x7c00
 8         mov ax,0xb800
 9         mov gs,ax
10         
11     ;利用int 0x10 的0x06号功能实现清屏
12         mov ax,0x600
13         mov bx,0x700
14         mov cx,0
15         mov dx,0x184f
16 
17         int 0x10
18         
19     ;获取当前光标位置    
20         mov ah,3
21         mov bh,0
22 
23         int 0x10
24     ;输出字符串“HELLO MBR” 
25         mov ax, message
26         mov bp, ax
27         mov cx, 9
28         mov ax, 0x1301
29         mov bx, 0x2
30         int 0x10
31         
32         jmp $                       ;使CPU悬停在此
33 
34         message db "HELLO MBR"
35         times 510-($-$$) db 0
36         db 0x55,0xaa
mbr.S

  第1行的“vstart = 0x7c00”表示该程序在编译的时候,告诉编译器将我的起始地址编译为0x7c00。

  第2~6行,因为BIOS是通过jmp 0:0x7c00的方式跳转到MBR中的,所以此时cs为0。而CPU中的段寄存器不能通过立即数来对它们赋值,因此只能通过其他寄存器来对它们初始化,这里先将cs寄存器的值赋给ax,再使用ax来初始化其他段寄存器。

  MBR也是程序,是程序就需要栈,而我们的程序被加载到0x7c00处,0x7c00以下的区域暂时没被使用,所以先将栈顶设为0x7c00。

  第11~30行中的代码便是清屏和打印字符,这里只是为了测试使用,没有什么实际意义。

  第32行,我们通过jmp $指令让CPU一直跳转执行该行,也就是c语言中的“while(1);”作用,因为后面的区域没有可供CPU执行的代码,所以为了避免CPU跑偏,现在先让它一直在此死循环。

  第34~36行,我们现在构建的MBR,最终的目的是希望被BIOS访问并且加载到地址0x7c00处。因此回顾前面的内容,要想让BIOS相信这就是它苦苦寻找的东西,那我们就要让我们的MBR符合要求,也就是代码最后两个字节是0x55和0xaa,并且整个MBR的大小必须是512字节。所以这里使用“times 510 - ($ - $$)db 0”来将前510个地址中为空的地址处全部填为0,随后再单独给最后的两个字节设置为0x55和0xaa。

  一切就绪工作完成后,使用nasm来编译汇编代码,输入如下代码,便可以在当前目录下得到mbr.bin文件。
  nasm mbr.S -o mbr.bin
  使用ls命令来查看一下生成的bin文件的大小。
  ls -lb mbr.bin
  结果如下:
  
  可以看到mbr.bin的大小的确是512字节,那么接下来就通过dd命令来将mbr.bin文件写入到我们前面创建的磁盘hd60M.img中:
  dd if=./mbr.bin of=./hd60M.img bs=512 count=1 conv=notrunc
  写入成功后会有如下输出:
  
  这一步过后,我们便可以开始准备运行测试。

三、运行测试

  启动bochs测试一下,我是在bochs的安装目录下启动的,输入 ./bin/bochs -f bochsrc.disk 回车,默认[6]开始模拟,再按回车。随后在出现的控制台中按下c,bochs便开始运行起来了。

  当MBR成功被加载并且运行起来后,在屏幕上我们会看到预先设置的字符串“HELLO MBR”在不停的闪烁,到此也就说明我们编写的MBR没有问题。

   

  现在我们已经初步实现了一个简单的MBR,只不过这个MBR没有什么实质性作用。下面我们将会完善这个MBR,只是在完善MBR之前,我们还需要做一件更重要的事。欲知后事如何,请看下回分解。

 

posted @ 2022-05-04 11:10  李知行  阅读(593)  评论(0编辑  收藏  举报