FAT32汇总
2015-11-17 09:12
465 查看
FAT32 是不是过时了呢,答案当然是否定的,目前在消费类的电子产品都市使用FAT32文件系统,如手机SD卡,家用摄像机,照相机、MP3等等
其实系统本身都市LINUX,为什么还要用FAT32呢,因为要在windows上使用。还有像用于监控行业录像存储,如预分配、也是很方便的。
====================================================================================================
详细参考
<FAT文件系统原理>
MBR
定义:
http://baike.baidu.com/link?url=Dw-rX5Ua4xpuvbCPtYPnO_BTqpEC5bOAk3u2ZQb_c04ib9WDus1_8RhNONe2-7AEXXUSkY7-fjyV8iHgJ4jm0NnMHhABnZGpX0_EK-maSB_
MBR,全称为Master Boot Record,即硬盘的主引导记录。
为了便于理解,一般将MBR分为广义和狭义两种:广义的MBR包含整个扇区(引导程序、分区表及分隔标识),也就是上面所说的主引导记录;而狭义的MBR仅指引导程序而言。
硬盘的0柱面、0磁头、1扇区称为主引导扇区(也叫主引导记录MBR)。它由三个部分组成,主引导程序、硬盘分区表DPT(DiskPartition
table)和分区有效标志。在总共512字节的主引导扇区里主引导程序(boot
loader)占446个字节,第二部分是Partition
table区(分区表),即DPT,占64个字节,硬盘中分区有多少以及每一分区的大小都记在其中。第三部分是magic
number,占2个字节,固定为0xAA55或0x55AA,这取决于处理器类型[4] ,如果是小端模式处理器[5] (如Intel系列),则该值为0xAA55;如果是大端模式处理器[5] (如Motorola6800),则该值为0x55AA。
MBR是不属于任何一个操作系统,也不能用操作系统提供的磁盘操作命令来读取它,但可以通过命令来修改和重写,如在minix3里面,可以用命令:installboot
-m /dev/c0d0/usr/mdec/masterboot来把masterboot这个小程序写到mbr里面,masterboot通常用汇编语言来编写。我们也可以用ROM-BIOS中提供的INT13H的2号功能来读出该扇区的内容,也可用软件工具Norton8.0中的DISKEDIT.EXE来读取。
http://baike.baidu.com/view/1412956.htm
传统的分区方案(称为MBR分区方案)是将分区信息保存到磁盘的第一个扇区(MBR扇区)中的64个字节中,每个分区项占用16个字节,这16个字节中存有活动状态标志、文件系统标识、起止柱面号、磁头号、扇区号、隐含扇区数目(4个字节)、分区总扇区数目(4个字节)等内容。由于MBR扇区只有64个字节用于分区表,所以只能记录4个分区的信息。这就是硬盘主分区数目不能超过4个的原因。后来为了支持更多的分区,引入了扩展分区及逻辑分区的概念。但每个分区项仍用16个字节存储。
主分区数目不能超过4个的限制,很多时候,4个主分区并不能满足需要。另外最关键的是MBR分区方案无法支持超过2TB容量的磁盘。因为这一方案用4个字节存储分区的总扇区数,最大能表示2的32次方的扇区个数,按每扇区512字节计算,每个分区最大不能超过2TB。磁盘容量超过2TB以后,分区的起始位置也就无法表示了。在硬盘容量突飞猛进的今天,2TB的限制早已被突破。由此可见,MBR分区方案现在已经无法再满足需要了。[2]
(2)DBR包含DOS引导程序和BPB。
(3)BPB十分重要,由此可算出逻辑地址与物理地址。
以上仅DOS(FAT16)为例,由于DOS(FAT16)已经退出历史舞台,但现在0柱面1磁头1扇区这个位置仍然是起着类似的作用,所以准确地说,DBR应该改称为OBR(OSBoot
Record)即操作系统引导扇区,如WINXP的OBR(FAT32或NTFS)就是在DOS的DBR基础逐步演变而来的。OBR(DBR)是高级格式化程序产生的,如FORMAT、PM、DM、DISKPART、WINXP磁盘管理器。
BOOT RECORD,DOS引导记录),位于柱面0,磁头1,扇区1,即逻辑扇区0。DBR分为两部分:DOS引导程序和BPB(BIOS参数块)。其中DOS引导程序完成DOS系统文件(IO.SYS,MSDOS.SYS)的定位与装载,而BPB用来描述本DOS分区的磁盘信息,BPB位于DBR偏移0BH处,共13字节。
它包含逻辑格式化时使用的参数,可供DOS计算磁盘上的文件分配表,目录区和数据区的起始地址,BPB之后三个字提供物理格式化(低格)时采用的一些参数。引导程序或设备驱动程序根据这些信息将磁盘逻辑地址(DOS扇区号)转换成物理地址(绝对扇区号)。
MBR(主引导记录) DBR(OBR操作系统引导记录) FAT
根目录 数据区
SD卡中FAT32文件格式快速入门(图文详细介绍)
http://blog.csdn.net/mjx91282041/article/details/8904705
意思是主引导记录。位于硬盘的0柱面、0磁头、1扇区。
MBR
大小为1个扇区,512字节。
下面是MBR的结构:
偏移 构成部分及作用
0-138 引导程序(139字节),检测所有分区,识别出活动分区
139-217 提示信息区(79字节),存放报错信息
218-445 保留区(228字节),未用
446-509 分区信息表(64字节),可存放4个分区的基本信息
510-511 结束标志(2字节),55AA
MBR的主要功能主要有两个:检测分区和存放分区信息。
虚拟MBR:指MBR将硬盘定义为两个分区,即主分区和扩展分区(通常是除主分区外剩余的所有硬盘空间),然后再扩展分区上咋定义主分区和扩展分区,知道所有分区定义完毕。
虚拟MBR的作用主要是定义分区,所以它只包含分区信息表,不包含引导程序和提示信息。
分区表位于MBR内,占64个字节,可以描述4个分区的信息。
分区表结构:
字节 值 含义
0 80 活动分区标志,00为非活动分区
1 01 起始磁头号01
2 01 起始扇区号01
3 00 起始柱面号00
4 07 NTFS分区
5 FE 结束磁头号254
6 FF 结束扇区号63
7 FF 结束柱面号1023
8-11 3F
00 0000 本分区之前已用63个扇区
12-15 FC
8A 3801
本分区扇区总数为20482
812
常用分区类型:
分区类型 含义 分区类型 含义
05 扩展分区 16 隐藏FAT16
06 FAT16 17 隐藏NTFS/HPFS
07 NTFS 1B 隐藏FAT32
0B Windows 95FAT32 1C 隐藏FAT32
0C Windows
95FAT32 82 Linuxswap 分区
0E Windows 95FAT16 83 Linux
分区
0F Windows
95 扩展分区 A6 Open
BSD
FAT文件系统分为三个部分:保留区、FAT区和数据区,如下所示:
|---保留区
---|--- FAT1---|--- FAT2 ---|--- 数据区 ---|
1. 保留区中包含文件系统的一些总体信息,类似于unix文件系统里的超级块信息。
2. FAT区包含文件的分配表链。
3. 数据区存放实际的文件数据(目录的数据为目录项列表)。
FAT32
的“数据区域”是真正用来存储用户数据的区域。
数据区域紧跟在FAT
区域之后,数据区域被划分为一个个的簇,所有的簇从2号开始编码,也就是说2号簇就是数据区域的起始位置。
FAT表(文件内容族链)
[4字节]
[4字节] [4字节]
[4字节] [4字节]
保留
保留
2号族
数据区
文件列表(文件元信息)
[32字节]
[32字节] [32字节]
[32字节] [32字节]
文件内容(用户数据)
http://blog.163.com/ourhappines@126/blog/static/121363154201311834528623/
心得:
FAT表中的每一项的地址编号(从0开始)就是数据区的族号(数据区每一族的编号就顺序的记录在FAT表中,就是地址编号,表项的值记录了族的状态:下一族,坏族,未用族),表项的值就是地址编号族的下一族,地址编号和地址编号的值都是族号,这样文件所属族就形成了族链(单项链表)。FAT表项0
1号系统预留,从2号开始分配给数据区,即从数据区分配的族从2号开始计数。文件的第一族号在目录项中,目录(文件夹)是不占用族号的,因不分配族空间,只在根目录中占用目录项(32字节).
文件读取:目录项族号(就是FAT表项的地址编号),地址编号的值就是下一个族号,依次类推,直到0x0FFFFFFF(小尾存储,从右往左)结束标志。根目录(存储文件或文件夹的元信息,本人习惯叫目录表)都属于数据区范围,文件系统创建时同时创建根目录,即分配2号族,如果一个族不够,则继续分配,则有可能根目录的族是不连续的。与数据族(存储文件内容的族)
交错存储。
FAT32本身没有限制目录项书目,即没有限制根目录大小(根目录就是目录表),根目录根普通目录(文件或文件夹)一样,也是又族链组成;网上很多说最大支持65536个目录项,那是短文件名,如果是长文件名就更少,如2015-08-13_07-46-09_00371_A.mp4=31字节,则占用4个目录项(3个长文件名项
1个短文件名项),65536/4=16384个目录项,即最大支持16384个目录(包括文件及文件夹)。今天看了LINUX(3.18.2)内核代码,果真是这样,原来是文件系统实现者做了限制,这一点在windows和linux都得到了验证。
msdos_fs.h:30行
:
#defineMSDOS_DIR_BITS
5
/* log2(sizeof(struct msdos_dir_entry)) */
/*directory limit */
#defineFAT_MAX_DIR_ENTRIES
(65536)
#defineFAT_MAX_DIR_SIZE
(FAT_MAX_DIR_ENTRIES<< MSDOS_DIR_BITS) = 65536*32=2,097,152
限制了最大目录项,也就限制了根目录大小,即为2M。
如果族为4K,则根目录所分配的族数量最大为512个族。512*4K=2M
添加目录项的实现在fs/fat/dir.c
fat_add_entries 1292
根目录满了后,如果有删除的目录项(第一个字节为0xE5),则会复用该项。何时复用,这个可能不同系统实现不一样。
FAT32 FAT区__FAT表解析
一、
FAT 表概述位置:
紧跟在文件系统的“保留区”之后
;
有两个数据结构完全相同的FAT(FAT,FileAllocation Tbale
文件分配表)组成。
作用:FAT表项,描述文件系统内的簇分配状态,说明文件系统内数据所分配的连续簇的顺序关系(即表明文件或目录的下一簇的序号)。常规规则:·
数量:通常情况下一个FAT
文件系统会有两个FAT
表,
但有时候也会允许只有一个FAT
表, FAT
表的具体个数记录在引导扇区的
偏移 0x10
字节处。[b]位置:[/b]因为FAT区位于文件系统的保留区之后,所以FAT1在文件系统中的位置可以通过引导记录中偏移0x0E~0x0F
字节处的“保留扇区”数得到。
· FAT2 紧跟在FAT1之后,
它的位置可以通过FAT1的位置加上每个FAT
表的大小扇区数获得。FAT
表中记录了每个文件的簇链结构;
FAT
表中记录的与数据区簇对应的表项,从0号标记开始至当前数据区所分配的簇的最大数值,记录簇信息到FAT
项;但是注意:其中 0号~1号簇的值都是操作系统预先不留设定的特殊标记,而数据区的起始簇是2号簇。
二、、FAT
表的特性
FAT 表由一些[b]列大小相等的表项组成,有如下特性:
· FAT32 中每个簇的状态,使用32bit(4字节)记录在FAT表中。
FAT 表中的所有字节位置以 4个字节为单位进行划分;并以所有划分后的位置由0进行地址编号。“0号
和 1号”
地址被系统保留并存储特殊标识内容。从 2号
地址开始,
每个地址对应于数据区的簇号,
FAT
表中的地址编号与数据区中的簇号相同。
[/b]称FAT
中的这些四字节一组划分的项的地址为 FAT
表项,
FAT表项中记录的值为FAT
表项值。(簇编号与簇内内容关系如果
Map中的键-值
关系相同)
当文件系统创建时(就是格式化操作时),
分配给FAT
区域的空间将会被清空,
在FAT1与FAT2
的0号和1号表项写入特定值。
由于创建文件系统的同时,也会创建根目录,
也就是为根目录分配了一个簇空间,通常为2号簇,所以2号簇所对应的“2号FAT表项”也会被写入一个结束标记。
· 如果某个簇未被使用,他所对应的FAT
表项内的FAT
表项值即用0进行填充,表示该FAT
表项所对应的簇未被分配使用
· 当某个簇被分配使用时,那么他所对应的FAT表项的值为文件的下一个存储文件的簇号。
如果该文件结束于该簇,则在它的FAT表项中记录的是一个文件结束标记,对于FAT32
而言,代表[b]文件结束的[/b]FAT表项值为0x0FFFFFFF。
· 如果某个簇存在坏扇区,则整个簇会用FAT
表项值
0x0FFFFFF7
标记为坏簇,
不再使用,这个坏簇标记就记录在它所对应的FAT表项中。
· 由于簇号起始于2,
所以FAT表的0号表项与1号表项不予任何簇对应。
FAT32
的0号表项值总是“F8FFFF0F”注意:
可以搜索扇区偏移0字节处的该值(F8FFF0F)以查找FAT表。
· [b]1[/b]号表项可能被用于记录“脏标志”,
以说明文件系统没有被正常卸载或者磁盘表面存在错误。
不过此值似乎不重要,正常情况下,1号表项值“FFFFFFFF”或“FFFFFF0F”
项内容填写规则:
·在文件系统中新建文件时,如果新建的文件只有一个簇,为其分配的簇所对应的FAT表项将会被写入结束标记。如果新建的文件不只占用一个簇,则在其所占用的每个簇对应的FAT表项中写入为其分配的下一个簇的簇号,在最后一个簇对应的FAT
表项中写入结束标记。
· 新建目录时,只为其分配一个簇的空间,对应的FAT
表项中写入结束标记。当目录增大超过一个簇的大小时,将会在空闲空间中继续为其分配一个簇,并在FAT
表中为其建立FAT
表链以描述它所占用的簇的情况。
· 对文件或目录进行删除操作时,他们所对应的FAT
表项将会被清空,设置为0以表示其所对应的簇处于未分配的状态。
三、 FAT表的使用
一个文件的"起始簇号"记录在它的目录项中,
该文件的 "其他簇"
则用一个簇连结构记录在FAT
表中。
如果一个簇所对应的FAT表项的表项值为非零,
则表明该簇已经被分配使用了,但是这时表项值可能为两种情况,一个是一个文件的下一个簇号值,也有可能是一个文件的结束标记0x0FFFFFFF,或者是一个坏簇标记0x0FFFFFF7
。
如果要寻找一个文件的下一个簇,只需要查看该文件的目录项中描述的起始簇号所对应的FAT项,如果该文件只有一个簇,则此处的值为一个结束标记0x0FFFFFFF;如果该文件不只一个簇,则此处
的值是它的下一个簇的簇号。
[b]>> [/b]查询簇连接结构模拟步骤:
当我们要寻找某个文件时,
首先从该文件的“目录项”中获取该文件的第一“簇”的簇号,然后根据“第一簇”的“簇号
N”,然后根据N
从FAT区的FAT表找出N簇号所对应的FAT
表项,查看FAT
表项的内容:
若是文件结束,该表项值为 0x0FFFFFFF;
若是没有结束,而该文件的大小超出一个簇,则N所对应的FAT表项的表项值为该文件下一个簇的簇号,然后再找到下一个簇号N+1
所对应的FAT表项,查看其表项值,依次类推,就推出了一个文件在FAT表中的
簇链连接结构;
也或者表项值为 0xFFFFFFF7
坏簇标识。
[b]>> [/b]其他查找FAT
表项:
要找到一个簇的FAT
表项,只要用他的
簇号乘以每个FAT
表项的字节数即可
。对于FAT32而言,每个FAT
表项占用4个四字节,
如果我们寻找9号簇的表项位置,则用
4*9=36,也就是说位于FAT
表内偏移36(0x24)字节处。
注意:
WinHex 提供了直接跳转到某个指定FAT
表项的功能。
文件系统大小的上限值却绝育FAT
项的大小。
簇链中的每个FAT
项记录着下一个簇的簇地址,FAT
项所能表示的数字有一个上限,这个上限也就是文件系统中的最大簇号。 FAT 32文件系统的FAT
项只使用了32bit
中的28bit
,因此只能描述 268435456个簇(实际上还要考略小于这个值,因为这其中还包含了结束标志及坏簇标志的保留值)。
操作系统通过检测FAT
表中的表项来确定文件系统中的各个簇是否被分配使用。当我们在Windows
下右击某个FAT
分区查看其属性时,显示的已用空间和未用空间就是根据FAT
表统计而来的。
有时我们会遇到,查看属性时发现已用空间并没有减少,但存储的文件却不见了。这是因为某些病毒在某些文件的目录项中写入了删除标记,但并没有清楚FAT
表内的簇链所至
FAT32系统中长文件名的存储
http://blog.csdn.net/yanpingsz/article/details/5597893
短目录结构
typedef struct
{
//
FILE_NAME DIR_Name;
//短文件名
uint8 NAME[8];
//文件名
uint8 TYPE[3];
//文件类型
uint8 DIR_Attr;
//文件属性
uint8 DIR_NTRes;
//保留
uint8 DIR_CrtTimeTeenth;
//文件创建时间的10
毫秒位
uint16 DIR_CrtTime;
//文件创建时间
uint16 DIR_CrtDate;
//文件创建日期
uint16 DIR_LastAccDate;
//文件最后访问日期
uint16 DIR_FstClusHI;
//文件起始簇号的高16
位
uint16 DIR_WrtTime;
//文件的最近修改时间
uint16 DIR_WrtDate;
//文件的最近修改日期
uint16 DIR_FstClusL0;
//文件起始簇号
uint32 DIR_FileSize;
//文件的长度
}__attribute__((packed))DIR;
来自linux内核
Msdos_fs.h
struct msdos_dir_entry {
__u8
name[MSDOS_NAME];/* name and extension */
__u8
attr;
/*attribute bits */
__u8
lcase;
/*Case for base and extension */
__u8
ctime_cs;
/*Creation time, centiseconds (0-199) */
__le16
ctime;
/*Creation time */
__le16
cdate;
/*Creation date */
__le16
adate;
/*Last access date */
__le16
starthi;
/*High 16 bits of cluster in FAT32 */
__le16
time,date,start;/* time, date and firstcluster */
__le32
size;
/*file size (in bytes) */
};
typedef struct
{
uint8 LDIR_Ord;
//长目录项在本组中的序号
uint8 LDIR_Name1[10];
//长文件名的1-5个字符
uint8 LDIR_Attr;
//长文件名目录项标志
uint8 LDIR_Type;
//为0表示长文件名的子项
uint8 LDIR_Chksum;
//校验值(根据短文件名计算得出)
uint8 LDIR_Name2[12];
//长文件名的6-11个字符
uint16 LDIR_FstClusL0;
//文件起始簇号(常置0)
uint8 LDIR_Name3[4];
//长文件名的12-13个字符
}__attribute__((packed))LDIR;
BPB of DBR
typedef struct
{
uint8BS_jmpBoot[3];
//跳转指令
uint8BS_OEMName[8];
//厂商标志和os版本号
uint16BPB_BytesPerSec;
//扇区字节数
uint8BPB_SecPerClus;
//每簇扇区数
uint16BPB_RsvdSecCnt;
//保留扇区数
uint8BPB_NumFATs;
//FAT 数
uint16BPB_RootEntCnt;
//根目录项数(FAT32必须设置为0)
uint16BPB_TotSec16;
//小扇区数(FAT32必须设置为0)
uint8BPB_Media;
//媒体描述符:有关媒体被使用的信息。值0xF8表示硬盘。
uint16BPB_FATSz16;
//每FAT扇区数(FAT32必须设置为0)
uint16BPB_SecPerTrk;
//每道扇区数
uint16BPB_NumHeads;
//磁头数
uint32BPB_HiddSec;
//隐藏扇区数:该分区上引导扇区之前的扇区数
uint32BPB_TotSec32;
//总扇区数:
本字段包含FAT32分区中总的扇区数
uint32BPB_FATSz32;
//每FAT扇区数:该分区每个FAT所占的扇区数
uint16BPB_ExtFlags;
//扩展标志
uint16BPB_FSVer;
//文件系统版本:只供FAT32使用
uint32BPB_RootClus;
//根目录簇号
uint16BPB_FSInfo;
//FAT32分区中的FSINFO结构所占的扇区数
uint16BkBootSec;
//FAT32分区的保留区中引导记录的备份数据所占的扇区号
uint8BPB_Reserved[12];
//保留(用于FAT扩展使用)
uint8BS_DrvNum;
//物理驱动器号与BIOS物理驱动器号有关
uint8BS_Reservedl;
//保留
uint8BS_BootSig;
//扩展引导标签:本字段必须要有能被Windows2000
所识别的值0x28或0x29
uint32BS_VolID;
//分区序号在格式化磁盘时所产生的一个随机序号,
uint8BS_VolLab[11];
//卷标签
uint8BS_FilSysType[8];
//系统ID(FAT32)
uint8ExecutableCode[420];
uint8ExecutableMarker[2];
//55AA
}__attribute__((packed)) FAT_BPB;
来自linux内核的msdos_fs.h
struct fat_boot_sector {
__u8
ignored[3];
/* Boot strap short or near jump */
__u8
system_id[8];
/* Name - can be used to special case
partition manager volumes */
__u8
sector_size[2];
/* bytes per logical sector */
__u8
sec_per_clus;
/* sectors/cluster */
__le16
reserved;
/*reserved sectors */
__u8
fats;
/*number of FATs */
__u8
dir_entries[2];
/* root directory entries */
__u8
sectors[2];
/* number of sectors */
__u8
media;
/*media code */
__le16
fat_length;
/*sectors/FAT */
__le16
secs_track;
/*sectors per track */
__le16
heads;
/*number of heads */
__le32
hidden;
/*hidden sectors (unused) */
__le32
total_sect;
/*number of sectors (if sectors == 0) */
union{
struct{
/*
Extended BPB Fields for FAT16 */
__u8
drive_number;
/* Physical drive number */
__u8
state;
/*undocumented, but used
for mount state. */
__u8
signature; /* extended boot signature */
__u8
vol_id[4];
/*volume ID */
__u8
vol_label[11];
/* volume label */
__u8
fs_type[8];
/* file system type */
/*other fiealds are not added here */
}fat16;
struct{
/*only used by FAT32 */
__le32
length;
/*sectors/FAT */
__le16
flags;
/*bit 8: fat mirroring,
low 4: active fat */
__u8
version[2];
/* major, minor filesystem
version */
__le32
root_cluster;
/*first cluster in
root directory */
__le16
info_sector;
/*filesystem info sector */
__le16
backup_boot;
/*backup boot sector */
__le16
reserved2[6];
/*Unused */
/*Extended BPB Fields for FAT32 */
__u8
drive_number;
/* Physical drive number */
__u8
state;
/* undocumented, but used
for mount state. */
__u8
signature; /* extended boot signature */
__u8
vol_id[4];
/*volume ID */
__u8
vol_label[11];
/* volume label */
__u8
fs_type[8];
/* file system type */
/*other fiealds are not added here */
}fat32;
};
};
短文件格式的目录项。其参数意义见表14:
系统将长文件名以13个字符为单位进行切割,每一组占据一个目录项。所以可能一个文件需要多个目录项,这时长文件名的各个目录项按倒序排列在目录表中,以防与其他文件名混淆。
长文件名中的字符采用unicode形式编码(一个巨大的进步哦),每个字符占据2字节的空间。其目录项定义如表15。
系统在存储长文件名时,总是先按倒序填充长文件名目录项,然后紧跟其对应的短文件名。从表15可以看出,长文件名中并不存储对应文件的文件开始簇、文件大小、各种时间和日期属性。文件的这些属性还是存放在短文件名目录项中,一个长文件名总是和其相应的短文件名一一对应,短文件名没有了长文件名还可以读,但长文件名如果没有对应的短文件名,不管什么系统都将忽略其存在。所以短文件名是至关重要的。
在不支持长文件名的环境中对短文件名中的文件名和扩展名字段作更改(包括删除,因为删除是对首字符改写E5H),都会使长文件名形同虚设。
(长文件名如何与短文件名对应?仅靠她们之间的位置关系?)
长文件名和短文件名之间的联系光靠他们之间的位置关系维系显然远远不够。其实,长文件名的0xD字节的校验和起很重要的作用,此校验和是用短文件名的11个字符通过一种运算方式来得到的。系统根据相应的算法来确定相应的长文件名和短文件名是否匹配。这个算法不太容易用公式说明,我们用一段c程序来加以说明。
假设文件名11个字符组成字符串shortname[],校验和用chknum表示。得到过程如下:
inti,j,chknum=0;
for (i=11; i>0; i--)
chksum = ((chksum & 1) ? 0x80 :0) + (chksum >> 1) + shortname[j++];
如果通过短文件名计算出来的校验和与长文件名中的0xD偏移处数据不相等。系统无论如何都不会将它们配对的。
依据长文件名和短文件名对目录项的定义,加上对簇的编号和链接,FAT32上数据的读取便游刃有余了。
工具WINHEX
FAT32系统中长文件名的存储http://blog.csdn.net/yanpingsz/article/details/5597893
FAT32文件系统为什么用96字节而不是32字节来描述文件?http://zhidao.baidu.com/link?url=3EDf9bEIpU-T0MHutrw_2o-dKhVUFkGpu3edMukY_-M0q7P15OcKdDHyvJMFD6ek3Sa-QSE6iGV7bT4pcKrdaa
转发至微博
其实系统本身都市LINUX,为什么还要用FAT32呢,因为要在windows上使用。还有像用于监控行业录像存储,如预分配、也是很方便的。
====================================================================================================
详细参考
<FAT文件系统原理>
MBR
定义:
http://baike.baidu.com/link?url=Dw-rX5Ua4xpuvbCPtYPnO_BTqpEC5bOAk3u2ZQb_c04ib9WDus1_8RhNONe2-7AEXXUSkY7-fjyV8iHgJ4jm0NnMHhABnZGpX0_EK-maSB_
MBR,全称为Master Boot Record,即硬盘的主引导记录。
为了便于理解,一般将MBR分为广义和狭义两种:广义的MBR包含整个扇区(引导程序、分区表及分隔标识),也就是上面所说的主引导记录;而狭义的MBR仅指引导程序而言。
硬盘的0柱面、0磁头、1扇区称为主引导扇区(也叫主引导记录MBR)。它由三个部分组成,主引导程序、硬盘分区表DPT(DiskPartition
table)和分区有效标志。在总共512字节的主引导扇区里主引导程序(boot
loader)占446个字节,第二部分是Partition
table区(分区表),即DPT,占64个字节,硬盘中分区有多少以及每一分区的大小都记在其中。第三部分是magic
number,占2个字节,固定为0xAA55或0x55AA,这取决于处理器类型[4] ,如果是小端模式处理器[5] (如Intel系列),则该值为0xAA55;如果是大端模式处理器[5] (如Motorola6800),则该值为0x55AA。
MBR是不属于任何一个操作系统,也不能用操作系统提供的磁盘操作命令来读取它,但可以通过命令来修改和重写,如在minix3里面,可以用命令:installboot
-m /dev/c0d0/usr/mdec/masterboot来把masterboot这个小程序写到mbr里面,masterboot通常用汇编语言来编写。我们也可以用ROM-BIOS中提供的INT13H的2号功能来读出该扇区的内容,也可用软件工具Norton8.0中的DISKEDIT.EXE来读取。
http://baike.baidu.com/view/1412956.htm
MBR分区表
MBR分区表传统的分区方案(称为MBR分区方案)是将分区信息保存到磁盘的第一个扇区(MBR扇区)中的64个字节中,每个分区项占用16个字节,这16个字节中存有活动状态标志、文件系统标识、起止柱面号、磁头号、扇区号、隐含扇区数目(4个字节)、分区总扇区数目(4个字节)等内容。由于MBR扇区只有64个字节用于分区表,所以只能记录4个分区的信息。这就是硬盘主分区数目不能超过4个的原因。后来为了支持更多的分区,引入了扩展分区及逻辑分区的概念。但每个分区项仍用16个字节存储。
主分区数目不能超过4个的限制,很多时候,4个主分区并不能满足需要。另外最关键的是MBR分区方案无法支持超过2TB容量的磁盘。因为这一方案用4个字节存储分区的总扇区数,最大能表示2的32次方的扇区个数,按每扇区512字节计算,每个分区最大不能超过2TB。磁盘容量超过2TB以后,分区的起始位置也就无法表示了。在硬盘容量突飞猛进的今天,2TB的限制早已被突破。由此可见,MBR分区方案现在已经无法再满足需要了。[2]
硬盘DBR编辑
(1)DBR位于柱面0、磁头1、扇区1,其逻辑扇区号为0(2)DBR包含DOS引导程序和BPB。
(3)BPB十分重要,由此可算出逻辑地址与物理地址。
以上仅DOS(FAT16)为例,由于DOS(FAT16)已经退出历史舞台,但现在0柱面1磁头1扇区这个位置仍然是起着类似的作用,所以准确地说,DBR应该改称为OBR(OSBoot
Record)即操作系统引导扇区,如WINXP的OBR(FAT32或NTFS)就是在DOS的DBR基础逐步演变而来的。OBR(DBR)是高级格式化程序产生的,如FORMAT、PM、DM、DISKPART、WINXP磁盘管理器。
常见问题
DBR(DOSBOOT RECORD,DOS引导记录),位于柱面0,磁头1,扇区1,即逻辑扇区0。DBR分为两部分:DOS引导程序和BPB(BIOS参数块)。其中DOS引导程序完成DOS系统文件(IO.SYS,MSDOS.SYS)的定位与装载,而BPB用来描述本DOS分区的磁盘信息,BPB位于DBR偏移0BH处,共13字节。
它包含逻辑格式化时使用的参数,可供DOS计算磁盘上的文件分配表,目录区和数据区的起始地址,BPB之后三个字提供物理格式化(低格)时采用的一些参数。引导程序或设备驱动程序根据这些信息将磁盘逻辑地址(DOS扇区号)转换成物理地址(绝对扇区号)。
MBR(主引导记录) DBR(OBR操作系统引导记录) FAT
根目录 数据区
SD卡中FAT32文件格式快速入门(图文详细介绍)
http://blog.csdn.net/mjx91282041/article/details/8904705
MBR和分区表http://blog.sina.com.cn/s/blog_68ff00380100rs0h.html
MBR意思是主引导记录。位于硬盘的0柱面、0磁头、1扇区。
MBR
大小为1个扇区,512字节。
下面是MBR的结构:
偏移 构成部分及作用
0-138 引导程序(139字节),检测所有分区,识别出活动分区
139-217 提示信息区(79字节),存放报错信息
218-445 保留区(228字节),未用
446-509 分区信息表(64字节),可存放4个分区的基本信息
510-511 结束标志(2字节),55AA
MBR的主要功能主要有两个:检测分区和存放分区信息。
虚拟MBR:指MBR将硬盘定义为两个分区,即主分区和扩展分区(通常是除主分区外剩余的所有硬盘空间),然后再扩展分区上咋定义主分区和扩展分区,知道所有分区定义完毕。
虚拟MBR的作用主要是定义分区,所以它只包含分区信息表,不包含引导程序和提示信息。
分区表位于MBR内,占64个字节,可以描述4个分区的信息。
分区表结构:
字节 值 含义
0 80 活动分区标志,00为非活动分区
1 01 起始磁头号01
2 01 起始扇区号01
3 00 起始柱面号00
4 07 NTFS分区
5 FE 结束磁头号254
6 FF 结束扇区号63
7 FF 结束柱面号1023
8-11 3F
00 0000 本分区之前已用63个扇区
12-15 FC
8A 3801
本分区扇区总数为20482
812
常用分区类型:
分区类型 含义 分区类型 含义
05 扩展分区 16 隐藏FAT16
06 FAT16 17 隐藏NTFS/HPFS
07 NTFS 1B 隐藏FAT32
0B Windows 95FAT32 1C 隐藏FAT32
0C Windows
95FAT32 82 Linuxswap 分区
0E Windows 95FAT16 83 Linux
分区
0F Windows
95 扩展分区 A6 Open
BSD
FAT文件系统分为三个部分:保留区、FAT区和数据区,如下所示:
|---保留区
---|--- FAT1---|--- FAT2 ---|--- 数据区 ---|
1. 保留区中包含文件系统的一些总体信息,类似于unix文件系统里的超级块信息。
2. FAT区包含文件的分配表链。
3. 数据区存放实际的文件数据(目录的数据为目录项列表)。
FAT32
的“数据区域”是真正用来存储用户数据的区域。
数据区域紧跟在FAT
区域之后,数据区域被划分为一个个的簇,所有的簇从2号开始编码,也就是说2号簇就是数据区域的起始位置。
FAT表(文件内容族链)
[4字节]
[4字节] [4字节]
[4字节] [4字节]
保留
保留
2号族
数据区
文件列表(文件元信息)
[32字节]
[32字节] [32字节]
[32字节] [32字节]
文件内容(用户数据)
http://blog.163.com/ourhappines@126/blog/static/121363154201311834528623/
心得:
FAT表中的每一项的地址编号(从0开始)就是数据区的族号(数据区每一族的编号就顺序的记录在FAT表中,就是地址编号,表项的值记录了族的状态:下一族,坏族,未用族),表项的值就是地址编号族的下一族,地址编号和地址编号的值都是族号,这样文件所属族就形成了族链(单项链表)。FAT表项0
1号系统预留,从2号开始分配给数据区,即从数据区分配的族从2号开始计数。文件的第一族号在目录项中,目录(文件夹)是不占用族号的,因不分配族空间,只在根目录中占用目录项(32字节).
文件读取:目录项族号(就是FAT表项的地址编号),地址编号的值就是下一个族号,依次类推,直到0x0FFFFFFF(小尾存储,从右往左)结束标志。根目录(存储文件或文件夹的元信息,本人习惯叫目录表)都属于数据区范围,文件系统创建时同时创建根目录,即分配2号族,如果一个族不够,则继续分配,则有可能根目录的族是不连续的。与数据族(存储文件内容的族)
交错存储。
FAT32本身没有限制目录项书目,即没有限制根目录大小(根目录就是目录表),根目录根普通目录(文件或文件夹)一样,也是又族链组成;网上很多说最大支持65536个目录项,那是短文件名,如果是长文件名就更少,如2015-08-13_07-46-09_00371_A.mp4=31字节,则占用4个目录项(3个长文件名项
1个短文件名项),65536/4=16384个目录项,即最大支持16384个目录(包括文件及文件夹)。今天看了LINUX(3.18.2)内核代码,果真是这样,原来是文件系统实现者做了限制,这一点在windows和linux都得到了验证。
msdos_fs.h:30行
:
#defineMSDOS_DIR_BITS
5
/* log2(sizeof(struct msdos_dir_entry)) */
/*directory limit */
#defineFAT_MAX_DIR_ENTRIES
(65536)
#defineFAT_MAX_DIR_SIZE
(FAT_MAX_DIR_ENTRIES<< MSDOS_DIR_BITS) = 65536*32=2,097,152
限制了最大目录项,也就限制了根目录大小,即为2M。
如果族为4K,则根目录所分配的族数量最大为512个族。512*4K=2M
添加目录项的实现在fs/fat/dir.c
fat_add_entries 1292
根目录满了后,如果有删除的目录项(第一个字节为0xE5),则会复用该项。何时复用,这个可能不同系统实现不一样。
FAT32 FAT区__FAT表解析
一、
FAT 表概述位置:
紧跟在文件系统的“保留区”之后
;
有两个数据结构完全相同的FAT(FAT,FileAllocation Tbale
文件分配表)组成。
作用:FAT表项,描述文件系统内的簇分配状态,说明文件系统内数据所分配的连续簇的顺序关系(即表明文件或目录的下一簇的序号)。常规规则:·
数量:通常情况下一个FAT
文件系统会有两个FAT
表,
但有时候也会允许只有一个FAT
表, FAT
表的具体个数记录在引导扇区的
偏移 0x10
字节处。[b]位置:[/b]因为FAT区位于文件系统的保留区之后,所以FAT1在文件系统中的位置可以通过引导记录中偏移0x0E~0x0F
字节处的“保留扇区”数得到。
· FAT2 紧跟在FAT1之后,
它的位置可以通过FAT1的位置加上每个FAT
表的大小扇区数获得。FAT
表中记录了每个文件的簇链结构;
FAT
表中记录的与数据区簇对应的表项,从0号标记开始至当前数据区所分配的簇的最大数值,记录簇信息到FAT
项;但是注意:其中 0号~1号簇的值都是操作系统预先不留设定的特殊标记,而数据区的起始簇是2号簇。
二、、FAT
表的特性
FAT 表由一些[b]列大小相等的表项组成,有如下特性:
· FAT32 中每个簇的状态,使用32bit(4字节)记录在FAT表中。
FAT 表中的所有字节位置以 4个字节为单位进行划分;并以所有划分后的位置由0进行地址编号。“0号
和 1号”
地址被系统保留并存储特殊标识内容。从 2号
地址开始,
每个地址对应于数据区的簇号,
FAT
表中的地址编号与数据区中的簇号相同。
[/b]称FAT
中的这些四字节一组划分的项的地址为 FAT
表项,
FAT表项中记录的值为FAT
表项值。(簇编号与簇内内容关系如果
Map中的键-值
关系相同)
当文件系统创建时(就是格式化操作时),
分配给FAT
区域的空间将会被清空,
在FAT1与FAT2
的0号和1号表项写入特定值。
由于创建文件系统的同时,也会创建根目录,
也就是为根目录分配了一个簇空间,通常为2号簇,所以2号簇所对应的“2号FAT表项”也会被写入一个结束标记。
· 如果某个簇未被使用,他所对应的FAT
表项内的FAT
表项值即用0进行填充,表示该FAT
表项所对应的簇未被分配使用
· 当某个簇被分配使用时,那么他所对应的FAT表项的值为文件的下一个存储文件的簇号。
如果该文件结束于该簇,则在它的FAT表项中记录的是一个文件结束标记,对于FAT32
而言,代表[b]文件结束的[/b]FAT表项值为0x0FFFFFFF。
· 如果某个簇存在坏扇区,则整个簇会用FAT
表项值
0x0FFFFFF7
标记为坏簇,
不再使用,这个坏簇标记就记录在它所对应的FAT表项中。
· 由于簇号起始于2,
所以FAT表的0号表项与1号表项不予任何簇对应。
FAT32
的0号表项值总是“F8FFFF0F”注意:
可以搜索扇区偏移0字节处的该值(F8FFF0F)以查找FAT表。
· [b]1[/b]号表项可能被用于记录“脏标志”,
以说明文件系统没有被正常卸载或者磁盘表面存在错误。
不过此值似乎不重要,正常情况下,1号表项值“FFFFFFFF”或“FFFFFF0F”
项内容填写规则:
·在文件系统中新建文件时,如果新建的文件只有一个簇,为其分配的簇所对应的FAT表项将会被写入结束标记。如果新建的文件不只占用一个簇,则在其所占用的每个簇对应的FAT表项中写入为其分配的下一个簇的簇号,在最后一个簇对应的FAT
表项中写入结束标记。
· 新建目录时,只为其分配一个簇的空间,对应的FAT
表项中写入结束标记。当目录增大超过一个簇的大小时,将会在空闲空间中继续为其分配一个簇,并在FAT
表中为其建立FAT
表链以描述它所占用的簇的情况。
· 对文件或目录进行删除操作时,他们所对应的FAT
表项将会被清空,设置为0以表示其所对应的簇处于未分配的状态。
三、 FAT表的使用
一个文件的"起始簇号"记录在它的目录项中,
该文件的 "其他簇"
则用一个簇连结构记录在FAT
表中。
如果一个簇所对应的FAT表项的表项值为非零,
则表明该簇已经被分配使用了,但是这时表项值可能为两种情况,一个是一个文件的下一个簇号值,也有可能是一个文件的结束标记0x0FFFFFFF,或者是一个坏簇标记0x0FFFFFF7
。
如果要寻找一个文件的下一个簇,只需要查看该文件的目录项中描述的起始簇号所对应的FAT项,如果该文件只有一个簇,则此处的值为一个结束标记0x0FFFFFFF;如果该文件不只一个簇,则此处
的值是它的下一个簇的簇号。
[b]>> [/b]查询簇连接结构模拟步骤:
当我们要寻找某个文件时,
首先从该文件的“目录项”中获取该文件的第一“簇”的簇号,然后根据“第一簇”的“簇号
N”,然后根据N
从FAT区的FAT表找出N簇号所对应的FAT
表项,查看FAT
表项的内容:
若是文件结束,该表项值为 0x0FFFFFFF;
若是没有结束,而该文件的大小超出一个簇,则N所对应的FAT表项的表项值为该文件下一个簇的簇号,然后再找到下一个簇号N+1
所对应的FAT表项,查看其表项值,依次类推,就推出了一个文件在FAT表中的
簇链连接结构;
也或者表项值为 0xFFFFFFF7
坏簇标识。
[b]>> [/b]其他查找FAT
表项:
要找到一个簇的FAT
表项,只要用他的
簇号乘以每个FAT
表项的字节数即可
。对于FAT32而言,每个FAT
表项占用4个四字节,
如果我们寻找9号簇的表项位置,则用
4*9=36,也就是说位于FAT
表内偏移36(0x24)字节处。
注意:
WinHex 提供了直接跳转到某个指定FAT
表项的功能。
文件系统大小的上限值却绝育FAT
项的大小。
簇链中的每个FAT
项记录着下一个簇的簇地址,FAT
项所能表示的数字有一个上限,这个上限也就是文件系统中的最大簇号。 FAT 32文件系统的FAT
项只使用了32bit
中的28bit
,因此只能描述 268435456个簇(实际上还要考略小于这个值,因为这其中还包含了结束标志及坏簇标志的保留值)。
操作系统通过检测FAT
表中的表项来确定文件系统中的各个簇是否被分配使用。当我们在Windows
下右击某个FAT
分区查看其属性时,显示的已用空间和未用空间就是根据FAT
表统计而来的。
有时我们会遇到,查看属性时发现已用空间并没有减少,但存储的文件却不见了。这是因为某些病毒在某些文件的目录项中写入了删除标记,但并没有清楚FAT
表内的簇链所至
FAT32系统中长文件名的存储
http://blog.csdn.net/yanpingsz/article/details/5597893
短目录结构
typedef struct
{
//
FILE_NAME DIR_Name;
//短文件名
uint8 NAME[8];
//文件名
uint8 TYPE[3];
//文件类型
uint8 DIR_Attr;
//文件属性
uint8 DIR_NTRes;
//保留
uint8 DIR_CrtTimeTeenth;
//文件创建时间的10
毫秒位
uint16 DIR_CrtTime;
//文件创建时间
uint16 DIR_CrtDate;
//文件创建日期
uint16 DIR_LastAccDate;
//文件最后访问日期
uint16 DIR_FstClusHI;
//文件起始簇号的高16
位
uint16 DIR_WrtTime;
//文件的最近修改时间
uint16 DIR_WrtDate;
//文件的最近修改日期
uint16 DIR_FstClusL0;
//文件起始簇号
uint32 DIR_FileSize;
//文件的长度
}__attribute__((packed))DIR;
来自linux内核
Msdos_fs.h
struct msdos_dir_entry {
__u8
name[MSDOS_NAME];/* name and extension */
__u8
attr;
/*attribute bits */
__u8
lcase;
/*Case for base and extension */
__u8
ctime_cs;
/*Creation time, centiseconds (0-199) */
__le16
ctime;
/*Creation time */
__le16
cdate;
/*Creation date */
__le16
adate;
/*Last access date */
__le16
starthi;
/*High 16 bits of cluster in FAT32 */
__le16
time,date,start;/* time, date and firstcluster */
__le32
size;
/*file size (in bytes) */
};
typedef struct
{
uint8 LDIR_Ord;
//长目录项在本组中的序号
uint8 LDIR_Name1[10];
//长文件名的1-5个字符
uint8 LDIR_Attr;
//长文件名目录项标志
uint8 LDIR_Type;
//为0表示长文件名的子项
uint8 LDIR_Chksum;
//校验值(根据短文件名计算得出)
uint8 LDIR_Name2[12];
//长文件名的6-11个字符
uint16 LDIR_FstClusL0;
//文件起始簇号(常置0)
uint8 LDIR_Name3[4];
//长文件名的12-13个字符
}__attribute__((packed))LDIR;
BPB of DBR
typedef struct
{
uint8BS_jmpBoot[3];
//跳转指令
uint8BS_OEMName[8];
//厂商标志和os版本号
uint16BPB_BytesPerSec;
//扇区字节数
uint8BPB_SecPerClus;
//每簇扇区数
uint16BPB_RsvdSecCnt;
//保留扇区数
uint8BPB_NumFATs;
//FAT 数
uint16BPB_RootEntCnt;
//根目录项数(FAT32必须设置为0)
uint16BPB_TotSec16;
//小扇区数(FAT32必须设置为0)
uint8BPB_Media;
//媒体描述符:有关媒体被使用的信息。值0xF8表示硬盘。
uint16BPB_FATSz16;
//每FAT扇区数(FAT32必须设置为0)
uint16BPB_SecPerTrk;
//每道扇区数
uint16BPB_NumHeads;
//磁头数
uint32BPB_HiddSec;
//隐藏扇区数:该分区上引导扇区之前的扇区数
uint32BPB_TotSec32;
//总扇区数:
本字段包含FAT32分区中总的扇区数
uint32BPB_FATSz32;
//每FAT扇区数:该分区每个FAT所占的扇区数
uint16BPB_ExtFlags;
//扩展标志
uint16BPB_FSVer;
//文件系统版本:只供FAT32使用
uint32BPB_RootClus;
//根目录簇号
uint16BPB_FSInfo;
//FAT32分区中的FSINFO结构所占的扇区数
uint16BkBootSec;
//FAT32分区的保留区中引导记录的备份数据所占的扇区号
uint8BPB_Reserved[12];
//保留(用于FAT扩展使用)
uint8BS_DrvNum;
//物理驱动器号与BIOS物理驱动器号有关
uint8BS_Reservedl;
//保留
uint8BS_BootSig;
//扩展引导标签:本字段必须要有能被Windows2000
所识别的值0x28或0x29
uint32BS_VolID;
//分区序号在格式化磁盘时所产生的一个随机序号,
uint8BS_VolLab[11];
//卷标签
uint8BS_FilSysType[8];
//系统ID(FAT32)
uint8ExecutableCode[420];
uint8ExecutableMarker[2];
//55AA
}__attribute__((packed)) FAT_BPB;
来自linux内核的msdos_fs.h
struct fat_boot_sector {
__u8
ignored[3];
/* Boot strap short or near jump */
__u8
system_id[8];
/* Name - can be used to special case
partition manager volumes */
__u8
sector_size[2];
/* bytes per logical sector */
__u8
sec_per_clus;
/* sectors/cluster */
__le16
reserved;
/*reserved sectors */
__u8
fats;
/*number of FATs */
__u8
dir_entries[2];
/* root directory entries */
__u8
sectors[2];
/* number of sectors */
__u8
media;
/*media code */
__le16
fat_length;
/*sectors/FAT */
__le16
secs_track;
/*sectors per track */
__le16
heads;
/*number of heads */
__le32
hidden;
/*hidden sectors (unused) */
__le32
total_sect;
/*number of sectors (if sectors == 0) */
union{
struct{
/*
Extended BPB Fields for FAT16 */
__u8
drive_number;
/* Physical drive number */
__u8
state;
/*undocumented, but used
for mount state. */
__u8
signature; /* extended boot signature */
__u8
vol_id[4];
/*volume ID */
__u8
vol_label[11];
/* volume label */
__u8
fs_type[8];
/* file system type */
/*other fiealds are not added here */
}fat16;
struct{
/*only used by FAT32 */
__le32
length;
/*sectors/FAT */
__le16
flags;
/*bit 8: fat mirroring,
low 4: active fat */
__u8
version[2];
/* major, minor filesystem
version */
__le32
root_cluster;
/*first cluster in
root directory */
__le16
info_sector;
/*filesystem info sector */
__le16
backup_boot;
/*backup boot sector */
__le16
reserved2[6];
/*Unused */
/*Extended BPB Fields for FAT32 */
__u8
drive_number;
/* Physical drive number */
__u8
state;
/* undocumented, but used
for mount state. */
__u8
signature; /* extended boot signature */
__u8
vol_id[4];
/*volume ID */
__u8
vol_label[11];
/* volume label */
__u8
fs_type[8];
/* file system type */
/*other fiealds are not added here */
}fat32;
};
};
短文件格式的目录项。其参数意义见表14:
表14 FAT32短文件目录项32个字节的表示定义 | |||
字节偏移(16进制) | 字节数 | 定义 | |
0x0~0x7 | 8 | 文件名 | |
0x8~0xA | 3 | 扩展名 | |
0xB* | 1 | 属性字节 | 00000000(读写) |
00000001(只读) | |||
00000010(隐藏) | |||
00000100(系统) | |||
00001000(卷标) | |||
00010000(子目录) | |||
00100000(归档) | |||
0xC | 1 | 系统保留 | |
0xD | 1 | 创建时间的10毫秒位 | |
0xE~0xF | 2 | 文件创建时间 | |
0x10~0x11 | 2 | 文件创建日期 | |
0x12~0x13 | 2 | 文件最后访问日期 | |
0x14~0x15 | 2 | 文件起始簇号的高16位 | |
0x16~0x17 | 2 | 文件的最近修改时间 | |
0x18~0x19 | 2 | 文件的最近修改日期 | |
0x1A~0x1B | 2 | 文件起始簇号的低16位 | |
0x1C~0x1F | 4 | 表示文件的长度 |
* 此字段在短文件目录项中不可取值0FH,如果设值为0FH,目录段为长文件名目录段 |
长文件名中的字符采用unicode形式编码(一个巨大的进步哦),每个字符占据2字节的空间。其目录项定义如表15。
表15 FAT32长文件目录项32个字节的表示定义 | ||||
字节偏移 (16进制) | 字节数 | 定义 | ||
0x0 | 1 | 属性字节位意义 | 7 | 保留未用 |
6 | 1表示长文件最后一个目录项 | |||
5 | 保留未用 | |||
4 | 顺序号数值 | |||
3 | ||||
2 | ||||
1 | ||||
0 | ||||
0x1~0xA | 10 | 长文件名unicode码① | ||
0xB | 1 | 长文件名目录项标志,取值0FH | ||
0xC | 1 | 系统保留 | ||
0xD | 1 | 校验值(根据短文件名计算得出) | ||
0xE~0x19 | 12 | 长文件名unicode码② | ||
0x1A~0x1B | 2 | 文件起始簇号(目前常置0) | ||
0x1C~0x1F | 4 | 长文件名unicode码③ |
在不支持长文件名的环境中对短文件名中的文件名和扩展名字段作更改(包括删除,因为删除是对首字符改写E5H),都会使长文件名形同虚设。
(长文件名如何与短文件名对应?仅靠她们之间的位置关系?)
长文件名和短文件名之间的联系光靠他们之间的位置关系维系显然远远不够。其实,长文件名的0xD字节的校验和起很重要的作用,此校验和是用短文件名的11个字符通过一种运算方式来得到的。系统根据相应的算法来确定相应的长文件名和短文件名是否匹配。这个算法不太容易用公式说明,我们用一段c程序来加以说明。
假设文件名11个字符组成字符串shortname[],校验和用chknum表示。得到过程如下:
inti,j,chknum=0;
for (i=11; i>0; i--)
chksum = ((chksum & 1) ? 0x80 :0) + (chksum >> 1) + shortname[j++];
如果通过短文件名计算出来的校验和与长文件名中的0xD偏移处数据不相等。系统无论如何都不会将它们配对的。
依据长文件名和短文件名对目录项的定义,加上对簇的编号和链接,FAT32上数据的读取便游刃有余了。
工具WINHEX
FAT32系统中长文件名的存储http://blog.csdn.net/yanpingsz/article/details/5597893
FAT32文件系统为什么用96字节而不是32字节来描述文件?http://zhidao.baidu.com/link?url=3EDf9bEIpU-T0MHutrw_2o-dKhVUFkGpu3edMukY_-M0q7P15OcKdDHyvJMFD6ek3Sa-QSE6iGV7bT4pcKrdaa
转发至微博
相关文章推荐
- Linux 性能优化之 IO 子系统
- linux本地文件上传之RZ/SZ和sftp
- OpenGL学习常用网站
- 每天一个linux命令(44):top命令
- linux rehat 9.0 系统基本操作/命令
- 【转】OpenGL多线程创建纹理,附加我的测试结果
- CentOS 7中没有ifconfig命令,而且不能发现eth0
- 在CentOS上安装PostgreSQL9.4.5
- 构建高并发高可用的电商平台架构实践
- 微软正式上线Win10商店企业版 用于商业的门户网站
- (总结)Nginx/LVS/HAProxy负载均衡软件的优缺点详解
- 一步步教你Hadoop多节点集群安装配置
- Linux 系统内核空间与用户空间通信的实现与分析
- 在 Linux 下用户空间与内核空间数据交换的方式,第 2 部分: procfs、seq_file、debugfs和relayfs
- KeepAlived+LVS集群架构方案学习笔记
- hadoop思维:HDFS和MapReduce
- linux 安装mysql服务
- Docker实战(五):Docker安装Tomcat
- linux字符cdev和Inode的关系
- CentOS上yum的使用方法总结