文章目录
FATFS文件系统详解
1. 简介
2. 基础概念
3. FAT文件系统组成介绍
4. FAT文件系统分析
4.1 采用FAT格式格式化SD nand/sd卡
4.2 引导扇区分析
4.3 分区偏移及大小计算
4.4 FAT子类型确认
4.4 访问FAT条目
4.5 文件与簇之间的关系
4.6 FSInfo扇区结构及备份引导扇区
4.7 FAT目录
4.7.1 SFN 短文件名目录
4.7.2 LFN长文件名
4.7.3 LFN系统对于SFN的兼容
5. 分区分析
5.1 保留分区分析
5.2 FAT区分析
5.3 根目录区分析
5.4 数据区分析
5.5 新增文件测试
6. 总结
1. 简介
在早期计算机刚发展的时候,那时候硬盘大小、flash设备容量都比较小,随着技术的不断迭代更新,硬盘容量越来越大。在早期,面对小容量的硬盘/flash,往往采用对应地址存放对应数据的方案,由于数据量不大,操作起来尚还可以。但是发展到今天,随着硬盘/flash容量不断增大,存储的数据也越来越多,早期单一的对应地址存放对应数据的方案已经无法满足我们的需求,操作硬盘/flash会变得异常的困难复杂。
因此针对上述问题,一群大佬们便开始设计文件系统这样一个东西,用来管理硬盘/flash上的数据信息,像我们电脑上打开文件夹,访问里面的文件,这其实就是基于文件系统访问电脑硬盘上数据的一个操作。
发展至今,文件系统已有众多版本,本文主要分享 关于FAT文件系统的详细设计, FAT文件系统适用于嵌入式设备,如SD卡、SD nand、spi nor flash等众多存储设备,同时基于此文件系统的文件亦能被电脑正常读取。
在研究文件系统之前,我们需要首先弄清楚关于内存这块的几个基本概念:
Fat文件系统官方文档:
FAT文件系统在flash上的布局如下图所示,总共由四个区域组成:
接下来,我们对一张格式化为FAT格式的SD卡进行分析,理解FAT文件系统的实现细节:
4. FAT文件系统分析
4.1 采用FAT格式格式化SD nand/sd卡
1.使用win10格式化一张118.5M的SD nand / sd卡,我这里用的是手上的一颗 创世CS 家的sd nand加一块转接板,和SD卡完全没有区别,且SD nand在稳定性上比SD卡具有优势。
此处由于SD nand(SD卡)大小原因,默认采用FAT16进行了格式化!因此在下文中我们先以FAT16进行分析,之后再重新格式化为FAT32进行分析,就很容易懂了!
4.2 引导扇区分析
2.打开后我们可以以二进制的格式查看SD卡上所有数据,首先看到第一个扇区,也就是对应的引导扇区 boot sector,注意引导扇区位于保留区!
3.接下来我们根据官方文档 对引导扇区进行分析
注意,FAT文件系统数据均采用小端格式!
a) 首先是FAT12/16/32公共部分,(偏移值 0 - 35):
b) 接下来是FAT12/16特有字段(偏移值36)
c) 如果是FAT32,则采用FAT32特有字段解析(偏移值和FAT12/16特有字段一致为36)
虽然此处我们的是FAT16格式,不过此处也将FAT的字段进行描述,方便理解。
以上就是引导扇区内容的详细分析了,通过引导扇区的内容,我们即可知道FAT文件系统依赖的硬件存储空间大小、簇大小、扇区大小以及以及FAT系统版本等重要信息。
同时通过引导扇区的内容,我们便可计算出对应的FAT的四个区域的大小及起始偏移位置等重要信息,接下来计算FAT四个分区的起始位置及大小。
4.3 分区偏移及大小计算
FAT卷总共分为以下四个区域:
1.第一个扇区为引导扇区,存放BPB(BIOS Parameter Block)数据,存放的是FAT卷的配置参数。
2.上述参数中以 BPB_ 命名的字段都是 BPB 的一部分,而以 BS_ 标题命名的字段都不是 BPB 的一部分,而只是引导扇区的一部分
各分区偏移地址及大小如下:
此外,关于FAT区,通常存在一个以上的FAT,如此处所格式化的sd卡便存在两个FAT,对应的偏移地址和大小如下:
4.4 FAT子类型确认
关于FAT的类型是FAT12/16/32确认:FAT类型由数据区内簇的数量决定,除此之外无其他办法!
簇的数量计算公式:CountofClusters = DataSectors / BPB_SecPerClus;
如我们这里:CountofClusters = 242176 / 4 = 60544,所以为 FAT16!
当簇的大小从 512 ~ 32768字节的各种条件下,不同类型FAT对应卷的大小范围如下:
4.4 访问FAT条目
FAT区由一条条FAT条目构成,关于 FAT[N] 对应的条目具体位置计算如下:
格外需要注意的是,不同格式,对应的FAT条目的长度和格式不一样:
此外对于FAT32格式,高4位是保留位,只有低28位有效!
具体如下图所示:
4.5 文件与簇之间的关系
那么文件和簇之间的相互关系又是怎样的呢?我们又是如何准确的找到存放在flash上的文件的呢?接下来让我们看下文件与簇之间的关系映射。
在FAT卷上文件通过目录管理,目录是一个32字节数组组成的目录条目结构,此目录结构包含:文件名、文件大小、时间戳以及文件所在的第一个簇号。
簇号为0和1的簇被保留,由参数BPB_RootClus可知,有效簇从第2号簇开始。FAT[2](2号簇)对应数据区的第一个簇。
因此第N个簇的位置计算公式如下:
FirstSectorofCluster = DataStartSector + (N - 2) * BPB_SecPerClus
每个条目所在的位置,对应一个簇。当文件长度大于一个簇长度时,条目内的值为下一个条目的索引,直到文件所在的最后一个簇,由此构成簇链!文件所在的最有一个簇所对应的FAT条目内的值由一个特殊的值(EOC)组成,它永远不会匹配任何有效的簇号,如下:
存在一些特殊的值被用来做损坏簇的标记,如下:
不过此处需要注意,在FAT12/16系统上,上述特殊值绝不会和任何有效簇匹配,但是在FAT32上有可能,因此为了防止混淆,你在创建FAT32系统的时候应该避免这种情况发生!因此FAT32系统上簇的上限为268435445(大于256M个簇)
FAT条目初始化的时候,FAT[2] 及以后的数据应被初始化为0,指示未被使用处于空闲状态,如果值不为0,则意味着簇被损坏或被使用状态。在FAT12/16系统上,空闲簇的数量未被记录,而在FAT32系统上,FAT32支持FSInfo结构体,里面记录了空闲簇的数量。
关于FAT[0]和FAT[1]:
此两个保留的条目,没有与任何簇有联系;不过具有其他意义,如下:
FAT[0]中的?? 与 BPB_Media 相同;
FAT[1] 记录了错误历史记录:卷脏标志(FAT16:bit15、FAT32:bit31),系统在启动的时候清除此位,正常关闭的时候恢复。
如果此位已经清除,表明上次未被正常关闭,可能存在逻辑卷错误;硬件错误标志(FAT16:bit14、FAT32:bit30)当出现无法恢复的读写错误时清除,表明需要进行全面检查。
关于FAT区域,有两个重点注意事项:
下表展示了不同FAT类型中FAT值所对应的含义解释:
4.6 FSInfo扇区结构及备份引导扇区
此部分内容只在FAT32系统上存在,对于FAT12系统FAT区域大小最大6KB,对于FAT16系统FAT区域最大128KB,但是在FAT32系统上FAT区域通常上达数MB,这是因为FAT32系统支持FSInfo数据结构。
在FAT32系统上新增FSInfo数据结构的原因是:在FAT12/16系统上,想要知道flash上剩余的簇数需要扫描整个FAT区才能计算出来,但随着flash容量的不断扩大,扫描花费的时长越来越长,为了避免扫描浪费过多的时间,因此在FAT32系统上增加了FSInfo结构,用于记录flash上剩余的簇数。
FSInfo数据结构如下:
注意:当扇区大小大于512字节时, 剩余空间采用0x00填充
4.7 FAT目录
FAT目录分为长文件名目录(LFN)以及短文件名目录(SFN),长文件目录是在短文件名目录上的一个扩展,具体采用长文件名还是短文件名由读取FAT文件系统的操作系统决定,如windows;设置长文件名时短文件名也被设置,具有兼容性。
此外,有一个很重要的概念:在FAT文件系统上目录也是一个文件,只是此文件的属性不一样而已。
在所有目录中,有一个比较特殊的是根目录,且根目录作为顶层目录必须存在。
4.7.1 SFN 短文件名目录
目录条目结构如下:
关于目录结构的第一个字段 DIR_Name 的第一个元素 DIR_Name[0] 在目录表中有着特殊作用,如下:
这么设计的意义是什么呢?将 DIR_Name[0] 用作特殊字符,其目录在于方便文件删除!当我们删除一个文件的时候,文件系统并不会将此文件所对应的数据全部删除,因为那样太费时间了,也没有必要,而是直接将对应文件的目录项中的 DIR_Name[0] 修改为 0xE5 即可!
关于文件名字段 DIR_Name,在FAT文件系统中还有如下规定:
以下为文件名存储示例:
4.7.2 LFN长文件名
长文件名是文件名的另外一种存储方式,由于SFN短文件名具有长度、字符等限制,在一些场景下不能很好的满足需求,因此就需要使用到长文件名,关于长文件名的具体内容如下:
长文件名是一个具有特殊属性的目录条目。长文件名目录属性 DIR_Attr 字段的值 ATTR_LONG_NAME = (ATTR_READ_ONLY | ATTR_HIDDEN | ATTR_SYSTEM | ATTR_VOLUME_ID) = 0x0F;
关于长文件名的目录属性如下:
关于长文件名,有以下几点重要概念:
下图是官方关于一个名为 “MultiMediaCard System Summary.pdf” 的长文件名在flash上的长文件名条目,如下所示,一眼没看明白也没关系,后文有实例说明,对长文件名有概念了就行!
关于长文件名的checksum字段和计算,算法如下:
4.7.3 LFN系统对于SFN的兼容
在使用LFN长文件名的系统中,会自动生成SFN短文件名已确保此文件在短文件名的文件系统中可使用。同时为了防止生成的短文件名冲突,SFN的生成采用 名称+数字后缀+扩展 的格式,同时采用以下规则生成SFN:
有损转转换标识为:~,ASCII值为0x7E,十进制126
示例如下:
至此,FAT文件系统的理论部分已经描述完了,接下来我们继续使用winhex对数据进行分析。
继续回顾我们一开始的这张布局图
5.1 保留分区分析
保留分区为第一个分区,其中引导扇区位于保留分区的第一个扇区。
根据 4.3 章节计算结果可知,保留分区起始地址为 0x00,大小 0xC00
保留分区数据如下,保留分区内最重要的内容即为引导扇区,除引导扇区外,其他剩余空间全部保留,采用0x00覆盖。关于引导扇区已在 4.2 章节详细分析,此处不再做介绍。
5.2 FAT区分析
根据 4.3 章节描述,FAT区的起始地址为 0xC00,大小为 0x3B400,此外存在两个FAT区,FAT1和FAT2,起始地址分别为:0xC00、0x1E600,对应地址数据如下:
FAT1 数据:
FAT2 数据如下:
由于此处采用FAT16格式,所以每个FAT条目占据两个字节!
根据上述数据进行分析:
此处可能大家会由疑问,刚刚格式化的sd卡为什么会存在文件内,其实这个是系统文件,格式化后自带的,默认是隐藏的,只有使用winhex才能看到,也就是对应的System Volume Information文件夹。
5.3 根目录区分析
注意,根目录区只有 FAT12 / FAT16 系统上存在,在FAT32系统上不存在此区域。
根目录区用来记录根目录下的文件内容,根据 4.3 章节计算可知,根目录区起始地址为:0x3C000,大小为0x4000,数据内容如下:
以下是对数据字段进行分析后的内容,如下图所示:
格式化之后,默认会生成一个System Volume Infomation的系统文件夹,同时此文件夹是根目录下唯一的一个文件,因此在根目录的数据如上图所示。
至此,根目录区分析完了,同时根目录区的 System Volume Information文件指向数据区第一个簇(2号簇),接下来我们便进入数据区进行分析。
5.4 数据区分析
根据 4.3 章节计算可知,数据区起始地址为:0x40000,大小为242176 * 512 = 0x764 0000,数据内容如下:
对应数据字段分析如下:
System Volume Information 目录下存在两个文件,分别是IndexerVolumeGuid 和 WPSettings.dat。根据上述分析可知:
首先,我们跳转到4号簇上查看IndexerVolumeGuid的数据,对应地址计算方式为:
FirstSectorofCluster = DataStartSector + (N - 2) * BPB_SecPerClus = 512 + (4 - 2) * 4
= 520;
对应地址为: FirstSectorofCluster * BPB_BytsPerSec = 520 * 512 = 0x0004 1000
接着跳转到3号簇上查看WPSettings.dat的数据,对应地址计算方式为:
FirstSectorofCluster = DataStartSector + (N - 2) * BPB_SecPerClus = 512 + (3 - 2) * 4
= 516;
对应地址为: FirstSectorofCluster * BPB_BytsPerSec = 520 * 512 = 0x0004 0800
5.5 新增文件测试
2.新增long file test文件夹,里面存入一个 长度为 2050 Byte(占据两个簇的空间) 的test.txt文件,使用winhex重新打开磁盘进行分析。
根目录区变化如下:
数据区变化如下:
long file test 目录数据指向6号簇,跳转至6号簇,地址 DataStartSector + (N - 2) * BPB_SecPerClus = 0x40000 + (6-2) * 4 * 512 = 0x420000
test.txt 文件指向 7号簇,跳转至7号簇,地址 DataStartSector + (N - 2) * BPB_SecPerClus = 0x40000 + (7-2) * 4 * 512 = 0x428000,均为test.txt的实际有效数据,如下:
6. 总结
以上便是关于FAT文件系统的全部分析了,通过上述分析,外加新增文件辅助理解,对于文件在FAT文件系统下如何管理、存储,相信已经有了非常深入的了解。
FAT文件系统分为四个区:
保留区最重要的是里面包含引导扇区,引导扇区内存放着BIOS参数信息,通过此参数可以知道FAT文件系统的flash布局,以及flash大小,fat块大小、簇大小等关键信息;
FAT区,记录了文件所占用簇的情况,以及对于文件大小大于一个簇的文件,在FAT区内形成簇链,记录文件由哪几个簇组成
根目录区,只有FAT12/16系统所有,记录了根目录下的文件/目录条目信息
数据区,记录数据分为两个部分,第一部分为目录信息,除根目录外,每个文件夹需要占据一个及以上的簇描述对应目录下的文件情况;第二部分为具体文件数据。两部分数据通过短文件名SFN字段进行关联!
以上就是FAT文件系统的简单概括,由于本文使用的是FAT16文件系统作为实例分析,关于FAT32文件系统,在下一篇博文中进行补充,敬请关注!
全部0条评论
快来发表一下你的评论吧 !