ExFAT也叫FAT64,是微软专门为可移动设备设计的。它抛弃了之前FAT(FAT12,FAT16,FAT32)系统的许多内部结构,不再兼容之前的FAT。相比较之前的FAT系统,他有几个重要的改进。
- 单个文件大小突破4GB的限制,最大可达到32GB。
- 分区大小突破之前32GB的限制,最大可达到2TB。
- 内部结构调整,实现同样功能的操作,相比较之前的FAT系统,减少读写设备的次数。
- 对DBR表,文件名,文件目录项,等,增加校验字段,提高数据安全性。
ExFAT结构
不同于其他FAT文件系统,ExFAT的用户数据区内有乾坤。
BOOT分区
ExFAT 的BOOT区最少为24个扇区,分成主BOOT区和备份BOOT区,两个区各12个扇区。
引导区结构
typedef struct
{
__u8 jump[3]; // 0x00 jmp and nop instructions
__u8 oem_name[8]; // 0x03 "EXFAT "
__u8 __unused1[53]; // 0x0B always 0
le64_t sector_start; // 0x40 partition first sector
le64_t sector_count; // 0x48 partition sectors count
le32_t fat_sector_start; // 0x50 FAT first sector
le32_t fat_sector_count; // 0x54 FAT sectors count
le32_t cluster_sector_start;// 0x58 first cluster sector
le32_t cluster_count; // 0x5C total clusters count
le32_t rootdir_cluster; // 0x60 first cluster of the root dir
le32_t volume_serial; // 0x64 volume serial number
struct // 0x68 FS version
{
__u8 minor;
__u8 major;
}version;
le16_t volume_state; // 0x6A volume state flags
__u8 sector_bits; // 0x6C sector size as (1 << n)
__u8 spc_bits; // 0x6D sectors per cluster as (1 << n)
__u8 fat_count; // 0x6E always 1
__u8 drive_no; // 0x6F always 0x80
__u8 allocated_percent; // 0x70 percentage of allocated space
__u8 __unused2[397]; // 0x71 always 0
le16_t boot_signature; // the value of 0xAA55
}exfat_super_block_t;
相关LBA计算:
FAT表LBA = 分区偏移量 + FAT表偏移量。
簇堆分配表LBA = 分区偏移量 + 簇堆偏移量。
用户数据区LBA = 分区偏移量 + 簇堆偏移量。
簇LBA = 用户数据区LBA + ((簇号 – 2)<< SectorsPerClusterShift)
EXFAT与之前FAT系统的不同点:
1) FAT表长度,不再由总簇数决定,而是由一个字段指定。
2) 是否为EXFAT系统,不再和总簇数相关。理论上总簇数可以从1 ~ 0x0fffffff。
3) 分区大小,没有明确规定,理论上500K ~ 2TB。
校验和为32bit,用该检验和填写满整个扇区。校验和计算公式如下。
UInt32 exfat_checksum(...)
{
UInt32 NumberOfBytes = (UInt32)BytesPerSector * 11;
UInt32 Checksum = 0;
UInt32 Index;
for (Index = 0; Index < NumberOfBytes; Index++)
{
if ((Index == 106) || (Index == 107) || (Index == 112))
{
continue;
}
Checksum =((Checksum&1) ? 0x80000000 : 0) + (Checksum>>1) + (UInt32)Sectors[Index];
}
return Checksum;
}
该公式计算引导区前面11个扇区的校验和。
FAT区
FAT区分成多个FAT项,每一个FAT项的大小为32bit,类似FAT32。第一、二项为保留,固定填写0x0ffffff8和0xffffffff。对于EXFAT系统,FAT项并非必须填写,和之前的FAT系统存在区别。可以遵从如下规则填写FAT表。
1) 如果文件占用的簇号是连续的,不必填写簇链;
2) 如果文件占用的簇号不连续,最好填写整个完整的簇链。填写簇链的规则和FAT32一致。
3) 如果删除某个文件,可以不用删除FAT表中的FAT项数据,但必须把簇堆分配表中相对应的BIT置为0。
用户数据区
用户数据区包含三个特殊文件,簇堆分配表文件,大写转换表文件和根目录文件。
簇堆分配表
簇堆分配表,记录分区上所有簇的使用情况。每一个bit代表一个簇,0表示空簇,1表示该簇已被占用。起始簇号从2开始,也就是BIT0对应簇号2,BIT1对应簇号3。簇堆分配表以文件存储的方式存在,一般对应根目录下第一个文件,也就是第二个目录项。他的大小由总簇数决定,占用N个簇的空间。
大写转换表
大写表是一张Unicode字符映射图,每一个字符占用2个字节。文件名比较时,先把文件名格式转换成Unicode,再通过该表把文件名转成大写Unicode,转换完成后才进行文件名比较。大写表中的数据进行了部分压缩,压缩起始标志码FFFFh,随后跟一个压缩长度。大写表只对大小写一样的数据进行压缩。
示例:
目录文件
- EXFAT普通目录下没有“。”和“。。”目录项。
- 根目录比较特殊,下