FAT文件系统结构

本文深入探讨了FAT文件系统,包括FAT12、FAT16、FAT32和ExFAT的不同版本,以及VFAT的长文件名支持。详细介绍了FAT文件系统的结构,如引导记录区、BPB、扩展的引导记录、文件分配表和目录的实现细节。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

FAT文件系统结构

FATFS是一个简单的文件系统,本质上说它是一个巨大的表-簇的链表。是目前最常使用的文件系统之一。

1、FATFS的分类

FAT文件系统有几个不同的版本。每个版本都针对不同大小的存储介质。
(1)、FAT12
FAT12是为软盘设计的,它最大可以管理16MB的大小,因为它使用12位来寻址簇。
(2)、FAT16
FAT16是为早期硬盘设计的,可以处理最大SIZE为64K个簇*簇SIZE。硬盘越大,簇SIZE就越大,因为簇的个数已经确定了,要增大磁盘只能增大簇的SIZE,这就导致了磁盘上大量的“闲置空间”,即是最后一个簇可能浪费大量空间。
(3)、FAT32
FAT32解决了一些FAT的问题。不再是64K的最大簇数目!FAT32实际上只使用了28位起来操作,因为32位簇的数目的最高4位被保留了,并且从未使用过。实际上你可以叫它FAT28。该文件系统可以处理每个分区最多256M(2^28)的簇数目。这使得非常大的硬盘仍然可以保持相当小的簇大小,从而减少文件之间的闲置空间。
(4)、ExFAT
ExFAT是由Microsoft创建的SDXC卡上使用的文件系统。它基本上是FAT32,实际上每个FAT条目使用32位,有一些扩展。
(5)、VFAT
VFAT是FAT文件系统的扩展,它能够使用长文件名(最多255个字符)。

2、实现细节

FAT文件系统将存储媒体视为簇的平面阵列(数组)。存储媒体被组织成三个基本区域

  • 引导记录区
  • 文件分配表(FAT)
  • 目录和数据区域

2.1、引导记录区(Boot Record)

引导记录占用一个扇区,并且总是位于“分区”的逻辑扇区号0中。这是分区上最容易让计算机在加载它时找到的扇区。如果存储媒体是分区的(例如硬盘),那么实际媒体的开头包含MBR (x86)或其他形式的分区信息。在这种情况下,每个分区的第一个扇区保存一个卷引导记录.

2.2、BPB (BIOS 参数块)

引导记录同时包含代码和数据。非代码的数据称为BPB。
在这里插入图片描述

2.3、扩展的引导记录(Extended Boot Record)

扩展的引导记录紧跟BPB后面。开头的数据称为EBPB。它包含不同的信息,这取决于这个分区是FAT12、FAT16还是FAT32文件系统。紧随EBPB之后的是实际的引导代码,然后是标准的0xAA55引导签名,以填充512字节的引导扇区。偏移量显示从标准启动记录开始。
(1)、FAT12和FAT16
在这里插入图片描述
(2)、FAT32
在这里插入图片描述
(3)、FSInfo 机构体 (FAT32 only)
在这里插入图片描述

2.4、文件分配表

文件分配表(FAT)是存储在存储媒体上的一个表,它指示磁盘上所有数据在所有簇上的状态和位置。它可以被认为是磁盘的“目录”。簇可以被使用,它也可能被操作系统保留,它可能由于磁盘上的坏扇区而不可用,或者它可能被一个文件使用。文件的簇不必在磁盘上彼此相邻。事实上,它们很可能散布在整个磁盘中。FAT表允许操作系统在获得一个文件中链接的全部簇。
(1)、FAT 12
FAT12使用12位来处理磁盘上的簇。FAT中的每个12位条目都指向磁盘上的文件的下一个簇。给定一个有效簇号,下面是如何提取集簇链中的下一个簇的值代码:

unsigned char FAT_table[sector_size];
unsigned int fat_offset = active_cluster + (active_cluster / 2);// multiply by 1.5
unsigned int fat_sector = first_fat_sector + (fat_offset / section_size);
unsigned int ent_offset = fat_offset % section_size;
 
//at this point you need to read from sector "fat_sector" on the disk into "FAT_table".
 
unsigned short table_value = *(unsigned short*)&FAT_table[ent_offset];
 
if(active_cluster & 0x0001)
   table_value = table_value >> 4;
else
   table_value = table_value & 0x0FFF;
 
//the variable "table_value" now has the information you need about the next cluster in the chain.

如果“table_value”大于或等于(>=)0xFF8(4088),那么在链中就没有更多的簇。这意味着整个文件已被读取。如果“table_value”等于(==)0xFF7,那么这个簇已经被标记为“bad”。“坏的”簇容易出错,应该避免。如果“table_value”不是上述情况之一,那么它就是文件中下一个簇的簇号。
因为FAT12使用的条目大小不能被8位整除,所以在一个小端机器上计算出如何解释FAT可能会有点让人困惑。考虑0x123和0x456这两个连续的条目。在小端端计算机上,第一个条目的第一个字节是底部的两个半字节 (0x23),最高的半字节进入第二个字节的底部半字节 (0x?1)。由于下一项现在是从字节中间开始的,所以只有最低的半字节能填入字节(0x6?),而最高的两个半字节可以填入下一个字节(0x45)。因此,这两个条目看起来是这样的:0x23 0x61 0x45。
(2)、FAT 16
FAT16使用16位来处理磁盘上的簇。因此,从16位文件分配表中提取值要容易得多。具体做法如下:

unsigned char FAT_table[sector_size];
unsigned int fat_offset = active_cluster * 2;
unsigned int fat_sector = first_fat_sector + (fat_offset / sector_size);
unsigned int ent_offset = fat_offset % sector_size;
 
//at this point you need to read from sector "fat_sector" on the disk into "FAT_table".
 
unsigned short table_value = *(unsigned short*)&FAT_table[ent_offset];
 
//the variable "table_value" now has the information you need about the next cluster in the chain.

如果“table_value”大于或等于(>=)0xFFF8,那么在链中就没有更多的簇了。这意味着整个文件已被读取。如果“table_value”等于(==)0xFFF7,那么这个簇已经被标记为“bad”。“坏的”簇容易出错,应该避免。如果“table_value”不是上述情况之一,那么它就是文件中下一个簇的簇号。 (3)、FAT32 fat32使用28位来处理磁盘上的集群。是的,没错。fat32只使用32位中的28位。最高的4位是保留的。这意味着它们在读取时应该被忽略,而在写入时应该保持不变。除了这个小细节之外,从32位FAT中提取值几乎与对16位FAT进行相同的操作:

unsigned char FAT_table[sector_size];
unsigned int fat_offset = active_cluster * 4;
unsigned int fat_sector = first_fat_sector + (fat_offset / sector_size);
unsigned int ent_offset = fat_offset % sector_size;
 
//at this point you need to read from sector "fat_sector" on the disk into "FAT_table".
 
//remember to ignore the high 4 bits.
unsigned int table_value = *(unsigned int*)&FAT_table[ent_offset] & 0x0FFFFFFF;
 
//the variable "table_value" now has the information you need about the next cluster in the chain.

如果“table_value”大于或等于(>=)0x0FFFFFF8,那么在链中就没有更多的簇了。这意味着整个文件已被读取。如果“table_value”等于(==)0x0FFFFFF7,那么这个簇已经被标记为“bad”。“坏的”簇容易出错,应该避免。如果“table_value”不是上述情况之一,那么它就是文件中下一个簇的簇号。

3、目录

目录项只是存储所需的信息,以了解文件的数据或文件夹的子文件夹在磁盘上的存储位置。它还保存条目的名称、大小和创建时间等信息。FAT文件系统中有两种目录。标准8.3目录项,它出现在所有FAT文件系统中,以及长文件名目录项(可选地出现,以允许更长的文件名)。

3.1、标准的8.3文件格式(目录条目格式)

在这里插入图片描述

3.2、长文件名(目录条目格式)

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值