《一个操作系统的实现》(四):让操作系统走进保护模式

一个操作系统从开机到开始运行,大致经历“引导->加载内核入内存->跳入保护模式->开始执行内核”这样一个过程。

几乎所有的文件系统都会把磁盘划分为若干层次以方便组织和管理,这些层次包括扇区(磁盘上的最小数据单元),簇(一个或多个扇区),分区(通常指整个文件系统)。

对于FAT12文件系统来说,第0号扇区为引导扇区,其中有一个叫做BPB(BIOS Parameter Block)的数据结构,格式如下表,其中BPB_开头的属于BPB,其余的只是引导扇区的一部分。

FAT12引导扇区的格式
名称偏移长度内容Orange's的值
BS_jmpBoot03一个短跳转指令jmp LABEL_START
nop
BS_OEMName38厂商名'ForrestY'
BPB_BytesPerSec112每扇区字节数0x200
BPB_SecPerClus131每簇扇区数0x1
BPB_RsvdSecCnt142Boot记录占用多少扇区0x1
BPB_NumFATs161共有多少FAT表0x2
BPB_RootEntCnt172根目录文件最大值0xE0
BPB_TotSec16192扇区总数0xB40
BPB_Media211介质描述符0xF0
BPB_FATSz16222每FAT扇区数0x9
BPB_SecPerTrk242每磁道扇区数0x12
BPB_NumHeads262磁头数(面数)0x2
BPB_HiddSec284隐藏扇区数0
BPB_TotSec32324如果BPB_TotSec16是0,由这个值记录扇区数0
BS_DrvNum361中断13的驱动器号0
BS_Reserved1371未使用0
BS_BootSig381扩展引导标记(29h)0x29
BS_VolID394卷序列号0
BS_VolLab4311卷标'OrangeS0.02'
BS_FileSysType548文件系统类型'FAT12'
引导代码及其他62448引导代码、数据及其他填充字符等引导代码(剩余部分被0填充)
结束标志51020xAA550xAA55
接下来扇区号1-9、10-18分别由两个完全相同的表(FAT1和FAT2)占用,接下来是根目录区(长度非固定,需计算),剩余的是数据区(截止到2879号)。

根目录区由若干个目录条目组成,每个条目占32字节,条目最多有BPB_RootEntCht个,即根目录区大小依赖于BPB_RootEntCht。

根目录区中的条目格式
名称偏移长度描述
DIR_Name00xB文件名8字节,扩展名3字节
DIR_Attr0xB1文件属性
保留位0xC10保留位
DIR_WrtTime0x162最后一次写入时间
DIR_WrtDate0x182最后一次写入日期
DIR_FstClus0x1A2此条目对应的开始簇号
DIR_FileSize0x1C4文件大小
注意,数据区的第一个簇号是2,而不是0或1。

实际上,对于小于512字节的文件来说,FAT表用处不大,但如果文件大于512字节,就需要FAT表来找到所有的簇(扇区)。通常FAT项的值代表的是文件下一个簇号。还需要注意的是一个FAT项可能会跨越两个扇区。

引导扇区需要有BPB等头信息才能被识别,书上BPB的代码如下:

jmp short LABEL_START		; Start to boot.
	nop				; 这个 nop 不可少

	; 下面是 FAT12 磁盘的头
	BS_OEMName	DB 'ForrestY'	; OEM String, 必须 8 个字节
	BPB_BytsPerSec	DW 512		; 每扇区字节数
	BPB_SecPerClus	DB 1		; 每簇多少扇区
	BPB_RsvdSecCnt	DW 1		; Boot 记录占用多少扇区
	BPB_NumFATs	DB 2		; 共有多少 FAT 表
	BPB_RootEntCnt	DW 224		; 根目录文件数最大值
	BPB_TotSec16	DW 2880		; 逻辑扇区总数
	BPB_Media	DB 0xF0		; 媒体描述符
	BPB_FATSz16	DW 9		; 每FAT扇区数
	BPB_SecPerTrk	DW 18		; 每磁道扇区数
	BPB_NumHeads	DW 2		; 磁头数(面数)
	BPB_HiddSec	DD 0		; 隐藏扇区数
	BPB_TotSec32	DD 0		; wTotalSectorCount为0时这个值记录扇区数
	BS_DrvNum	DB 0		; 中断 13 的驱动器号
	BS_Reserved1	DB 0		; 未使用
	BS_BootSig	DB 29h		; 扩展引导标记 (29h)
	BS_VolID	DD 0		; 卷序列号
	BS_VolLab	DB 'OrangeS0.02'; 卷标, 必须 11 个字节
	BS_FileSysType	DB 'FAT12   '	; 文件系统类型, 必须 8个字节  

LABEL_START:

要加载一个文件如内存的话免不了要读软盘。这时候需要用到int 13h中断,此中断参数详见 这篇文章。中断参数需要柱面号、磁头号、当前柱面上的扇区号三个分量,这三个分量的计算方法如下:

扇区号/每磁道扇区数(18),得商Q和余数R。柱面号为Q>>1,磁头号为Q&1,起始扇区号为R+1。

Loader要做的事情至少有两件:加载内核入内存;跳入保护模式。因为内核开始执行的时候一定在保护模式下。.COM的内核可以直接放入内存,但是ELF格式的内核不能直接放进内存(下一章会讲)。


---------------------

在编译生成boot.bin后,还需要这样做:首先用bximage生成一个软盘映像(直接执行bximage),然后执行如下命令

nasm loader.asm -o loader.bin

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

sudo mount -o loop a.img /mnt/floppy/

sudo cp loader.bin /mnt/floppy/ -v

sudo umount /mnt/floppy/

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值