1 硬盘结构
由上面可知,主引导记录MBR中的分区表有4个分区项目,每个分区项可以放一个主分区,也就是表中的基本分区,或者放一个基本分区。所以系统最多有四个主分区,但是如果我们想要更多的分区的话,我们可以放扩展分区,一个扩展分区可以扩展无限个逻辑分区。上图有三个主分区,一个扩展分区,扩展分区扩展为2个逻辑分区。
扩展分区是如何扩展的呢,其实,每个逻辑分区的头部都有一个字段指向下一个逻辑分区,但最后一个时,就不指向了。
2 MBR
主引导记录共有512字节,占用一个扇区,前面446字节为启动代码,后面64字节,每个16字节指向一个分区。MBR最后两个字节固定为“55aa”。这是是否为有效MBR的判断。
3 FAT32文件系统
FAT32文件系统主要包括三个部分:DBR(dos boot record),FAT表区,数据区。
3.1 DBR区
即DOS引导记录,大小为512个字节。它一定是位于文件系统的最开始,存放启动代码。
3.2 FAT表区
FAT区内存放的是FAT表,对于FAT文件系统来说FAT表至关重要,因此在FAT表1后面还有一份FAT表2,二者的内容完全一样,FAT2作为备份,当FAT1出现错误或损坏时对其进行恢复。
FAT表其实就是一张表,它的每一项大小为4个字节,按照顺序,从第二项开始分别对应着数据区里的每一个簇(第0项和第1项保留给系统使用)。FAT表内项里的内容表示下一个数据存放的簇号,如果已经是最后一簇了则项里的内容为0XFFFFFFFF。
FAT表里的每一项的作用:表明相应的簇被占领;指向下一个簇。
项里面的数据表示意义如图:
3.3 数据区
数据区分为两个部分:根目录区和实际数据区。
3.3.1 根目录区:
根目录区,一般位于数据区的最开始位置,里面存放着根目录下的文件或者文件夹的信息。
根目录区里每一项为32byte,如下:
//fat32短目录项结构
struct
{
uchar file_name[8]; //文件名,不足用空格(0x20)填充
uchar ext_name[3]; //扩展名(后缀名),不足用空格(0x20)填充
uchar attribute; //属性:0:读写;1只读;10隐藏;100系统;1000卷标;10000子目录;100000归档,0x0f表示是长目录结构;(除0xf外其他为二进制值)
uchar reserved; //系统保留
uchar milli_time; //创建时间的10毫秒位
FDT_TIME create_time; //文件创建时间
FDT_DATE create_date; //文件创建日期
FDT_DATE last_visit_date; //文件最后访问日期
ushort high_clus; //文件起始簇号的高16位
FDT_TIME change_time; //文件的最近修改时间
FDT_DATE change_date; //文件的最近修改日期
ushort low_clus; //文件起始簇号的低16位
uint file_length; //文件的长度
}SHORT_FDT32;
3.3.2 实际数据区
实际数据区与FAT表区的一一对应,FAT表区的0,1项用作它用,所以FAT表区从2开始。也就是FAT表区的第2项,对应着实际数据区的第一个簇,即0-4k位置,FAT表区的第3项,对应着实际数据区从4k-8k位置,依次类推。
4 FAT32文件系统大致实现
例如,现在根目录下存放着两个文件1.txt和2.txt。根目录分区就会有两个记录,每个为32byte。假设1.txt文件有20k大小,系统一个簇为4k,所以1.txt要占5个簇,即再FAT1表中占5个项。
假设现在应用程序要打开读取1.txt文件,我们现在根目录区中找到1.txt那一项,找到1.txt的对应项之后,我们可以看到两个字段字段high_clus,low_clus,将这两个簇组合起来后,我们就可以得到1.txt的起始簇,假设得到1.txt的起始簇是4,那么接下来,我们就到FAT1表区中找到第4个项,然后我们查看该项,发现它是指向第8项的,第8又指向7,依次类推,所以1.txt所在的地址为
4->8 ->7 ->6->10
总共5个簇,共20k,假如第一簇的地址在磁盘10000处,那么,文件1.txt在
10000+4*4k –> 10000+8*4k –> 10000+7*4k 。。。。。
假如根目录区中除了放1.txt,2.txt两个文件外,还放了home这个文件夹时,找法还是和1.txt文件一样,不过根目录区中相应的32byte项的attribute 字段应当填子目录,表明这个是文件夹。然后所找到的簇所对应的实际数据区中的数据不是和1.txt一样放文件内容,而是放着和根目录区一样的目录项(每项32字节大小)