FAT12中的12表示的是表项的位数,12位,可以表示2^12 = 4096
个表项,一个簇等于4个扇区大小(以U盘在Windows格式化成FAT为例),一个扇区等于512字节,那么FAT12能支持最大的容量是:
4096 4 512 = 8,388,608 Bytes = 8 MiB
1. FAT12文件系统布局
图1 FAT12文件系统布局
(1)文件分配表FAT占8个扇区
文件分配表占用的空间为:2^12 / 512 = 8个扇区
,为了安全起见,磁盘存放了两份FAT。
这里有一个技术难点,FAT每个表项用12位(1.5个字节)来表示,那么,3个字节表示的是两个表项。
(2)根目录区
根目录区只存放根目录,其他目录和文件存放在数据区。
每个目录表项(FCB,文件控制块)大小为32个字节,一个扇区512字节,因此,一个扇区最多存放16个目录表项。
19 - 32扇区,共14个扇区,用于存放根目录区,因此,FAT12最多只能含有14*16=224
个文件或者目录。
2. 引导扇区
引导扇区(volume boot record, VBR)处在第0个扇区,512字节,包含了文件系统的一些基本信息。
Starting byte | Length (in bytes) | Stored data |
---|---|---|
0 | 11 | Ignore |
11 | 2 | Bytes per sector |
13 | 1 | Sectors per cluster |
14 | 2 | Number of reserved sectors |
16 | 1 | Number of FATs |
17 | 2 | Maximum number of root directory entries |
19 | 2 | Total sector count |
21 | 1 | Ignore |
22 | 2 | Sectors per FAT |
24 | 2 | Sectors per track |
26 | 2 | Number of heads |
28 | 4 | Ignore |
32 | 4 | Total sector count for FAT32 (0 for FAT12 and FAT16) |
36 | 2 | Ignore |
38 | 1 | Boot signature |
39 | 4 | Volume id |
43 | 11 | Volume labeld |
54 | 8 | File system type (e.g. FAT12, FAT16) |
62 | 448 | 引导代码、数据及其他填充字符等 |
510 | 2 | 结束标志,值固定为0xAA55 |
3. 文件分配表
从FAT12文件系统布局图可以看出,数据区是从第33个扇区开始,文件分配表表项的值存放的是逻辑簇号。
这里有个技术难点,12位正好是1.5个字节,这意味着3个字节表示2个表项。
举例,打印出FAT的内容,f8 ff ff 00 f0 ff ff ff ...
,FAT前几个表项的值为:
- ff8
- fff
- 000
- fff
接下来,解释为什么是这样子。
(1)大小端
首先,FAT文件系统是为IBM PC机设计的,字节存储采用的是小端格式(little-endian),即最低有效字节(Least Significant Byte, LSB)放在内存的低地址,举例,一个数0x12345678
,最低有效字节为0x78
。
(2)12位与8位转换
文件分配表读取到内存,可以视为一个数组,每个元素为8位,
下标 | 值 |
---|---|
0 | 76543210 |
1 | 54321098 |
2 | 32109876 |
然而,FAT是每12位表示一个表项,这意味着上述3个字节正好表示两个表项。现在要获取第n
个表项的值,有两种情况:
n
为偶数,取(3*n)/2
上的8位,和1+(3*n)/2
位置上的低4位,接上例,n=0
,取位置1上的低4位,即1098
,那么,FAT第0个表项的值为109876543210
n
为奇数,取(3*n)/2
位置上的高4位,和1+(3*n)/2
上的8位,接上例,n=1
,取位置1上的高4位,即5432
,那么,FAT第0个表项的值为321098765432
4. 根目录区
4.1 文件控制块
目录文件,每个目录项表示一个文件控制块,32字节。文件控制块示意图如下:
各个字段长度及含义如下:
4.2 文件名Filename
文件名8个字节,但有以下两个特殊情况:
- 文件名第一个字节如果是
0xE5
,表示该目录项是空闲的,未被使用 - 文件名第一个字节如果是
0x00
,表示该目录项及后续的目录都是空闲的( this directory entry is free and all the remaining directory entries in this directory are also free)
文件名固定占8个字节,如果文件名少于8个字节,用空格填充(十六进制为0x20
)。
FAT12不分区文件名的大小写,总是以大写的形式存在,
文件和目录不能取相同的名称,尽管属性不一样。
4.3 属性字段Attributes
属性字段是8位,每一位表示一个属性(1
表示拥有该属性),如下:
举例,0001 0010
,表示文件属于为Hidden
(是隐藏文件),subdirectory
(是一个子目录,而不是一个文件)。
值得注意的是,如果属性值为0x0F
,该目录项是长文件名的一部分。
4.4 First logical cluster
该目录或者文件存储在磁盘的第一个簇。
(1)一个簇等于多少个扇区
对于软盘,一个簇等于一个扇区。
对于U盘,如果把U盘在Windows格式化成FAT,一个簇等于4个扇区。
(2)逻辑簇号
磁盘0-32扇区存放的是引导区、文件分配表、根目录区。从第33扇区开始,才是数据区开始的地方,将数据区开始的地址视为逻辑上第一个簇号。
(3)逻辑簇号转换为物理簇号
文件分配表前两个表项保留,在软盘中,簇大小等于扇区大小,那么,物理扇区号为:
物理扇区号 = 33 + FAT entry number - 2
5. 其他
FAT表
- 创建文件(空文件,文件大小为0),不分配簇
- 文件夹大小,始终0
- 时间和日期存储方式:1980-1-1以来,粒度为2s
SYSTEM~1: System Volume
~
表示长文件名,1
是编号,详情见:维基百科文件名
FCB
- 第一项,是卷标名
- 第二项和第三项,System volume information
保留扇区数:8,包含引导扇区,FAT从第8个扇区开始(通过WinHex)
进一步问题:
- read/write功能,写的时候,如何修改FAT表和FCB。
F8 FF FF FF FF FF FF 0F
- FF8
- FFF
- FFF
- FFF
- FFF
后面三个FFF,对于以下三个文件,查看下面三个文件的FCB,可知,其第一个簇号分别为2、3、4
System Volume Information
- IndexerVolumeGuid
- WPSettings.dat
问题:为什么是14?
(For FAT12, 14 sectors * 16 directory entries per sector = 224 possible entries), restricting the total amount of files or directories that can be created therein.
The number of root directory entries available for FAT12 and FAT16 is determined when the volume is formatted, and is stored in a 16-bit field.
For a given number RDE
and sector size SS
, the number RDS
of root directory sectors is RDS = ceil((RDE × 32) / SS)
, and RDE
is normally chosen to fill these sectors, i.e., RDE × 32 = RDS × SS
. FAT12 and FAT16 media typically use 512 root directory entries on non-floppy media. Some third-party tools, like mkdosfs, allow the user to set this parameter.
参考资料: