主引导扇区
主引导扇区
主引导扇区又称为MBR,是操作系统的起点,当计算机启动后,必须读取位于硬盘上的第一个扇区做为引导扇区。
1. 主引导扇区格式
-
主引导扇区大小必须是512字节。
-
必须位于硬盘开始位置的512字节。
例如在1.44M软盘上,位于(柱面=0,磁头=0,扇区1)位置
-
主引导扇区必须是以0x55 0xAA为结尾的。
2. 主引导扇区执行过程
主引导扇区由BIOS进行加载。
系统首先会读取 0 柱面 0 磁道 1 扇区,将其内容加载到内存地址的 0x0000:0x7c00处。然后跳转到内存的0x7c00处执行指令。
至于为什么必须加载到0x7c00的地方,当时就这么规定的吧,没啥特殊的地方,计算机读取指令开始时,会从0x7c00处读取。(其实还是有点特殊的地方,参见http://www.ruanyifeng.com/blog/2015/09/0x7c00.html)
编写一个主引导扇区
下面我们编写一个最简单的主引导扇区,并且在虚拟机中加载运行。
1. 代码
创建boot目录,并新建文件boot/boot.asm
;ratsOS
[bits 16]
org 0x7c00 ;指明程序的偏移的基地址
;引导扇区代码
jmp Entry
db 0x90
db "RATSBOOT"
;程序核心内容
Entry:
jmp $ ;让CPU挂起,等待指令。
;扇区格式
Fill0:
resb 510-($-$$) ;处理当前行$至结束(1FE)填充0
db 0x55, 0xaa
使用nasm编译
nasm -f bin -o boot.bin boot/boot.asm
然后,使用linux命令创建一个1.44M大小,字节都为0的ratsos.img镜像文件
dd if=/dev/zero of=fdimage.img bs=1024 count=1440
将引导扇区文件,添加到ratsos.ima镜像中
dd if=boot.bin of=ratsos.ima bs=512 count=1 conv=notrunc
创建完成,至于dd命令的用法,在此不做详述了。
构建run.sh执行脚本如下
#!/bin/bash
NASM=nasm
$NASM -f bin -o boot.bin boot/boot.asm
dd if=/dev/zero of=ratsos.ima bs=512 count=2880
dd if=boot.bin of=ratsos.ima bs=512 count=1 conv=notrunc
2. 在虚拟机中执行
使用vitualbox虚拟机加载运行镜像
顺利启动,可以发现进入一个黑屏界面。并且光标一直闪烁。
代码地址
https://github.com/sxt102400/ratsos/tree/master/chapter2.1
附:FAT32格式的主引导扇区
上面那段没有定义引导扇区的系统文件格式,实际上在win系统签名一段包括一段系统文件格式的代码。
FAT32 : http://zh.wikipedia.org/wiki/FAT32#FAT32
;以下这段是标准FAT32 格式软盘专用的代码
JMP Entry
DB 0x90 ;nop,0x02
DB "RATSBOOT" ;(8字节)启动区的名称可以是任意的字符串
DW 512 ;每个扇区(sector)的大小(必须为512 字节)
DB 8 ;簇(cluster )的大小(每个簇为8个扇区)
DW 584 ;保留扇区数,包括启动扇区
DB 2 ;FAT的个数(必须为2)
DW 0 ;最大根目录条目个数
DW 0 ;总扇区数(如果是0,就使用偏移0x20处的4字节值)
DB 0x00f8 ;磁盘介质描述
DW 0 ;(FAT16)每个文件分配表的扇区
DW 63 ;每个磁道扇区数
dw 255 ;磁头数
dd 63 ;隐藏扇区
dd 3902913 ;磁盘大小,总共扇区数(如果超过65535,参见偏移0x13)
dd 3804 ;每个文件分配表的扇区,3804个扇区
dw 0 ;Flagss
dw 0 ;版本号
dd 2 ;根目录启始簇
dw 1 ;FSInfo扇区
dw 6 ;启动扇区备份
times 12 db 0 ;保留未使用
DW 0 ;操作系统自引导代码
db 0x80 ;BIOS设备代号
db 0 ;未使用
db 0x29 ;标记
DD 0xffffffff ;序列号
DB "HELLO-OS " ;(11字节)磁盘名称,卷标。字符串长度固定
DB "FAT32 " ;(8字节)FAT文件系统类型。 0x52
times 12 db 0