(一)为什么要有文件系统

文件系统是操作系统用于明确存储设备或分区上的文件的方法和数据结构,即在存储设备上组织文件的方法。如果没有文件系统,那我们想找到在硬盘上保存的数据会是一件很麻烦的事情,文件系统的作用是,它负责为用户建立文件、读出、修改,控制文件的读取,我们常说的格式化硬盘就是写入文件系统。文件系统的种类有很多,而且有各自的特点,本文主要介绍FAT32文件系统。

(二)FAT32文件系统组成

FAT32文件系统由DBR及其保留扇区,FAT1,FAT2和DATA四个部分组成(下图MBR是主引导记录,不一定每个磁盘都有)
在这里插入图片描述

(三)分步介绍各部分

(1) 首先介绍一下MBR

MBR主要存储磁盘分区相关的信息,如果存在MBR的话,那么它占用第一个扇区的512个字节,前446个字节为MBR启动代码(这里不关心),接下来16*4个字节为磁盘分区表,每个分区的信息要占16个字节,所以,MBR分区表最多只能保存4个分区的分区信息,最后两个字节是结束标识0x55AA。
如果你的SD卡开头是EB 58 90那就说明你的SD卡没有MBR,需要重新创建MBR,创建过程可以参考SD卡移植FAT32文件系统无MBR,下面我们来看下MBR的内容:
在这里插入图片描述

标识长度介绍
Active1字节0x80表示活动分区,0x00表示非活动分区0x80
StartHead1字节分区的开始磁头0x20
StartCylSect2字节开始柱面与扇区(柱面和扇区分别占用不同位数,有需要查资料)0x21 0x00
PartType1字节分区类型(0x0b和0x0c都是FAT32)0x0c
EndHead1字节分区的结束磁头0xFE
EndCylSect2字节结束柱面与扇区(柱面和扇区分别占用不同位数,有需要查资料)0xff 0xE1
StartLBA4字节分区的第一个扇区0x00 0x08 0x00 0x00
Size4字节分区总扇区数目0x00 0xc0 0xf3 0x00

上面显示的是小端模式(地址值存放低字节)
这么多信息,对于初学着只需要知道分区的第一个扇区和分区的大小即可,从上面可以看出起始扇区为0x00000800(注意是小端模式!!)=2048扇区,总扇区数目为0x00f3c000,那么总大小为0xf3c000*512/1024/1024/1024=7.6G

注:
(1)MBR分区方案中,有三种类型的分区,主分区、扩展分区和逻辑分区。扩展分区与逻辑分区是为了突破分区表中只能保存4个分区的限制而出现的。扩展分区不能直接使用,需要在扩展分区内划分一个或多个逻辑分区后才能使用。
(2)一般每个扇区的容量是512字节,4个字节的扇区能表示的最大容量是2TB(2^32 * 512/1024/1024/1024=2048G=2TB),由此可知,在MBR分区表中,分区的起始位置不能大于2TB,分区的最大容量,也不能大于2TB。所以,对2TB以上容量的物理硬盘,不适合使用MBR分区方案。

有一些硬盘厂商,尝试扩大扇区的大小,来突破MBR不适合2TB容量以上的硬盘这一限制。所以有时你会发现市场上存在的硬盘,不完全是每个扇区512字节的,有1024字节甚至2048字节每扇区的。但扩大扇区的大小,又会带来很多其他的问题,特别是会严重影响硬盘的速度,所以这种方法,没有被广泛接受。

(2)DBR介绍

DBR是我们格式化分区时创建的,每个分区都会有DBR信息,1个DBR只能定义1个分区的系统文件,占用512个字节
在这里插入图片描述
从上面的MBR可知第一个分区在2048扇区(2048*512字节=0x100000)我们直接跳过去看看:
在这里插入图片描述
跳转指令:EB 58 90:本身占2字节它将程序执行流程跳转到引导程序处
OEM代号:这部分占8字节,其内容由创建该文件系统的OEM厂商具体安排。

跳转指令之后是8字节长的OEM ID,它是一个字符串, OEM ID标识了格式化该分区的操作系统的名称和版本号。为了保留与MS-DOS的兼容性,通常Windows 2000格式化该盘是在FAT16和FAT32磁盘上的该字段中记录了“MSDOS 5.0”,在NTFS磁盘上(关于ntfs,另述),Windows 2000记录的是“NTFS”。通常在被Windows 95格式化的磁盘上OEM ID字段出现“MSWIN4.0”,在被Windows 95 OSR2和Windows 98格式化的磁盘上OEM ID字段出现“MSWIN4.1”。
BPB:下面是从上图截下的BPB内容
在这里插入图片描述
我们主要关注红色字体标出的内容:

标识长度介绍
BytesPerSec2字节每扇区字节数,通常为512、1024、2048、40960x00 0x02
SecPerClus1字节每簇扇区数,这个值不能为0,而且必须是2的整数次方,比如1、2、4、8、16、32、64、1280x08
ResdSecCnt2字节保留扇区数0x5E 0x06
NumFATs1字节FAT表数目0x02
RootEntCnt2字节FAT32固定为00x00 0x00
TotSec162字节FAT32固定为00x00 0x00
Media1字节存储介质,0xF8标准值,可移动存储介质0xf8
FATSz162字节FAT32固定为00x00 0x00
SecPerTrk2字节磁道扇区数0x3f 0x00
NumHeads2字节磁头数0xff 0x00
HiddSec4字节FAT区前隐藏扇区数0x00 0x08 0x00 0x00
TotSec324字节总扇区数0x00 0xC0 0xF3 0x00
FATSz324字节一个FAT表扇区数0xd1 0x3c 0x00 0x00
ExtFlags2字节FAT32持有0x00 0x00
FSVer2字节FAT32持有0x00 0x00
RootClus4字节第一个目录的簇号0x02 0x00 0x00 0x00
FSInfo2字节保留扇区数,FSINFO(文件系统信息扇区)扇区号是1,该扇区为操作系统提供关于空簇总数及下一可用簇的信息0x01 0x00
BkBootSec2字节通常为60x06 0x00
Reserved12字节用以扩展0x00 0x00 … 0x00
DrvNum1字节驱动器号0x80
Reserved11字节保留0x00
BootSig1字节扩展引导标签0x29
VolID4字节分区序列0x24 0x09 0x88 0x8a
FileSysType11字节卷标
FilSysType18字节系统ID

解读:
(1)从上面我们可以看出每扇区字节数为0x0200,即512字节
(2)每簇扇区数为0x08
(3)保留扇区数为:0x065e=1630
(4)FAT表数目为2
(5)总扇区为:0x00f3c000即15974400个扇区
(6)一个fat表扇区数:0x000003cd1即15569
(7)第一个目录簇号0x00000002
(8)第一个fat表的扇区号=DBR所在扇区+保留扇区=2048+1630=3678
(9)第一个目录的扇区号=第一个fat表的扇区号+2*(一个fat表扇区数)=3678+2*15569=34816
FAT32文件系统在DBR的保留扇区中安排了一个文件系统信息扇区,用以记录数据区中空闲簇的数量及下一个空闲簇的簇号,该扇区一般在分区的1号扇区,也就是紧跟着DBR后的一个扇区,其内容如下
在这里插入图片描述
引导程序代码:FAT32的DBR引导程序占用420字节,对于没有安装操作系统的分区来说这段程序是没有用处的.
结束标识:DBR的结束标志与MBR,EBR的结束标志相同,为“55 AA”。

(3)FAT表介绍

文件系统分配磁盘空间按簇来分配。因此,文件占有磁盘空间时,基本单位不是字节而是簇,即使某个文件只有一个字节,操作系统也会给它分配一个最小单元:即一个簇。对于大文件,需要分配多个簇。同一个文件的数据并不一定完整地存放在磁盘中一个连续地区域内,而往往会分若干段,像链子一样存放。这种存储方式称为文件的链式存储。为了实现文件的链式存储,文件系统必须准确地记录哪些簇已经被文件占用,还必须为每个已经占用的簇指明存储后继的下一个簇的簇号,对于文件的最后一簇,则要指明本簇无后继簇。这些都是由FAT表来保存的,FAT 表对应表项中记录着它所代表的簇的有关信息:诸如是空,是不是坏簇,是否是已经是某个文件的尾簇等。

定位FAT绝对位置的方法如下:

1、首先从MBR的分区表中得知分区的起始扇区,偏移到此扇区。

2、从DBR的BPB中得知DBR的保留扇区数,FAT表的个数,FAT表的大小。

3、因此FAT1=分区起始扇区+DBR保留扇区,FAT2=分区起始扇区+DBR保留扇区+FAT1。

从上面我们计算出第一个fat表的扇区号在3678扇区,第一个目录的扇区号34816,我们使用winhex查看一下:
在这里插入图片描述
第0号表项:0x0FFFFFF8,表示FAT表固定标识
第1号表项:0xFFFFFFFF,不用,默认值
第2号表项:0x0FFFFFFF,根目录所在簇,由于此时只占用1簇,所以是结束标识
下面我们在SD卡里创建一个大于4k(每簇占8个扇区即4k,只有大于4k才占用多簇)文件,重新查看该位置的内容
在这里插入图片描述
此时已经看到新增加了三簇内容:该test文件簇链为0x05—>0x06–>0x07(结束),注意簇链结束标识为0x0FFFFFFF,文件大小小于一簇大小的直接占用1簇,以0X0FFFFFFF结束
在这里插入图片描述

(4) 数据区

数据区时真正用于存放用户数据的区域,数据区的位置在FAT2的后面,具体定位方式如下;

1、通过MBR中的分区表信息得知分区的起始位置。

2、通过分区中DBR得知DBR的保留扇区数以及FAT表的大小,FAT表的个数。

3、通过上面的信息就可以找到数据区的起始位置,数据区 = 隐藏扇区数+DBR保留扇区+(每个FAT表扇区数*2)。

数据区的类容主要由三部分组成:根目录,子目录和文件内容。在数据区中是以“簇”为单位进行存储的,2号簇被分配给根目录使用。
数据起始扇区=根目录起始扇区号+(簇号-2)x每簇的扇区数
注:FAT表对所有划分后的位置由0进行地址编号。0号地址与1号地址被系统保留并存储特殊标志内容。从2号地址开始,每个地址对应于数据区的簇号,也就是数据区起始位第2簇!FAT表中0和1号表项没有对应物理地址。
前面我们算出第一个目录(根目录)的扇区号34816,我们使用winhex直接跳转34816过去看下:
在这里插入图片描述
FAT32文件系统中,分区根目录下的文件和目录都放在根目录区中,子目录中的文件和目录都放在子目录区中,并且每32个字节为一个目录项(FDT),每个目录项纪录着一个目录或文件(也可能是多个目录项记录一个文件或目录),上图所示就是一个目录项。

在FAT32文件系统中,目录项可以分为四类:卷标目录项、“.”和“…”目录项、短文件名目录项、长文件名目录项。
我们分别创建SHUIYUE目录和SHUIYUE.txt文件来看下
在这里插入图片描述
在这里插入图片描述
FDT第1字节又表明了该文件的状态,它有如下四种取值方式:
a. 00H–目录项的空目录。
b. E5H–表示该目录项曾经使用过,但文件已被删除。
c. 2EH–表示子目录下的两个特殊文件 “. “或 “… “目录项
d. 其它任何字符–表示一个文件名(或目录名)的第一个字符的ASCII码值.
我们来看下SHUIYUE.txt目录项代表的东西

标识长度介绍
deName8字节文件名,不足部分补空格(0x20)0x53 0x48 0x55 0x49 0x59 0x55 0x45 0x20(SHUIYUE)
deExtension3字节扩展名,不足部分补空格(0x20)0x54 0x58 0x54(TXT)
deAttributes1字节文件属性0x20(存档)
deLowerCase1字节系统保留0x10
deCTime3字节创建时间0x8c 0x00 0xab
deCDate2字节创建日期0x8d 0x51
deADate2字节最后访问的日期0x8d 0x51
deHighClust2字节开始簇的高两个字节0x00 0x00
deMTime2字节最后修改的时间0x09 0xab
deMDate2字节最后修改的日期0x8d 0x51
deLowCluster2字节开始簇的低两个字节0x06 0x00
deFileSize4字节文件的大小0xd8 0x21 0x00 0x00

从上面我们可以看出SHUIYUE.txt开始簇为0x06我们查找FAT表:
在这里插入图片描述
从第6簇开始,占据了3簇,我们跳到第6簇看下内容,第6簇在数据区起始扇区34816+(6-2)*8=34848
在这里插入图片描述
从上可以看出刚好是我们写入的数据,其他可以自己尝试,例如新创建一个不同大小的文件、创建子目录观察数据的变化。

注:
(1)目录所在的扇区,都是以32 Bytes划分为一个单位,每个单位称为一个目录项。

(2)根据文件名及后缀,我们可以分为短目录文件,长目录文件,简单点理解,如果文件名>8 byte 或者后缀名>3, 则为长文件目录,否则为短文件目录
在这里插入图片描述


参考文章:
(1)FAT32长文件名短文件名目录项
(2)详解FAT32文件系统
(3)FAT32文件系统格式详解
(4)FAT32文件系统详解
(5)SD卡中FAT32文件格式快速入门(详细图文介绍)
(6)FAT32文件系统SD卡建立MBR引导扇区
(7)FAT32文件系统格式详解(图文针对具体文件存储,分析fat32 SD卡)
(8)MBR、EBR与DBR详解


本文章仅供学习交流用禁止用作商业用途,文中内容来水枂编辑,如需转载请告知,谢谢合作

微信公众号:zhjj0729

Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐