本文将以详解的图片和文字对比描述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 (在写这里的时候,本人着实郁闷了半天,U盘插到我笔记本上WIN7时,是完整的空盘,而插到台式机上时就显示已使用空间1KB。起初怀疑是单片机程序中硬盘镜像的FAT表有问题,弄了半天,最后用WinHex查看从台式机取下的U盘数据,发现里面被塞了两个文件,这下明白了,台式机有病毒,插上去就生成了两个文件。刚好占用两个扇区。所以在调试任何程序时,有些细节是蛮折腾人的。) 容量为6.00KB, 可用空间6.00KB。按道理我的硬盘应该有8KB才对,因为我在单片机内存中开辟了8KB。但为何会少了2KB呢?这个问题在看完后面之后你就会明白。 此时U盘里无任何文件数据,是一张空盘。 接下来用WinHex打开此盘,大家将会看到以下一些数据图片。 首先是前512字节,也就是“扇区0” 图 2 注意左边的一些信息,此U盘的大小为8K字节,(分为16个扇区 × 512字节)。也就是共有16个扇区。和我内存中开辟的缓冲区大小一致。但空闲的仅为6K字节,也就是说有2KB(即4个扇区)的容量被占用了。它们分别是: 图 3 DBR区 占用0 扇区。 FAT1表 占用 1 2 两个扇区 FAT2表 无 根目录 占用 3 扇区 数据区 占用 4------15 扇区 DBR区(DOS BOOT RECORD)即操作系统引导记录区的意思,通常占用分区的 第 0 扇区共 512 个字节(特殊情况也要占用其它保留扇区,我们先说第 0 扇)。在这 512 个字节中,其实又是由跳转指令,厂商标志和操作系统版本号,BPB(BIOS Parameter Block),扩展BPB,os引导程序,结束标志几部分组成。 图 4 表 1 跳转指令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中,偏移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表 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。 因为此为空盘,所以FAT表记录中仅有一个FAT表标志 F8 FF。 FAT表的另一扇区图,见图6。 图6 FAT文件系统的目录结构其实是一颗有向的从根到叶的树,这里提到的有向是指对于FAT 分区内的任一文件(包括文件夹),均需从根目录寻址来找到。可以这样认为:目录存储结构的入口就是根目录。 FAT 文件系统根据根目录来寻址其他文件(包括文件夹),故而根目录的位置必须在磁盘存取数据之前得以确定。FAT文件系统就是根据分区的相关DBR参数与DBR中存放的已经计算好的FAT表(2 份)的大小来确定的。格式化以后,根目录的大小和位置其实都已经确定下来了——位置紧随FAT2之后。但此U盘无FAT2,所以就紧随FAT1之后,占据第3扇区。 FAT文件系统的一个重要思想是把目录(文件夹)当作一个特殊的文件来处理,在FAT16中,虽然根目录地位并不等同于普通的文件或者说是目录,但其组织形式和普通的目录(文件夹)并没有不同。FAT 分区中所有的文件夹(目录)文件,实际上可以看作是一个存放其他文件(文件夹)入口参数的数据表。其具体存储原理是:不管目录文件所占空间为多少簇,一簇为多少字节。系统都会以32个字节为单位进行目录文件所占簇的分配。这32个字节以确定的偏移来定义本目录下的一个文件(或文件夹)的属性,实际上是一个简单的二维表。这32个字节的各字节偏移定义如表1-5所示。 因为此盘目前为空盘,所以根目录除了磁盘名称数据外,还无任何文件记录。在后面会具体举例说明。 根目录扇区数据请看图7. 图7 红色圈出来的32字节,作用是在盘符中显示名称“YangYong”。文件名“YangYong”;无扩展名;属性为归档卷标;其它项目全为0。 从第4扇区到第15扇区全为数据区,见图8。 图 8 下面我们通过在U盘中新建一个文件名为ReadMe.txt的文件来对比上面空盘,看存储内容发生了那些变化,帮助大家更好的了解FAT构架。 此时U盘容量变为5.5KB可用,见图9 图9 打开U盘可以看到我们新建的文件,见图10 图10 虽然文件只有79个字节,但却占据了512个字节,也就是一个扇区的容量。留意一下文件属性,后面我们会做对比。 打开文件,可以看到里面的内容,见图11。 图 11 用WinHex打开此U盘。扇区0的数据没有任何变化,而扇区1也就是FAT1区的数据发生了变化,如图12,请此图与前面的图5对比看 图 12 FAT1区多了两个字节,即“FF FF”表示此文件仅占一个扇区就结束了。 扇区2的数据也没有任何变化, 而扇区3作为根目录区,已经发生了变化,如图13,请与前面的图7对比看。 图13 红色圈起来的部分,为新增加的内容,下面具体分析一下其含义。 图14
日期 =(年份-1980)*512+月份*32+日 =(2010 -1980)×512 +9×32 +19 =0x3D33
时间 =小时*2048+分钟*32+秒/2 =19×512 + 21×32 +8/2 =0x9AA4
日期 =(年份-1980)*512+月份*32+日 =(2010 -1980)×512 +9×32 +19 =0x3D33
文章部分内容参考了http://blog.csdn.net/menghnhhuan/archive/2009/06/15/4270168.aspx,在此表示感谢!
第一次论坛发贴,着实耗时,初浅之极,不妥之处在所难免。。。。。。。
下面顺便上传一个查看工具和此文中用到的U盘数据文件
下一节,将以一个32MB的TF卡的实例更深入的探讨FAT文件构造的数据组织形式。请访问http://blog./singlechip/
|
|