一、声明

  1、本文来源和主旨

  2、本文测试环境

二、SD卡FAT文件系统

  1、SD卡FAT32文件系统的整体布局

  2、FAT文件系统简介

    ① 文件分配表

    ② 目录项

三、DBR(DOS BOOT RECORD,DOS引导记录)

  1、DBR与BPB

    ① DBR

    ② BPB

  2、DBR实例测试

  3、DBR参数计算

四、FSINFO分区

五、文件分区FAT表

  1、FAT表

  2、FAT表例

六、数据区

  1、目录项定义

    <1> 短文件目录项的具体定义

    <2> 长文件目录项的具体定义

  2、目录项举例

    <1> 短目录项举例

    <2>  长目录项举例

一、声明

1、本文来源和主旨

  本文几乎全部内容来自于SD卡中FAT32文件格式快速入门(图文详细介绍),这篇文章的理论阐释很到位,实验编排也不错。本文所做的工作就是将这篇文章中讲解的实验从头到尾做一遍。另外本文对于原文的编排有所调整,希望达到更加合理的布局。

2、本文测试环境

测试硬件:2G金士顿SD卡(格式化)

操作系统:"Windows XP"

测试软件:WinHex

二、SD卡FAT文件系统

1、SD卡FAT32文件系统的整体布局

  本SD卡的FAT32文件系统无MBR分区,只有一个基本分区,而基本分区的分布图如下图所示:

从WinHex中查看

2、FAT文件系统简介

  FAT(File Allocation Table,文件分配表)文件系统是windows操作系统所使用的一种文件系统,它的发展过程经历了FAT12、FAT16、FAT32三个阶段。FAT文件系统用“簇”作为数据单元。一个“簇”由一组连续的扇区组成,簇所含的扇区数必须是2的整数次幂。簇的最大值为64个扇区,即32KB。所有簇从2开始进行编号,每个簇都有一个自己的地址编号。用户文件和目录都存储在簇中。 本文每簇4KB大小。

  FAT文件系统的数据结构中有两个重要的结构:文件分配表和目录项:

① 文件分配表

  文件和文件夹内容储存在簇中,如果一个文件或文件夹需要多余一个簇的空间,则用FAT表来描述,如何找到另外的簇。FAT结构用于指出文件的下一个簇,同时也说明了簇的分配状态。FAT12、FAT16、FAT32这三种文件系统之间的主要区别在与FAT项的大小不同。

② 目录项

  FAT文件系统的每一个文件和文件夹都被分配到一个目录项,目录项中记录着文件名、大小、文件内容起始地址以及其他一些元数据。

  在FAT文件系统中,文件系统的数据记录在“引导扇区中(DBR)”中。引导扇区位于整个文件系统的0号扇区,是文件系统隐藏区域(也称为保留区)的一部分,我们称其为DBR(DOS Boot Recorder——DOS引导记录)扇区,DBR中记录着文件系统的起始位置、大小、FAT表个数及大小等相关信息。

  在FAT文件系统中,同时使用“扇区地址”和“簇地址”两种地址管理方式。这是因为只有存储用户数据的数据区使用簇进行管理(FAT12和FAT16的根目录除外),所有簇都位于数据区。其他文件系统管理数据区域是不以簇进行管理的,这部分区域使用扇区地址进行管理。文件系统的起始扇区为0号扇区。

三、DBR(DOS BOOT RECORD,DOS引导记录)

1、DBR与BPB

① DBR

  DBR(DOS Boot Recorder——DOS引导记录)扇区,DBR中记录着文件系统的起始位置、大小、FAT表个数及大小等相关信息。

② BPB

  BPB(BIOS Parameter Block)表,描述逻辑盘结构组成,包含隐藏扇区数目(从0-1-1开始计算)、FAT扇区数、FAT拷贝数、硬盘磁头总数、根目录表项最大值等。

  FAT32文件系统的扩展BPB区位于DBR内,从地址0x00B~0x052都是BPB的范围。

2、DBR实例测试

  格式化SD卡,用WinHex打开SD卡,内容如下:

【1】0x00~0x02:3字节,"EB5890",跳转指令。

【2】0x03~0x0A:8字节,文件系统标志和版本号,这里为MSDOS5.0。

【3】0x0B~0x0C:2字节,每扇区字节数,512(0X02 00)。

【4】0x0D~0x0D:1字节,每簇扇区数,8(0x08),这个值不能为0,而且必须是2的整数次方,比如1、2、4、8、16、32、64、128。

【5】0x0E~0x0F:2字节,保留扇区数,38(0x00 26),那么就知道FAT1起始位置在38扇区。

【6】0x10~0x10:1字节,FAT表个数为2,另外一个是备份的。

【7】0x11~0x12:2字节,FAT32必须等于0,FAT12/FAT16为根目录中目录的个数;

【8】0x13~0x14:2字节,FAT32必须等于0,FAT12/FAT16为扇区总数。

【9】0x15~0x15:1字节,哪种存储介质,0xF8标准值,可移动存储介质。

【10】0x16~0x17:2字节,FAT32必须为0,FAT12/FAT16为一个FAT表所占的扇区数。

【11】0x18~0x19:2字节,每磁道扇区数,只对于有“特殊形状”(由磁头和柱面每 分割为若干磁道)的存储介质有效,63(0x003F)。

【12】0x1A~0x1B:2字节,磁头数,只对特殊的介质才有效,255(0x00 FF)。

【13】0x1C~0x1F:4字节,EBR分区之前所隐藏的扇区数,0(0x00 00 00 00)。

【14】0x20~0x23:4字节,此文件系统分区的总扇区数,3887104(0x 00 3B 50 00),3887104 * 512 = 1990197248  ≈ 1.9GB。

【15】0x24~0x27:4字节,每个FAT表占用扇区数,3789(0x 00 00 0E CD)。

【16】0x28~0x29:2字节,标记,此域FAT32 特有。

【17】0x2A~0x2B:2字节,FAT32版本号0.0,FAT32特有。

【18】0x2C~0x2F:4字节,根目录所在第一个簇的簇号,2。(虽然在FAT32文件系统 下,根目录可以存放在数据区的任何位置,但是通常情况下还是起始于2号簇)。

【19】0x30~0x31:2字节,FSINFO(文件系统信息扇区)扇区号是1,该扇区为操作系统提供关于空簇总数及下一可用簇的信息。

【20】0x32~0x33:2字节,备份引导扇区的位置。备份引导扇区总是位于文件系统的6号扇区。

【21】0x34~0x3F:12字节,用于以后FAT 扩展使用。

【22】0x40~0x40:1字节,与FAT12/16 的定义相同,只不过两者位于启动扇区不同的位置而已。

【23】0x41~0x41:1字节,与FAT12/16 的定义相同,只不过两者位于启动扇区不同的位置而已 。

【24】0x42~0x42:1字节,扩展引导标志,0x29。与FAT12/16 的定义相同,只不过两者位于启动扇区不同的位置而已

【25】0x43~0x46:4字节,卷序列号。通常为一个随机值。

【26】0x47~0x51:11字节,卷标(ASCII码),如果建立文件系统的时候指定了卷标,会保存在此。

【27】0x52~0x59:8字节,文件系统格式的ASCII码,FAT32。

★【28】0x5A~0x1FD:90~509共410字节,引导代码。

【29】0x1FE~0x1FF:签名标志“55 AA”。

★说明:引导代码

FAT文件系统将引导代码与文件形同数据结构融合在一起,FAT32文件系统引导扇区的512字节中,90~509字节为引导代码,而FAT12/16则是62~509字节为引导代码。同时,FAT32还可以利用引导扇区后的扇区空间存放附加的引导代码。一个FAT卷即使不是可引导文件文件系统,也会存在引导代码。

3、DBR参数计算

由以上信息我们知道:

扇区大小:512 Bytes

簇大小:8 Sector = 2048 Bytes

保留扇区数:38 Sector

FAT表占用扇区数:3789 Sector

所以可以得知:

(1)FAT1地址

  = 38 * 512 = 19456 = 0x4C00

(2) FAT2地址

  = (38 + 3789)*512 = 1959424 = 0x1DE600

(3) 根目录地址

  = (38 + 3789 * 2)* 512 = 3899392 = 0x3B8000

(4) FAT表占据扇区数

  = 簇总数 * 4 Bytes/ 扇区占据字节数

  = (数据区扇区数/每簇占据扇区数)* 4 / 512

  = ( 3879488 / 8 ) * 4 / 512

  = 3788.5625

  FAT表占据扇区数取整数为3789Sector。

四、FSINFO分区

  FAT32在保留区中增加了一个FSINFO扇区,用以记录文件系统中空闲簇的数量以及下一可用簇的簇号等信息,以供操作系统作为参考。FSINFO信息扇区一般位于文件系统的1号扇区,结构非常简单。

【1】0x200~0x203: 4个字节,扩展引导标志“0x52526141”。

【2】0x204~0x3E3:480个字节,未使用,全部置0。

【3】0x3E4~0x3E7: 4个字节,FSINFO签名“0x72724161”。

【4】0x3E8~0x3EB: 4个字节,文件系统的空簇数,484934(0x00 07 66 46)。

【5】0x3EC~0x3EF: 4个字节,下一可用簇号(0x 00 00 00 04)。

【6】0x3F0~0x3FD: 14个字节,未使用。

【7】0x3FE~0x3FF: 2个字节,“55 AA”标志。

温馨提示:通常情况下,文件系统的2号扇区结尾也会被设置“55 AA”标志。6号扇区会有一个引导扇区的备份,7号扇区是一个FSINFO信息备份扇区,8号扇区可以看做是2号扇区的备份。

 五、文件分区FAT表

  文件系统分配磁盘空间按簇来分配。因此,文件占有磁盘空间时,基本单位不是字节而是簇,即使某个文件只有一个字节,操作系统也会给它分配一个最小单元:即一个簇。对于大文件,需要分配多个簇。同一个文件的数据并不一定完整地存放在磁盘中一个连续地区域内,而往往会分若干段,像链子一样存放。这种存储方式称为文件的链式存储。为了实现文件的链式存储,文件系统必须准确地记录哪些簇已经被文件占用,还必须为每个已经占用的簇指明存储后继的下一个簇的簇号,对于文件的最后一簇,则要指明本簇无后继簇。这些都是由FAT表来保存的,FAT 表对应表项中记录着它所代表的簇的有关信息:诸如是空,是不是坏簇,是否是已经是某个文件的尾簇等。

1、FAT表 

  FAT表中的表项也是以4字节为单位进行划分,对FAT表由0进行逻辑编号。0号地址与1号地址被系统保留并存储特殊标志内容。从2号地址开始,每个地址对应于数据区的簇号,FAT表中的地址编号与数据区中的簇号一一对应。我们称FAT表中的这些单元为FAT表项,FAT表项中记录的值称为FAT表项值。

  FAT32中把簇是以32bit(4个字节)进行编码,而这种编码是逻辑编码,与物理地址也有一定的对应关系。FAT表紧接着的是有效数据区,从此区开始从2进行簇标号。也就是说从物理地址0x3B8000(7616扇区)位置处,从2开始,以4KB (8*512)为跨度进行簇编号。

当文件系统被创建,也就是进行格式化操作时,分配给FAT区域的空间将会被清空,在FAT1与FAT2的0号表项与1号表项写入特定值。由于创建文件系统的同时也会创建根目录,也就是为根目录分配了一个簇空间,通常为2号簇,与之对应的2号FAT表项被写入一个结束标记。

说明:

① 由于簇号起始于2号,所以FAT表项的0号表项与1号表项不与任何簇对应。FAT32的0号表项值总是“F8FFFF0F”。

②  1号表项可能被用于记录脏标志,以说明文件系统没有被正常卸载或者磁盘表面存在错误。不过这个值并不重要。正常情况下1号表项的值为“FFFFFFFF”或“FFFFFF0F”。

②  如果某个簇未被分配使用,它对应的FAT表项内容为0;

③ 当某个簇已被分配使用,则它对应的FAT表项内的FAT表项值也就是该文件的下一个存储位置的簇号。如果该文件结束于该簇,则在它的FAT表项中记录的是一个文件结束标记,对于FAT32而言,代表文件结束的FAT表项值为0x0FFFFFFF。

③ 如果某个簇存在坏扇区,则整个簇会用0xFFFFFF7标记为坏簇,这个坏簇标记就记录在它所对应的FAT表项中。

④  在文件系统中新建文件时,如果新建的文件只占用一个簇,为其分配的簇对应的FAT表项将会写入结束标记。如果新建的文件不只占用一个簇,则在其所占用的每个簇对应的FAT表项中写入为其分配的下一簇的簇号,在最后一个簇对应的FAT表象中写入结束标记。

⑤ 新建目录时,只为其分配一个簇的空间,对应的FAT表项中写入结束标记。当目录增大超出一个簇的大小时,将会在空闲空间中继续为其分配一个簇,并在FAT表中为其建立FAT表链以描述它所占用的簇情况。

2、FAT表例

  笔者先对2G金士顿SD卡进行格式化,然后新建一个readme.txt文件,大小8.9KB。

  用WinHex打开FAT1区,内容如下

【0号表项】:0x0FFFFFF8;FAT表起始固定标识

【1号表项】:0xFFFFFFFF;不用,默认值

【2号表项】:0x0FFFFFFF;根目录所在簇,由于此时只占用1簇,所以是结束标志

【3号表项】:3号表项为0x00 00 00 04,readme.txt文件的下一簇号在4号表项,查看4号表项。

【4号表项】:4号表项为0x00 00 00 05,readme.txt文件下一簇号在5号表项,查看5号表项。

【5号表项】:5号表项为0x0F FF FF FF,结束符号。说明文件在5号簇时就存储完毕。

分析:readme.txt大小为8.9KB,而每簇大小为4KB,需要占用3个簇,这与存储结果一致。

 六、数据区

  数据区时真正用于存放用户数据的区域。数据区紧跟在FAT2之后,被划分成一个个的簇。所有的簇从2开始进行编号,也就是说,2号簇的起始位置就是数据区的起始位置。

1、目录项定义

  目录所在的扇区,都是以32 Bytes划分为一个单位,每个单位称为一个目录项(Directory Entry),即每个目录项的长度都是32 Bytes 。根目录由若干个目录项组成,一个目录项占用32个字节,可以是长文件名目录项、文件目录项、子目录项等。

<1> 短文件目录项的具体定义

☆ 目录项的第一个字节为“0xE5”,表示该项已被删除。

☆ 目录项的第一个字节为0x2E(“.”),表示当前目录的信息(目录的数据空间也会保存当前目录的目录项信息)

☆ 目录项的前两个字节为“0x2E 0x2E(“. .”),表示上一级目录。

☆ 目录项的第一个字节为"0x00",代表从此位置开始以后的数据空间都没有使用。

注意:

  对于目录对应的短目录项,没有文件长度参数,也就是说0x1C-0x1F等于0。那么对于目录,又如何知道它占用空间的大小呢,又如何遍历目录呢?

  目录中的目录项是按照从前到后紧密排放,即使文件或者目录删除,也不会删除它们对应的目录项(删除目录项意味着目录项清零),只是将目录项标记为删除(0xE5)。这样目录的数据空间直到遇到第一个空目录项之前,所有的目录项都是非空的。我们可以根据目录项是否非空判断是否到达了目录的目录项尾部。

  至于目录的大小,其实已经没有意义了。我们获取目录的大小就是想判断目录的结束位置,而现在第一个空目录项就是目录的结束位置,所以已经没有必要知道目录的大小。当然, 通过遍历目录可以确定目录占用空间的大小,不过没有意义。

<2> 长文件目录项的具体定义

再详细的列出上表中地址0x0处各位段的含义

☆ 长文件名文件目录项的unicode编码:无论是英文字符,还是中文字符都占用2个字节。

☆ 目录项的第一个字节为“0xE5”,表示该项已被删除。

☆  一个长文件它在目录中的记录可能有几个目录项组成,包含若干个长目录项和一个短目录项

☆ 0xB位段的取值如果是0FH代表是长目录项,反之就是短目录项。

☆ 1个长文件目录项:能记录13个字符,对应26个字节

☆ 顺序是从1开始编号直到13,倘若到了结尾的地方,除了要按照规则的编号还需要将0x0地址的第6位置1。

2、目录项举例

<1> 短目录项举例

  格式化SD卡,然后在其中创建一个文件readme.txt和Test子目录,WinHex打开根目录内容如下:

首先看子目录Test的对应目录项:

【1】0x3B8020 - 0x3B8027 目录项名为Test

【2】0x3B802B 10H(0001 0000B),表明为子目录

【3】[0x3B8034 - 0x3B8035,0x3B803A - 0x3B803B]  00 03H,表明Test子目录位于3号簇的位置,在FAT表中为3号表项

【4】0x3B803C - 0x3B803F 0000H,大小为0

readme.txt的对应目录项:

【1】0x3B8040 - 0x3B8047 目录项名为readme

【2】0x3B8048 - 0x3B804A 目录项扩展名为TXT

【3】0x3B804B 20H(0010 0000B),表明为归档文件

【3】[0x3B8054 - 0x3B8055,0x3B805A - 0x3B805B]  00 04H,表明readme.txt位于4号簇的位置,在FAT表中为4号表项

【4】0x3B805C - 0x3B805F 23A7H,大小为9127 Bytes

<2>  长目录项举例

  格式化SD卡,然后在其中创建一个文件abcdefghigklmnopqrstuvwxyz.txt,WinHex打开根目录内容如下:

先看看卷标 

【1】0x3B8000 - 0x3B8007 目录项名为Huang

【2】0x3B800B 08H(0000 1000B),表明为"卷标"

再看看长文件目录项

【1】003B8020   0x43 表明此长文件包含了3个长目录项,并且当前目录项是它的最后一个长目录项

【2】003B8040   0x02 表明这是长文件的第2个目录项

【3】003B8041 - 003B804A 长文件目录项的unicode的第一部分, 006EH 006FH 0070H 0071H 0072H 代表了nopqr五个字符

【4】003B804B  0x0F 表明是一个长目录项

【5】003B804D     0x27 校验和

【6】003B804E -003B8059 长文件目录项的unicode的第二部分, 0073H 0074H 0075H 0076H 0077H 0078H 代表了stuvwx六个字符

【7】003B805A - 003B805B 起始簇号,目前常置0

【8】003B805C - 003B805F 长文件目录项的unicode的第三部分, 0079H 007AH 代表了yz两个字符

 为了记录abcdefghigklmnopqrstuvwxyz.txt,使用了3个长目录项和1个短目录项。至于位于003B8080处的短目录项,就不在说明了。

参考资料:SD卡中FAT32文件格式快速入门(图文详细介绍)

     FAT文件系统原理(一)

FAT(维基百科)

SD卡FAT32文件系统格式的更多相关文章

  1. SD卡FAT32获得高速的文件格式(图文介绍)

    说明: MBR :Master Boot Record ( 主引导记录) DBR :DOS Boot Record ( 引导扇区) FAT :File Allocation Table ( 文件分配表 ...

  2. 玩转X-CTR100 l STM32F4 l SD卡FatFs文件系统

    我造轮子,你造车,创客一起造起来!塔克创新资讯[塔克社区 www.xtark.cn ][塔克博客 www.cnblogs.com/xtark/ ] X-CTR100控制器具有SD卡接口,本教程使用免费 ...

  3. SD卡fat文件系统移植

    经过充分的研究,发现fatfs文件系统移植的比较简单!因为代码都已经被别人做好了!我们只需把io层稍稍做个处理就ok了: 至于sd卡的驱动请看我这篇博客:http://blog.csdn.net/ie ...

  4. 比较详细的利用虚拟机对SD卡FAT32+EXT4+Ext4分区图解教程

    如果大家嫌虚拟机复杂,我这里提供一个我没用虚拟机之前的分区方法:这个方法实际是可行的 我在没有用虚拟机之前,我是这样操作的1.首先在分区软件分好fat32+ext2+ext22.然后用recovery ...

  5. SD卡中FAT32文件格式快速入门(图文详细介绍)【转】

    本文转自:http://blog.csdn.net/mjx91282041/article/details/8904705 说明: MBR :Master Boot Record ( 主引导记录) D ...

  6. SD卡中FAT32文件格式快速入门(图文详细介绍)

    说明: MBR :Master Boot Record ( 主引导记录) DBR :DOS Boot Record ( 引导扇区) FAT :File Allocation Table ( 文件分配表 ...

  7. SD卡中FAT32文件格式高速入门(图文具体介绍)

    说明: MBR :Master Boot Record ( 主引导记录) DBR :DOS Boot Record ( 引导扇区) FAT :File Allocation Table ( 文件分配表 ...

  8. 用SD卡下载uboot、linux内核和文件系统

    1. 移植mtd-utils: a) 下载utd-utils 下载地址为ftp://ftp.infradead.org/pub/mtd-utils/b) 交叉编译mtd-utilsi   修改Make ...

  9. 第37章 基于SD卡的FatFs文件系统—零死角玩转STM32-F429系列

    第37章     基于SD卡的FatFs文件系统 全套200集视频教程和1000页PDF教程请到秉火论坛下载:www.firebbs.cn 野火视频教程优酷观看网址:http://i.youku.co ...

随机推荐

  1. Java基础知识强化之网络编程笔记22:Android网络通信之 Android常用OAuth登录(获取个人信息)

    1. 获取百度个人信息(使用Gson解析): 2. 代码案例: (1)工程一览图,如下: (2)activity_main.xml: <LinearLayout xmlns:android=&q ...

  2. Android_Toast

    xml文件: main1: <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" ...

  3. jquery循环遍历radio单选按钮,并设置选中状态

    背景:自己在做项目过程中遇到的问题,现在记录一下. 需求:在ajax获取后台数据的之后,需要根据获取的数据对页面中的radio单选按钮进行选中状态设置 因为自身js功底欠佳,所以耽误了点时间,现在把方 ...

  4. aggregation 详解3(bucket aggregation)

    概述 桶分聚合不进行权值的计算,他们对文档根据聚合请求中提供的判断条件(比如:{"from":0,  "to":100})来进行分组(桶分). 桶分聚合还会额外 ...

  5. 【区间选点问题】uva 10148 - Advertisement

    区间选点问题,即数轴上有n个闭区间[l1i, ri],取尽量少的点,使得每个区间内都至少有一个点. The Department of Recreation has decided that it m ...

  6. js定时器window.setTimeout和setInterval

    window.setTimeout(function(){                            document.getElementById("editorindex&q ...

  7. linux gpg 使用笔记

    http://linux.chinaunix.net/techdoc/system/2009/04/30/1109541.shtml 一.GnuPG的简介     我们在网上的发送的邮件是明文的,可以 ...

  8. ASP.NET笔记之 ListView 与 DropDownList的使用(解决杨中科视频中的问题)

    1.Repeater用来显示数据.ListView用来操作数据 InsertItemTemplate和updateItemTemplate**Eval(显示数据)和Bind(双向绑定:不仅是需要展现, ...

  9. Error:(6, 0) No such property: outputDir for class: org.gradle.api.internal.project.DefaultProject_Decorated

    在学习greenDao过程中build.gradle文件中出现这个错误,找了半天不知道为什么.代码我是在git上下载的Demo,按理说应该是没问题的.到最后发现缺少了一个关键字Def // 这样有问题 ...

  10. asp.net 配置二级域名的共享session,并实现sso单点登录

    公司最近做了一个新网站.原先网站的网址是www.xxxx.com.新做的网站要部署到info.xxxx.com.这两个网站要实现单点登录.而新老网站本身机构的原因,对于登录状态的判断,说白了就是对于s ...