FAT12文件系统介绍

简介

FAT12文件系统是指:在磁盘上规定一种特定的存储格式,这种存储格式高效方便,功能强大,因此形成了统一的规定。

基础知识

具体来说FAT12文件系统为1.44M的软盘设计。1.44M的软盘有2880个扇区,一个扇区有512个字节;那么FAT12文件系统的管理的空间大小就是2880 * 512 = 1474560个字节

实际的扇区是在磁盘上,但是我们可以把所有的储存空间看作是一个很大的数组,把扇区当作是连续排列的。扇区当作数组看待时,称为逻辑扇区,从0开始编号。

FAT12基础结构

首先FAT12文件系统将2880个扇区分成5个部分:MBR引导记录、FAT1表、FAT2表、根目录、数据区

每个扇区和目录占有的空间如下表

起始地址(按字节编址)占有扇区数名称
01MBR
5129FAT1表
51209FAT2表
972814根目录
168962847数据区

下面是FAT12结构的示意图

image-20200331120720670.png

MBR引导记录

MBR引导记录有512个字节,最后两个字节是0x55和0xAA;MBR记录的所有信息如下(储存数据附上常用值;部分数据没有给出)

名称开始字节长度存储数据
BS_jmpBOOT03一个跳转指令
BS_OEMName38厂商名,‘msdos1.0’
BPB_BytesPerSec112每扇区字节数,512
BPB_SecPerClus131每簇扇区数,1
BPB_ResvdSecCnt142MBR占用扇区数,1
BPB_NumFATs161共有多少FAT表,2
BPB_RootEntCnt172根目录区文件最大数,224
BPB_TotSec16192扇区总数,2880
BPB_Media211介质描述符,0xF0
BPB_FATSz16222一个FAT表所占扇区数,9
BPB_SecPerTrk242每磁道扇区数
BPB_NumHeads262磁头数
BPB_HiddSec284隐藏扇区数,0
BPB_TotSec32324如果BPB_TotSec16=0,则这里给出扇区数
BS_DrvNum361INT 13H的驱动器号
BS_Reserved1371保留位
BS_BootSig381扩展引导标记
BS_VolID394卷序列号
BS_VolLab4311卷标
BS_FileSysType548文件系统类型,‘FAT12’
汇编代码64448引导记录里面的汇编代码
结束标志5102两个字节分别为0x55,0xAA

MBR引导记录就是BOIS读入内存的一个扇区,可以看到第一条指令就是汇编语言x86中的跳转指令,这条指令将跳转到后面的汇编代码区域进行执行。由于我们在做模拟FAT12文件系统程序时不需要考虑后面一段代码,因此后面的汇编代码通常为0。

真正要注意的地方就是前面的一些FAT12文件的参数。之后为了方便说明统一用默认值考虑FAT12文件系统,在DOS系统中这些值基本上也是固定的。

FAT1、FAT2表

这两个表完全相同,FAT2表存在的目的就是为了修复FAT1表。因此在实际操作的过程中可以将FAT1表在关机的时候赋值给FAT2即可。以后再说FAT表时,默认为FAT1表

FAT表每十二个bit(1.5个字节)为一个簇,这也正是FAT12名字的由来。

每个簇具储存了什么呢?首先12个二进制数字表示这个簇指向的下一个簇。FAT表从零开始编号。如果2号簇储存的数字为3,那么说明2号簇指向3号簇。3号簇的12位数字储存的是5的话,那么说明3号簇指向5号簇。这就形成了一个链表,链表的空指针NULL(结尾标志),使用0xFFF表示

FAT表有9个扇区一共有3072个簇,12位的二进制数能表示的最大簇号为4096。每个簇都能被访问,需要关心的是不要让簇号越界。

FAT表的0号簇和1号簇不能使用,他们储存的是坏簇标记0xFF0和结尾标志0xFFF。

下面截取了DOS系统FAT表的一部分,要注意Intel是用的大端存储,也就是高字节储存在高地址。第一个簇是0xF0 0xFF拼接起来的,0xFF的后面的F和0xF0拼接,形成0xFF0,也就是坏簇标记。第二个簇也可以用同样方法分析出来是0xFFF,这就是簇链表结束的标记。

image-20200331133954080.png

**簇到底有什么用?**之前提到过数据区有2847个扇区(<3072个簇),因此我们可以将每个簇映射到一个扇区上去。我们将扇区编号为0、1……由于0、1号簇无用,所以2号簇代表32号扇区(之前的扇区是MBR、FAT1、FAT2、根目录),3号簇代表33扇区,以此类推。

我们可以看到这个结构越来越像编程中的链表结构,用C语言可以表示成下面的结构

struct list
{
	struct block *next; // 簇就是这里的指针
    char block[512]; // 扇区就是这里的block,储存数据
};

**为什么簇和扇区要分离?**我们当然可以把next指针放在一个扇区内,这样看上去更像编程中的链表结构。然而在实际操作系统中,很多时候只需要访问簇号就可以了,不需要访问扇区中的数据(计算目录的大小),这个时候只读取一个扇区内的容基本上就可以完成操作,极大的减少了I/O时间。

根目录区

根目录顾名思义就是系统最初的文件夹。在Windows中用’\‘表示,在Linux中用’/'表示。根目录中储存了文件和子目录,两者的真正数据都是储存在数据区中,在根目录中之储存基本信息,用来找到它们真正的数据。这些基本信息叫文件目录项

一个文件目录项有32个字节,组织方法如下(按字节编址)

偏移量长度描述
08文件名
83文件扩展名
111文件属性
1210保留位
222创建时间
242创建日期
262首簇号
284文件大小

文件名和扩展名就是基本的名称和’.'后面的名称。例如a.txt文件名是a,扩展名是txt。有一点要注意的是文件名如果未满8位,那么要将后面的字符置为“空格”,而不是0。

文件属性基本有三种:隐藏文件0x27;目录0x10;普通文件0x20;

10个字节的保留位后来被用作储存“修改时间”等信息。在最初的DOS系统中就是被浪费掉了。

创建日期和时间比较复杂,我专门写了一篇文章仔细分析。其中有C语言的提取代码。

首簇号是指文件第一个段信息存放的地址。之前说过一个簇映射到一个数据区的扇区,因此文件的数据就储存在首簇号对应的扇区中。

如果文件只有一个扇区,首簇号为2,那么FAT表的前几个字节如下:F0 FF FF FF ?F。其中最后一个字节的低四位和前面的FF组成了结束标记FFF。文件的所有数据都存放在32扇区中。

如果文件有连个扇区,首簇号为2,那么FAT表的前几个字节可能是这样的:F0 FF FF 02 0F FF。文件的数据就存放在32和33扇区中。

文件大小就是用字节表示的文件大小。

数据区

数据区的某一个扇区如果是一个目录,那么这个目录被称为子目录。子目录分为一级、二级……子目录,他们的组织方法和根目录基本一样。

子目录中一定要包含两个目录项:. …

比如在DOS的某一个子目录下使用dir命令会有如下结果

image-20200331210408861.png

前两个目录项为了方便说明记为dot和dotdot。

dot目录项储存的首簇号为当前目录的首簇号,而就是说dot除了名字,其他信息和当前目录的目录项一样。那么当使用下面命令时,还是会停留在当前目录

cd .

dotdot目录项储存当前目录父目录的首簇号,如果父目录是根目录那么首簇号为零,这是一种特殊情况。在使用下面命令的时候,会退回到父目录

cd ..

如果某个扇区储存的是文件普通文件,那么就没有什么特定的规则,根据每个文件的不同会有不同的数据组织结构。

  • 2
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值