FAT32文件系统解析

2013-08-22
--luoqindong
以U盘为例,解析FAT32文件系统.
 

FAT32文件系统解析_第1张图片


U盘最小的存储单元为扇区(sector),一扇区为512Bytes,也有1024,2048的,不过一般都使用512Bytes.
U盘的第1扇区为MBR扇区(Master Boot Record),延用硬盘的叫法.
446字节的MBR是操作系统的引导代码,U盘用不上.DPT(Disk Partition Table),分区表,一项占用16字节,可以表示4个分区,

一个分区的U盘只用了第一项.

FAT32文件系统解析_第2张图片

 
Type Code: 表示该分区上使用的文件系统类型, 0x0B或0x0C表示FAT32文件系统类型.
LBA Begin: 该分区开始第一扇区的地址,即DBR扇区的地址.
MBR扇区的最后两字节为0x55,0xAA.


DBR(DOS Boot Record)扇区:

FAT32文件系统解析_第3张图片 


U盘只关心BPB(BIOS Parameter Block)字段

 FAT32文件系统解析_第4张图片


BPB字段包含的信息有
1. 1扇区包含有多少个字节
2. 1簇占多少个扇区
3. 保留的扇区数
4. 有多少份FAT表,为2,另一份为备份.
5. FAT表占用多少个扇区
Partition_LBA_Begin为DPT中的LBA Begin.
(unsigned long)fat_begin_lba = Partition_LBA_Begin + Number_of_Reserved_Sectors; (FAT表开始的Sector号)
(unsigned long)cluster_begin_lba = Partition_LBA_Begin + Number_of_Reserved_Sectors + (Number_of_FATs * Sectors_Per_FAT); (为根目录开始的Sector号)
(unsigned char)sectors_per_cluster = BPB_SecPerClus;(一簇占多少个扇区,一般为8,一簇为4KB)
(unsigned long)root_dir_first_cluster = BPB_RootClus;(根目录开始的簇编号,一般为2)


将簇转换成Sector地址:
lba_addr = cluster_begin_lba + (cluster_number - 2) * sectors_per_cluster; 


根目录
根目录里的数据以32字节为一项,项类型可以是:
1.Normal record with short filename - Attrib is normal 
2.Long filename text - Attrib has all four type bits set 
3.Unused - First byte is 0xE5 
4.End of directory - First byte is zero 
当有文件被删除是就会生产Unused项,该项的Byte1为0xE5,当有文件被创建的时候,可以使用该项.
Byte1为0的项表示目录的结尾.
以下只以short filename为例.

 FAT32文件系统解析_第5张图片

属性字段(1Byte)

FAT32文件系统解析_第6张图片 


通过属性字段可以确定该项对应的是一个普通文件(长文件名和短文件名)或子目录,长文件名的Bit[0~3]=1111B,
而短文件名Bit[0~3] = 0000B.
In FAT32, all files and subdirectories have short names, even if the user gave the file a longer name, 
so you can access all files without needing to decode the long filename records (as long as your code simply ignores them). 
FAT32的文件系统,即使用户给一个文件很长的名字(超过了8.3格式), 所有的文件和目录名称还都是使用短文件名,文件名称可能保存在其他地方了.
short filename项包含了文件名称,文件属性,文件大小,文件所在的第一簇的族号,如果文件的大小大于1簇的大小,
那就需要通过FAT表来取得整个文件了.


FAT32的FAT表(File Allocation Table)
FAT32的FAT表以32Bits为一个单元,每个单元都对应一个簇号.
如4G的U盘,扇区为512Bytes,1簇为4KB(8 Sectors),那FAT表的大小为(不考虑MBR, DBR,FAT表所占用的大小)
4*1024*1024 / 4*1024 = 1024 单元 = 1024*4 Bytes
因为根目录开始的簇编号为2,所以FAT表中的单元0和1不使用(硬盘会用到,U盘不关心这两个单元),每个单元的
内容表示下一簇的簇号,如以下的FAT表:
FAT32文件系统解析_第7张图片

 


FAT表的单元0和1不使用,根目录从第2簇开始,根目录所占用的族为: 0x02,0x09,0x0A,0x0B,0x11簇,
FAT表中的0x11单元内容为0xFFFFFFFF,表示这是根目录的最后一簇.
从根目录找到File #1的第一簇为3,发现File #1的大小大于4KB,所以得到FAT表中查找File #1的下一
簇在哪.FAT 表中的第3单元内容为4,表示下一簇为4,单元4的内容为5表示下一族为5,单元5内容为7表示
下一簇为7,依此类推,直到找到单元内容为0xFFFFFFFF为此,发现最后一簇是8.


参考文档:
<1>Paul's 8051 Code Library Understanding the FAT32 Filesystem
<2>4.5万字透视FAT32系统

你可能感兴趣的:(FAT32文件系统解析)