SD卡中FAT16文件分析

来源:互联网 发布:win7打开telnet23端口 编辑:程序博客网 时间:2024/05/16 12:33

         上一篇文章介绍了SD卡spi模式的实现,接下去自己又去学了FAT16文件系统。在网上找了很多资料,觉得有一篇还不错,就拿出来和大家分享分享。

 SD卡中FAT16文件分析 

         我们通常使用的硬盘的结构基本是这样的:一个电机带着N张盘片,通过磁头对上面的存储空间对写读写。每张盘面被分为多个磁道,每个磁道上又有多个扇区。一般一个硬盘还有多个磁头。为了便于管理,人们搞出来一个文件系统,常见的就是FAT16和FAT32以及NT系统上的NTFS。当然,半导体存储器虽然没有了这些机械的结构,但文件系统格式当时是在磁盘上搞出来的,所以有些格式还是得照它的模样来做的。这里,我们仅分析最常见的一种FAT16格式,即每个扇区大小为512字节,每个簇由32个扇区组成的这一种FAT格式,其他的大家可以自己查找相关资料。由于这个资料是我自己为了使用SD卡而临时整理出来的,所以仅供大家参考之用。 下面以一张SD卡里的内容分析一下FAT16,用于帮助大家用单片机操作SD卡。 


        上面为一个512M的SD卡的第一个物理扇区,大小为512B,常称为引导扇区。即MBR(主引导记录)。这个区在电脑硬盘上这个就是bios执行完ROM中的程序后在磁盘上访问的第一块空间,这里有一些引导信息。长度为466字节,地址为0x00~0x1BD。从1BE开始,每16个字节代表一个分区,共有4个,我这张SD卡只有一个分区,所以只有1BE-1CD有内容,后面三个都是空的。这四个16字节的表项就是我们所常说的分区表。 




从物理扇区的E9处,也就是逻辑0扇区读取数据,内容如下图
                               

这个区的具体内容如下 

以上是一张SD卡的BPB(BIOS参数数据块),从上面我们可以得到一些有用的信息:
1. 卡的大小是512M
2. 每个簇有32个扇区,即16K
3. 卡的总扇区数1000215,隐含区数233
4. FAT表的大小为123个扇区
        根据FAT16的格式,主引导区后就是两个一样的分区表,分区表后面又跟了32个扇区作为
根目录区。然后后面就是存放文件和文件夹的地方了。每个分区表既然大小算出来是123
个扇区,那么FAT1在1-123扇区,FAT2就是124-246扇区,根目录就是247-278,数据区
开始于279。
         在主引导区后面就是FAT表了。从上面可以得知一个FAT表是123个扇区。它里边的内容很
简单,里边的内容就是指出下一个簇在哪里。你的盘有多少个簇,那么它的FAT表就要有多
少个项来描述它们。因为FAT16是用2个字节(16位)来描述一个簇的,所以这时FAT表的
大小就应该是2位的簇数个字节。FAT表中,第4,5个簇表示第2个簇,第6,7个字节表
示第3个簇,第8,9字节表示第4个簇……。就这样,每一个簇都有两个和它对应的字节。
这两个字节里面存放的数据就是下一个16K数据所在的簇号。2个字节最大能表示65535,
一个簇最大为32K,所以FAT16最多能给65565*32K≈2G。这就是FAT16格式为什么分区不
能大于2G的原因。实际上,并不是所有的数值都代表簇号,有几个值被赋于了特定的含义,
       我们先看看这几个特殊值代表的含义。


                                        

看一个例子吧 



        上面是我的SD卡中第一个扇区的内容。它一开始就是F8 FF FF FF,从前面的特殊数
值中可以知道,这就是硬盘的标识,并且第1簇已经被占用了。我的SD卡里有一个文件,
名子叫dssd.bin,它是我把卡买回来后拷进去的第一个文件。它的第一个簇的地址是
0x0002。这个地址从哪里得来的要看后面的内容了,暂且就把它当已知条件吧。这也就是说,
在SD卡的第2个簇里边存放着dssd.bin的第1个16K数据,那么它的第二个16K放在哪里
呢,我们要看FAT表,每2个簇对应于FAT表中的第4,5个字节,里边的内容为0003,也
就是说第2个16K数据在第3个簇里。第3个簇对应的FAT表中的数据又是什么呢,原来是
0004,也就是说第3个16K的数据在第4个簇里。这样继续跟踪,我们发现,第9个簇里的
数据是FFFF,FFFF是什么意思?看一下特殊数值的含义,原来这是最后一个簇,也就是说,
我的dssd.bin文件到此为止。于是我们只要跟着FAT表的“指路”顺利地把dssd.bin文件
从SD卡中找到了。它在卡里占用了8个簇,我的卡里边1个簇为16K,所以这个文件的大
小也就最多为128K了。所以我们只要根据SD卡的读写方法,把第2-8簇里的内容读出来就
OK了。
        注意一下,我这张卡是为了学习FAT16而买的,没有碎片,所以文件的簇和簇都是连在
一起的,但实际上并不一定都是连着的,一定要通过FAT表中的指示去寻找下一个簇所在的
位置。
        说完FAT表,下面应该来看根目录区了。根目录区里面放的东西就是根目录下所见的东
西,根据对引导扇区的分析,我们可以找到根目录区在第247扇内。用winhex打开第247
个扇区

                               
         FAT16和FAT32每个文件名都占32个字节,这里放的是短文件名,也就是“8.3”格式的。
但FAT16的根目录区只有32个扇区,计算一下,每个扇区512字节,共32个扇区,而每个
文件要占用32个字节,很显然,根目录只能放512个文件了。因此,FAT16的根目录下只
能放512个文件(及文件夹)就是这个原因。
先看前32字节,它的内容是这样的 

                                         
        就看最前面的32字节吧,它表示了一个文件(或文件夹),现在对它分析一下。前11个字节
是文件名。从后面的ASCII表中可以看出,它就是我写进去的那个名为dssd.bin。
第0x0B个字节内容为0x20,可以知道它的属性为存档,这与我们从windows中观察到的它
的属性是一致的。大小为128K,也与我们的分析一致。
                                   
        再看一下创建和修改日期吧。找到对应的字节C9 34。它代表的值为0x34C9,把它弄成2
进制就是0011 0100 1100 1001 ,把它按格式分析一下,年:0011010 月0110 日1001
换成十进制就是26,加上1980为2006年。月份为6,日期为9。与上面的结果一致。时间
也一样分析,这就不再举例了。
        再看第二项,就是第3,4行,文件名是DCIM,没有后缀名。偏移地址0B处对应的数据
为10,对照着表看一下,它是一个文件夹。按上面的方法分析它,它开始于0000 000A,也
就是第10簇。我这个文件夹下面放的是一个文件夹,相机自己建的,名子叫101CANON。根
据刚才的经验,那第一个表项一定是以101CANON开头的,没有后缀名,属性为文件夹……
跟踪过去看一下再说。
                               
        咦?不对哦,它是2E,后面是空格。第二项,也不对,它是2E2E,后面也是空格,直到第
三项才是我预想的文件夹。 那前面那个项,一个是2E,一个是2E 2E,它倒底是何方神圣,对照ASCII表,它就是一个小点“.”。这个小点什么意思,那第二项就是“..”,有没有什么启发?——DOS!那个古老的操作系统是怎么访问文件夹的?cd ..就是返回上一层目录。难道是它……?没错!就是它,一个点代表当前目录,两个点代表上级目录。哈哈。看一下当前目录那一项,一下它的地址,000A,就是这个目录。而..对应的那一项,分析一下地址。00 00,也就是根录。所以就可以利用这里找到上一级目录,于是就可以实现一级一级目录的访问了。 FAT16的结构基本就介绍到这里了,以上是我对FAT16的认识。
        相信看了上面这篇文章你肯定会对FAT16文件系统有所了解。我后来写FAT16文件系统基本上也是参考了这份资料。可以说,了解了文件系统之后,感觉自己对现代信息技术又有了一定了解,相对于只用windows上的API函数操作文件系统,有一个从根本上对文件系统的了解感觉还是踏实多了。下面的文章我会讲讲如何实现一个文件系统,并提供自己的代码供参考。