512B是软盘第一扇区的大小,称为引导扇区。

系统要进入保护模式,512B是不够用的。

所以在软盘的其他地方存放一个文件,通过512B的引导扇区,加载到内存,并把控制权交给该它。

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

也就是说在内核开始执行之前不但要加载内核,还要准备保护模式等一系列工作,如果全部交给引导扇区来做,512B很可能不够用

所以不妨把这个过程交给另外的模块来完成,我们把这个模块叫做Loader。

引导扇区负责把Loader加载入内存并且把控制权交给它。

其他工作放心地交给Loader来做。

整理一下这一章的思路。

目的是突破引导扇区512字节的限制,方法是把在boot里完成loader.bin加载到内存,然后将控制权交给loader.bin(通过跳转)。

首先是系统引导boot,然后搜寻根目录区找到文件名为loader.bin的条目,在通过其对应的簇号去读取FAT表,把loader.bin文件载入内存(通过中断),loader.bin执行等待。

不过本章题目虽然是让操作系统走进保护模式,截止到最后还是没有跳入保护模式。

FAT12

FAT12是DOS时代就使用的文件系统,直到现在仍然在软盘上使用。

软盘层次:扇区(sector)磁盘上的最小数据单元 、簇(cluster)一个或多个扇区、分区(Partition)通常指整个文件系统

 

引导扇区是软盘上的第0个扇区,在这个扇区中有一个很重要的数据结构叫做BPB(BIOS Parameter Block)

以BPB_开头的域属于BPB,以BS_开头的域不属于BPB,只是引导扇区(boot sector)的一部分。

引导扇区的0--61字节都是BPB_或BS_开头的数据结构

引导扇区从62字节开始是引导代码和其他,长度是448字节

结束标志0XAA55 开始510,长度2个字节,一共是512字节。

 

引导扇区后面是两个完全相同的FAT表,每个FAT表占用9个扇区。第二个FAT表后根目录区。根目录区后是数据区。

所以可以发现软盘0扇区引导扇区,1--9扇区FAT1,10-18扇区FAT2,19- n扇区根目录 ,,,

可以发现根目录偏移了0-18个扇区也就是19个扇区,偏移了19*512=9728=0x2600个字节

根目录区由若干个目录条目(Directory Entry)组成,条目最多有BPB_RootEntCnt个,所以根目录区的大小是依赖BPB_RootEntCnt的,所以长度不固定。

每个根目录占用32个字节,它的格式如下: 

 

名称                偏移       长度          描述

DIR_Name       0           0xb          文件名8字节,扩展名3字节

DIR_Attr         0xb       1              文件属性

保留位             0xc        10            保留位

DIR_WitTime   0x16       2             最后一次写入时间

DIR_WitDate   0x18       2             最后一次写入日期

DIR_FstClus    0x1A      2              此条目对应的开始簇号

DIR_FileSize    0x1c       4              文件大小

根目录区实际上放的就是根目录下所有文件的信息结合:如每个文件的文件名,大小,属性,开始簇号等等。起到索引作用。

 所以我们要寻找loader时,先到根目录区选择文件名为loader的根目录,然后找到它的开始簇号,从而索引到文件。

根目录所占用的扇区的计算:

根目录扇区数=根目录目录条数*32/每扇区字节数

如果余数=0则 就是商,如果不是0就要加上1

如果根目录区占用14个扇区,则数据区开始扇区=根目录开始扇区+14=19+14=33

 

数据区的第一个簇的簇号是2。FAT表中第0个FAT项和第1个FAT项始终不使用,从第二个FAT项开始表示数据区的第一个簇。

每个FAT项是12位。这里设置一个簇就包含一个扇区。

通常FAT项的值代表的是文件下一个簇号,但如果值大于或等于0xFF8,则表示当前簇已经是本文件的最后一个簇。

 

如一个它的开始簇即DIR_FstClus值为3,对应第3个FAT项,此FAT中的值为0X008,代表这不是最后一个簇,下一个簇号是8,我们再找第八个FAT项,发现值为0x009,接下来第九个FAT项的值为0x00A,第0x0A个FAT项的值为0xFFF。所以该文件共占用了3,8,9,10 共4个簇。