原创 图文并茂 USB Mass Storage FAT文件系统彻底剖解(一)

2010-9-20 14:44 11295 6 17 分类: MCU/ 嵌入式


      本文将以详解的图片和文字对比描述FAT文件系统的基本构架细节。这是本人自己的学习笔记。希望大家能参照图片与文字(文中涉及的一些具体的数字请仔细留意一下),这将有利于你更深入的了解文件系统的简单构架,跟着我的思路往下理顺,相信对大家会有所收获。


      关于底层单片机的U盘固件程序在此就不谈了,这里只涉及上层文件系统部分。如果后面有时间,我再发贴上来。


      本例在LPC1768内存中开辟8K字节作为整个U盘文件系统缓冲区。通过USB接口向主机发送USB设备描述符,接口描述符,端点描述符,配置描述符。。。。。Bulk Only(批量传输)模式响应主机发送的CBW(Command Block Wrapper,即命令块包),将设备枚举为USB 海量存储设备(USB Mass Storage Class)。关于具体细节不属于本文的范畴,大家可以参考具体的USB协议,USB Mass Storage Class协议或是其他朋友写的文章。。。。。。


       成功枚举后,在电脑上将会看到如图1所示的硬盘图标,在我的电脑上是P盘。


图 1


clip_image002


       (在写这里的时候,本人着实郁闷了半天,U盘插到我笔记本上WIN7时,是完整的空盘,而插到台式机上时就显示已使用空间1KB。起初怀疑是单片机程序中硬盘镜像的FAT表有问题,弄了半天,最后用WinHex查看从台式机取下的U盘数据,发现里面被塞了两个文件,这下明白了,台式机有病毒,插上去就生成了两个文件。刚好占用两个扇区。所以在调试任何程序时,有些细节是蛮折腾人的。)


        容量为6.00KB, 可用空间6.00KB。按道理我的硬盘应该有8KB才对,因为我在单片机内存中开辟了8KB。但为何会少了2KB呢?这个问题在看完后面之后你就会明白。


此时U盘里无任何文件数据,是一张空盘。


        接下来用WinHex打开此盘,大家将会看到以下一些数据图片。


首先是前512字节,也就是“扇区0”


                                                                                                         图 2


00


       注意左边的一些信息,此U盘的大小为8K字节,(分为16个扇区 × 512字节)。也就是共有16个扇区。和我内存中开辟的缓冲区大小一致。但空闲的仅为6K字节,也就是说有2KB(即4个扇区)的容量被占用了。它们分别是:


图 3


clip_image006


DBR区           占用0 扇区。


           FAT1表          占用 1 2 两个扇区


                                                                                                                                                                                       FAT2表          无


                                                                                                                                                                                      根目录            占用 3 扇区


                                                                                                                                                                                       数据区            占用 4------15 扇区


          DBR区(DOS BOOT RECORD)即操作系统引导记录区的意思,通常占用分区的 第 0 扇区共 512 个字节(特殊情况也要占用其它保留扇区,我们先说第 0 扇)。在这 512 个字节中,其实又是由跳转指令,厂商标志和操作系统版本号,BPB(BIOS Parameter Block),扩展BPB,os引导程序,结束标志几部分组成。


图 4


clip_image008


表 1


clip_image010


跳转指令JUMP


       图 2列出的偏移0x00-0x02的跳转指令“EB 3C 90“,清楚地指明了引导代码的偏移位置。“jump 3CH“加上跳转指令所需的位移量2,即开始于0x3E。此段指令在不同的操作系统上和不同的引导方式上,其内容也是不同的。


OEM厂商标志


       跳转指令之后是8 字节长的OEM ID,它是一个字符串,OEM ID标识了格式化该分区的操作系统的名称和版本号。为了保留与MS-DOS的兼容性,通常Windows格式化该盘是在FAT16磁盘上的该字段中记录了“MSDOS5.0”,如图2所示。


BPB和扩展BPB


       BPB(BIOS Parameter Block)参数块记录着本分区的起始扇区、结束扇区、文件存储格式、硬盘介质描述符、根目录大小、FAT个数、分配单元(也称之为簇)的大小等重要参数。如表2所示


表2  FAT16分区的BPB字段                




表2  FAT16分区的BPB字段


字节位移


字段长度(字节)


例 值


名称、定义和描述


0x0B


2


00 02


扇区字节数(Bytes Per Sector) 硬件扇区的大小。本字段合法的十进制值有512、1024、2048和4096。对大多数磁盘来说,本字段的


值为512


0x0D


1


01


每簇扇区数(Sectors Per Cluster) 一个簇中的扇区数。由于FAT16文件系统只能跟踪有限个簇(最多为65536个)。因此,通过增加每簇的扇区数可以支持最大分区数。分区的缺省的簇的大小取决于该分区的大小。本字段合法的十进制值有 1、2、4、8、16、32、64和128。导致簇大于32KB(每扇区字节数*每簇扇区数)的值会引起磁盘错误和软件错误


0x0E


2


01 00


保留扇区数(Reserved Sector) 第一个FAT开始之前的扇区数,包括引导扇区。


0x10


1


01


FAT数(Number of FAT)该分区上FAT的副本数。本字段的值一般为2


0x11


2


10 00


根目录项数(Root Entries) 能够保存在该分区的根目录文件夹中的32个字节长的文件和文件夹名称项的总数。在一个典型的硬盘上,本字段的值为512。其中一个项常常被用作卷标号(Volume Label),长名称的文件和文件夹每个文件使用多个项。文件和文件夹项的最大数一般为511,但是如果使用的长文件名,往往都达不到这个数。


0x13


2


10 00


小扇区数(Small Sector) 该分区上的扇区数,表示为16位(<65536)。对大于65536个扇区的分区来说,本字段的值为0,而使用大扇区数来取代它。


0x15


1


F8


媒体描述符( Media Descriptor)提供有关媒体被使用的信息。值0xF8表示硬盘,0xF0表示高密度的3.5寸软盘。媒体描述符要用于MS-DOS FAT16磁盘,在Windows 2000中未被使用


0x16


2


02 00


每FAT扇区数(Sectors Per FAT) 该分区上每个FAT所占用的扇区数。计算机利用这个数和FAT数以及隐藏扇区数来决定根目录在哪里开始。计算机还可以根据根目录中的项数(512)决定该分区的用户数据区从哪里开始


0x18


2


01 00


每道扇区数(Sectors Per Trark)


0x1A


2


01 00


磁头数(Number of head)


0x1C


4


00 00 00 00


隐藏扇区数(Hidden Sector) 该分区上引导扇区之前的扇区数。在引导序列计算到根目录和数据区的绝对位移的过程中使用了该值


0x20


4


00 00 00 00


大扇区数(Large Sector) 如果小扇区数字段的值为0,本字段就包含该FAT16分区中的总扇区数。如果小扇区数字段的值不为0,那么本字段的值为0



结合图2和表2的数据可以得出以下信息:



     1. 本U盘的扇区大小为512字节



     2. 每簇扇区数为1,也就是说U盘共有15簇。



     3. 保留扇区数为1,也就是说U盘在FAT开始之前仅有一个引导扇区。



     4. 只有1个FAT表,占用2个扇区。



     5. 本U盘共有 16个扇区,总容量为8KB。



     6. 每道扇区1个,磁头1个,无隐藏扇区。


引导代码和结束标志


       在图2中,偏移0x3E开始的数据为操作系统引导代码。这是由偏移0x00开始的跳转指令所指向的,此段指令在不同的操作系统上和不同的引导方式上,其内容也是不同的,这里就不对引导代码进行探讨了,因为它涉及的很多东西,且本设计并没有使用到它。


       扇区的最后两个字节存储值为0xAA55的DBR有效标志,对于其他的取值,系统将不会执行DBR相关指令。


关于保留扇区


        操作系统之所以设置保留扇区,是为了对DBR作备份或留待以后升级时用。当DBR扇区被破坏导致分区无法访问时。可以用保留扇区的备份替换第0扇区来找回数据。在图2中,DBR偏移量0x0E位置的2个字节是0x0001,指明了保留的扇区数为1,即第一个FAT开始之前的扇区数,它包括引导扇区。


FAT表和数据的存储原则


      FAT(File Allocation Table 即文件分配表)是Microsoft在FAT文件系统中用于磁盘数据(文件)索引和定位引进的一种链式结构。它有两个,为的是备份。假如把磁盘比作一本书,FAT表可以认为是相当于书中的目录,而文件就是各个章节的内容,但FAT表的表示方法与目录有些不同。


      在FAT文件系统中,文件的存储依照FAT表制定的簇链式数据结构来进行。同时,FAT 文件系统将组织数据时使用的目录也抽象为文件,以简化对数据的管理。


      图5所示给出了此U盘上FAT表的数据。


图5 FAT表


01


      FAT 文件系统之所以有12,16,32 不同的版本之分,其根本在于FAT 表用来记录任意一簇链接的二进制位数。以FAT16为例,每一簇在FAT表中占据2个字节(二进制16位)。所以,FAT16最大可以表示的簇号为0xFFFF,以32K为簇的大小的话,FAT16可以管理的最大磁盘空间为:32KB×65535=2048MB,这就是为什么FAT16不支持超过2GB分区的原因。


      FAT表实际上是一个数据表,以2个字节为单位,我们暂将这个单位称为FAT记录项,从图5中,可以知道,前一个记录项(即前两个字节)是0xFFF8,它是FAT表的标志,通常情况,第1、2个记录项用作介质描述。从第三个记录项开始记录除根目录外的其他文件及文件夹的簇链情况。根据簇的表现情况FAT用相应的取值来描述,见表1-4。


clip_image014


        因为此为空盘,所以FAT表记录中仅有一个FAT表标志 F8 FF。


        FAT表的另一扇区图,见图6。


图6


clip_image016


根目录


     FAT文件系统的目录结构其实是一颗有向的从根到叶的树,这里提到的有向是指对于FAT 分区内的任一文件(包括文件夹),均需从根目录寻址来找到。可以这样认为:目录存储结构的入口就是根目录。


     FAT 文件系统根据根目录来寻址其他文件(包括文件夹),故而根目录的位置必须在磁盘存取数据之前得以确定。FAT文件系统就是根据分区的相关DBR参数与DBR中存放的已经计算好的FAT表(2 份)的大小来确定的。格式化以后,根目录的大小和位置其实都已经确定下来了——位置紧随FAT2之后。但此U盘无FAT2,所以就紧随FAT1之后,占据第3扇区。


     FAT文件系统的一个重要思想是把目录(文件夹)当作一个特殊的文件来处理,在FAT16中,虽然根目录地位并不等同于普通的文件或者说是目录,但其组织形式和普通的目录(文件夹)并没有不同。FAT 分区中所有的文件夹(目录)文件,实际上可以看作是一个存放其他文件(文件夹)入口参数的数据表。其具体存储原理是:不管目录文件所占空间为多少簇,一簇为多少字节。系统都会以32个字节为单位进行目录文件所占簇的分配。这32个字节以确定的偏移来定义本目录下的一个文件(或文件夹)的属性,实际上是一个简单的二维表。这32个字节的各字节偏移定义如表1-5所示。


clip_image018


     因为此盘目前为空盘,所以根目录除了磁盘名称数据外,还无任何文件记录。在后面会具体举例说明。


     根目录扇区数据请看图7.


图7


003


    红色圈出来的32字节,作用是在盘符中显示名称“YangYong”。文件名“YangYong”;无扩展名;属性为归档卷标;其它项目全为0。


    从第4扇区到第15扇区全为数据区,见图8。


图 8


clip_image022


    下面我们通过在U盘中新建一个文件名为ReadMe.txt的文件来对比上面空盘,看存储内容发生了那些变化,帮助大家更好的了解FAT构架


     此时U盘容量变为5.5KB可用,见图9


图9


clip_image024


    打开U盘可以看到我们新建的文件,见图10


图10


clip_image026


    虽然文件只有79个字节,但却占据了512个字节,也就是一个扇区的容量。留意一下文件属性,后面我们会做对比。


    打开文件,可以看到里面的内容,见图11。


图 11


clip_image028


      用WinHex打开此U盘。扇区0的数据没有任何变化,而扇区1也就是FAT1区的数据发生了变化,如图12,请此图与前面的图5对比看


图 12


6


     FAT1区多了两个字节,即“FF FF”表示此文件仅占一个扇区就结束了。


     扇区2的数据也没有任何变化,


     而扇区3作为根目录区,已经发生了变化,如图13,请与前面的图7对比看。


图13


07


    红色圈起来的部分,为新增加的内容,下面具体分析一下其含义。


图14


clip_image034



1. “52 45 41 44 4D 45 20 20” 为文件名的ASCII码,字符串为“ReadMe”。



2. “54 58 54” 为扩展名“txt”。



3. “20” 表示此文件属性为归档。



4. “00” 系统保留



5. “2C” 创建时间的10毫秒位



clip_image036



6. “B2 9A” 文件创建时间



             时间 =小时*2048+分钟*32+秒/2 =19×512 + 21×32 +36/2 =0x9AB2



7. “33 3D” 文件创建日期



            日期 =(年份-1980)*512+月份*32+日 =(2010 -1980)×512 +9×32 +19 =0x3D33
8. “33 3D” 文件最近访问日期


                      日期 =(年份-1980)*512+月份*32+日 =(2010 -1980)×512 +9×32 +19 =0x3D33


9. “00 00” 文件起始簇号高16位



10. “A4 9A” 文件最近修改时间




                       时间 =小时*2048+分钟*32+秒/2 =19×512 + 21×32 +8/2 =0x9AA4


11. “33 3D” 文件最近修改日期




                       日期 =(年份-1980)*512+月份*32+日 =(2010 -1980)×512 +9×32 +19 =0x3D33


12. “02 00” 文件起始簇号为 0002 即 第二簇



13. “4F 00 00 00” 文件长度为0x4F 即79个字节。




 


         文章部分内容参考了http://blog.csdn.net/menghnhhuan/archive/2009/06/15/4270168.aspx,在此表示感谢!


 


         第一次论坛发贴,着实耗时,初浅之极,不妥之处在所难免。。。。。。。


 


          下面顺便上传一个查看工具和此文中用到的U盘数据文件


         


 


          下一节,将以一个32MB的TF卡的实例更深入的探讨FAT文件构造的数据组织形式。请访问http://blog.ednchina.com/singlechip/

文章评论11条评论)

登录后参与讨论

用户377235 2015-1-15 10:39

开辟的内存空间做U盘,这个地址怎么没设置

用户377235 2014-3-8 10:06

真得了不起,看了受益匪浅

用户377235 2013-2-13 10:53

博主的敬业精神令人钦佩,堪称楷模!

用户967597 2012-8-10 11:18

一和二都看了,很实在的说明。谢了

用户377235 2012-8-8 23:01

感谢分享!

用户419652 2011-5-31 14:38

lz辛苦了

用户425516 2010-9-26 20:00

是蛮费时的,花了两天时间整理。以前没写过这些。。 呵呵 只要能对需要的朋友有所启发,就值得了,这么多年,毕竟我也是看别人的资料走过来的。也该贡献一下了

朱玉龙 2010-9-26 17:06

顶一下这么长的文章,写篇文章出来总是很费时的!

用户425516 2010-9-26 12:18

客气了! 共同进步。。。。

用户1584993 2010-9-26 11:22

博主写的很详细认真,肯定要给于鼓励的
相关推荐阅读
用户425516 2013-07-03 14:54
[博客大赛]四层板搞定--AT91SAM9X35 第二版
    花了一个月时间,又重新设计了一款AT91SAM9X35的板子。针对第一版做了以下改进。   1 200PIN1.27MM的双排插针换成了更可靠的BTB-80 插针   ...
用户425516 2013-04-25 09:48
[博客大赛]四层板搞定--AT91SAM9X35
  1月15号从零开始设计原理图,到今天4月15号,刚好3个月,终于用4层板设计完成了AT...
用户425516 2013-04-09 18:06
准备花3个月时间用四层板画--AT91SAM9X35
  最近终于腾出手来,比较看好AT91SAM9X35这颗芯片,打算好好弄弄。先从画板开始吧?虽然手上有芯片商提供的开发板,但总觉得不能自己画出一块板出来,技术永远不会属于自己。所以准...
用户425516 2013-02-01 15:01
PCB设计资料汇总
http://pan.baidu.com/share/link?shareid=202013&uk=3826038294#dir/path=%2FPCB%E8%AE%BE%E8%AE%A1...
用户425516 2012-12-12 16:00
[ti博客大赛]基于MSP430装备监控型冲击震动记录仪
概述 装备监控型冲击振动记录仪(以下简称记录仪)用于长时间监视装备在储存过程中受到的冲击振动,对超过阈值的冲击事件进行记录和报警。记录的事件包括对事件的发生强度和发生时间进行实时的记录。当需要...
用户425516 2012-12-12 16:00
[ti博客大赛]当年纯手工打造的---基于MSP430姿态调整仪
当年纯手工打造的---基于MSP430姿态调整仪。。。。采用三轴加速度传感器。。。 感兴趣的朋友可以到我博客探讨。。。。 http://bbs.ednchina.com/BLOG_ARTI...
我要评论
11
6
关闭 站长推荐上一条 /2 下一条