本节介绍 fat32 文件系统的组成部分。
fat32 文件系统的基本组成
网上大部分介绍 fat32 文件系统的文章通常都会按照下图,认为有 4 部分组成。
这当然没有错,只是这么作图有些不太恰当
。在 ubuntu 操作系统中,使用 mkfs.vfat -s2 -F32
命令将 u 盘格式化为 fat32 文件系统,会发现其实文件系统只有 3 个区域
,上图的引导扇区(BPB)实际上是存储在保留区
内部的,如下图:
上图是直接以 16 进制查看格式化后的 u 盘的数据。保留区在整个 u 盘的最前端,里面包含了 BPB 区
和它的一个备份。紧接着就是 fat 表区
。fat 表区
之后一直到 u 盘的最后,都是数据区
了。因此 fat32 文件系统的结构应该如下画才是合适的。
BPB
记录着文件系统的信息,数据将被存放在数据区
,而fat表取
则记录着用来索引数据的信息。用直白的话说,就是BPB
让使用者知道 u 盘叫什么名字,每个扇区多大,一共有多少个扇区等等,当使用者把数据存放在数据区
时,fat表区
负责告诉使用者这些数据存放到哪了。下面详细说说这几个部分。
1. 保留区
如上面所说,保留区在磁盘的最前端,fat12 和 fat16 的保留区通常只有一个扇区那么大,fat32 文件系统在微软的操作系统上,保留区可以为任意扇区大小,典型大小为 32 个扇区。保留区存放着 BPB 和 BPB 的备份。
2. BPB 区
BPB 区记录着磁盘的重要信息,如果 BPB 区的数据损坏了,操作系统就无法识别该磁盘了,只能重新格式化再使用了。那么 BPB 区记录着哪些信息呢?这里以一个 C 语言的结构体做介绍。
typedef struct __BPB
{
__le8 jmpBoot[3]; // EB 58 90
__le8 oemName[8]; // MSWIN4.1
__le16 bytesPerSec; // 每扇区字节数
__le8 secPerClus; // 每簇扇区数
__le16 reservedSecCnt; // 保留的扇区数,典型值 32
__le8 fatsCnt; // fat 表数量,通常为 2
__le16 rootEntCnt; // 根目录项数,fat32文件系统必须设置为 0
__le16 totSet16; // fat32 必须为 0
__le8 media; // 存储类型,0xF8表示可移动存储介质
__le16 fatSecCnt16; // fat32 必须为 0
__le16 secPerTrk; // 每磁道扇区数,参考值 0
__le16 numHeads; // 磁头数,参考值 9
__le32 hiddSec; // 隐藏扇区数,没有的话设置为 0
__le32 totSec32; // 总扇区数
__le32 fatSecCnt32; // 一个 fat 表所占的扇区数
__le16 extFlags; // 0
__le16 fsver; // 0
__le32 rootClus; // 根目录所在的簇号,通常为 2
__le16 fsInfo; // 1
__le16 bkBootSec; // 6
__le8 reserved[12];
__le8 drvType; // 0x00:软盘 0x80:硬盘
__le8 reserved1; // 0
__le8 bootSig; // 0x29
__le32 volID;
__le8 fileSysName[11]; // "NO NAME "
__le8 fileSysType[8]; // "FAT32 "
};
BPB的前 3 个字节是跳转指令,指向启动代码,通常固定为 0xEB 0x58 0x90
。接下来的 8 个字节是 oem 名,有的厂商提供的驱动程序会检测该值,所以建议设置为 MSWIN4.1
,以避免无法识别的情况发生。其他部分见注释,说的比较清楚了,也给出了参考值。
3. fat 表区
fat32 文件系统是以簇
为存储单元的,可在 BPB 中指定每个簇
占几个扇区,而通过 BPB 的介绍,我们知道 fat32 文件系统可以指定扇区的字节数,所以通过设置 BPB,可以决定 fat32 文件系统的最小存储单元。
存储单元是什么意思呢?我们以下图为例:
发现说明文件.txt
的大小只有 107B,但是占用空间却为 4kB,这是为什么呢?其实,这可以用最小存储单元解释。这里的 4kB
即为 fat32 文件系统的簇大小。在存储文件时,哪怕文件只有 1 个字节,它也会占用一个簇,存下一个文件时,将会占用下一个簇。这就解释了为何大小为 107 字节的文件占用空间为 4kB。
fat表的作用就是记录文件占用了哪些簇,fat 表每 4 个字节记录着一个簇。以后需要查询文件时,直接从fat表开始就可以了,不至于摸不着头脑。以上面 16 进制查看的 u 盘数据为例,因为是新格式化的 u 盘,所以整个 u 盘还没有被使用,数据区为空,fat 表区的 0 号和 1 号簇为保留簇,不使用,2 号簇则通常为根目录簇,所以刚格式化还没使用的 u 盘,fat 表记录着 3 个簇。
上面图中标的 fat 表区,实际上是两个 fat 表,其中一个是另一个的备份。
用dosfsck命令可以查看FAT32设备的相关信息:
$ sudo dosfsck -v /dev/ram1
dosfsck 3.0.12 (29 Oct 2011)
dosfsck 3.0.12 , 29 Oct 2011 , FAT32 , LFN
Checking we can access the last sector of the filesystem
Boot sector contents :
System ID " mkdosfs "
Media byte 0 xf8 ( hard disk )
512 bytes per logical sector
512 bytes per cluster
32 reserved sectors
First FAT starts at byte 16384 ( sector 32)
2 FATs , 32 bit entries
516608 bytes per FAT (= 1009 sectors )
Root directory start at cluster 2 ( arbitrary size )
Data area starts at byte 1049600 ( sector 2050)
129022 data clusters (66059264 bytes )
63 sectors / track , 255 heads
0 hidden sectors
131072 sectors total
Checking for unused clusters .
Checking free cluster summary .
/dev/ram1 : 0 files , 1/129022 clusters
4. 数据区
数据区记录的就是数据了,当然,数据区记录的不是纯粹的文件内容,还包括文件名,文件大小,文件的创建时间等属性信息。这个放在下一节详细说说。