文件系统fat32是什么意思fat32文件系统包含哪些结构fat32文件系统由什么组成




文件系统fat32是什么意思fat32文件系统包含哪些结构fat32文件系统由什么组成

2022-07-21 2:25:19 网络知识 官方管理员

  文件系统(FileSystem)是计算机系统必不可少的组成部分,可以说除了部分结构简单的单片机系统之外,文件系统是支撑每一个计算机系统运行的最重要的支撑,无论是操作系统、应用程序、文档还是音视频都是基于文件系统的。所以由此可见文件系统在计算机上的重要地位。

  嵌入式系统上有很多场合也需要使用大容量存储设备,这时候可以直接使用存储设备的读写API来进行数据的保存和读取,但是这样做的很大不足是无法和电脑系统的文件兼容,如果想将电脑系统上的一张图片或者txt文档存入嵌入式系统使用的存储器中去就会很麻烦,但是如果这个嵌入式存储器使用的是兼容FAT文件系统的存储格式那么气与个人电脑的文件交换就会大大方便。例如一般场合使用的TF卡,如果直接调用读和写函数进行TF的存取也不是不可以,但是如果这个TF卡上有FAT文件系统的话就可以使用读卡器从电脑上直接拷贝文件,大大方便了文件的交互。

  鉴于文件系统的重要性,有必要好好分析一下文件系统的组成原理,下面以当前主流的Windows文件系统FAT32为对象,分析一下文件系统的存储机制。

  下面是对FAT32文件系统的一个简要介绍:FAT32文件系统您一定不会陌生,最多看到它是在windows操作系统里,但在一些嵌入式产品(如手机、MP3、MP4等)中,也能看到它的身影。从某种意义上来讲,FAT32文件系统是非常成功的,使我们可以脱离底层储存设备驱动,更为方便高效地组织数据。给单片机系统中的大容量存储器(如SD卡、CF卡、硬盘等)配以FAT32文件系统,将是非常有意义的(如创建的数据文件可以在windows等操作系统中直接读取等)。

  我手上有一张512MB的TF卡将其插在电脑上使用二进制查看软件打开TF卡,下面是拷贝的前512字节的数据进行解说:

Offset0123456789ABCDEF00000000EB58904D53444F53352E300002087418ëX.MSDOS5.0...t.000000100200000000F800003F00FF0000000000.....ø..?.ÿ.....0000002000340F00C60300000000000002000000.4..Æ...........0000003001000600000000000000000000000000................0000004080012922BEA5F64E4F204E414D452020€.)"¾¥öNONAME000000502020464154333220202033C98ED1BCF4FAT323ɎѼô000000607B8EC18ED9BD007C885640884E028A56{ŽÁŽÙ½.|ˆV@ˆN.ŠV0000007040B441BBAA55CD13721081FB55AA750A@´A»ªUÍ.r..ûUªu.00000080F6C1017405FE4602EB2D8A5640B408CDöÁ.t.þF.ë-ŠV@´.Í00000090137305B9FFFF8AF1660FB6C640660FB6.s.¹ÿÿŠñf.¶Æ@f.¶000000A0D180E23FF7E286CDC0ED0641660FB7C9Ñ€â?÷â†ÍÀí.Af.·É000000B066F7E1668946F8837E16007539837E2Af÷áf‰Føƒ~..u9ƒ~*000000C0007733668B461C6683C00CBB0080B901.w3f‹F.fƒÀ.».€¹.000000D000E82C00E9A803A1F87D80C47C8BF0AC.è,.é¨.¡ø}€Ä|‹ð¬000000E084C074173CFF7409B40EBB0700CD10EB„Àt.<ÿt.´.»..Í.ë000000F0EEA1FA7DEBE4A17D80EBDF98CD16CD19î¡ú}ëä¡}€ëߘÍ.Í.000001006660807E02000F842000666A00665006f`€~...„.fj.fP.0000011053666810000100B4428A56408BF4CD13Sfh....´BŠV@‹ôÍ.000001206658665866586658EB33663B46F87203fXfXfXfXë3f;Før.00000130F9EB2A6633D2660FB74E1866F7F1FEC2ùë*f3Òf.·N.f÷ñþÂ000001408ACA668BD066C1EA10F7761A86D68A56ŠÊf‹ÐfÁê.÷v.†ÖŠV00000150408AE8C0E4060ACCB80102CD1366610F@ŠèÀä..̸..Í.fa.000001608274FF81C300026640497594C3424F4F‚tÿ.Ã..f@Iu”ÃBOO00000170544D4752202020200000000000000000TMGR........0000018000000000000000000000000000000000................0000019000000000000000000000000000000000................000001A00000000000000000000000000D0A4469..............Di000001B0736B206572726F72FF0D0A5072657373skerrorÿ..Press000001C020616E79206B657920746F2072657374anykeytorest000001D06172740D0A0000000000000000000000art.............000001E000000000000000000000000000000000................000001F00000000000000000AC01B901000055AA........¬.¹...Uª

  下面讲讲最重要的一个DBR(DOSBOOTRECORD操作系统引导记录区)。DBR是我们进军FAT32的首道防线。其实DBR中的BPB部分才是这一区域的核心部分(第12~90字节为BPB),只有深入详实地理解了BPB的意义,才能够更好地实现和操控FAT32。关于DBR在FAT32中的地位就不多说了,上面的数据中的前90个字节是BPB的主要部分。BPB的C语言结构体如下所示:

structFAT32_DBR{unsignedcharBS_jmpBoot[3];//跳转指令offset:0unsignedcharBS_OEMName[8];//原始制造商offset:3unsignedcharBPB_BytesPerSec[2];//每扇区字节数offset:11unsignedcharBPB_SecPerClus[1];//每簇扇区数offset:13unsignedcharBPB_RsvdSecCnt[2];//保留扇区数目offset:14unsignedcharBPB_NumFATs[1];//此卷中FAT表数offset:16unsignedcharBPB_RootEntCnt[2];//FAT32为0offset:17unsignedcharBPB_TotSec16[2];//FAT32为0offset:19unsignedcharBPB_Media[1];//存储介质offset:21unsignedcharBPB_FATSz16[2];//FAT32为0offset:22unsignedcharBPB_SecPerTrk[2];//磁道扇区数offset:24unsignedcharBPB_NumHeads[2];//磁头数offset:26unsignedcharBPB_HiddSec[4];//FAT区前隐扇区数offset:28unsignedcharBPB_TotSec32[4];//该卷总扇区数offset:32unsignedcharBPB_FATSz32[4];//一个FAT表扇区数offset:36unsignedcharBPB_ExtFlags[2];//FAT32特有offset:40unsignedcharBPB_FSVer[2];//FAT32特有offset:42unsignedcharBPB_RootClus[4];//根目录簇号offset:44unsignedcharFSInfo[2];//保留扇区FSINFO扇区数offset:48unsignedcharBPB_BkBootSec[2];//通常为6offset:50unsignedcharBPB_Reserved[12];//扩展用offset:52unsignedcharBS_DrvNum[1];//offset:64unsignedcharBS_Reserved1[1];//offset:65unsignedcharBS_BootSig[1];//offset:66unsignedcharBS_VolID[4];//offset:67unsignedcharBS_FilSysType[11];//offset:71unsignedcharBS_FilSysType1[8];//"FAT32"offset:82};

  每个字段的大小和含义都有详细的注释,解析这些数据使是们进行文件系统探秘的首要任务。需要注意的是在BPB中数据是以小端模式存储的,所以51单片机的大端模式下需要进行大小端的转换,而一般ARM的默认方式就是小端模式,所以无需进行转换操作。

  简单介绍DBR的BPB之后还需要介绍一下FAT表(文件分配表)的概念。什么是文件分配表呢?顾名思义,就是给文件分配存储空间的表,这里面存放的不是文件的数据而是文件所在的簇的信息,具体下面会给出解释。

  FAT表是FAT32文件系统中用于磁盘数据(文件)索引和定位引进的一种链式结构。可以说FAT表是FAT32文件系统最有特色的一部分,它的链式存储机制也是FAT32的精华所在,也正因为有了它才使得数据的存储可以不连续,使磁盘的功能发挥得更为出色。

  那么FAT表到底在什么地方?它到底是什么样子的?这时就要回到刚才的BPB部分了,在BPB中有一个字段叫做BPB_RsvdSecCnt,这个字段是表示保留山区数目,其实就是保留给BPB使用的空间的扇区数量,也就是说这个数值表示的就是FAT表前面的空间大小,那么FAT表的地址就是这个字段的数值了。其实在文件系统中为了保证正确性和稳定性胡设置两个完全相同的FAT表,并且两个FAT是同步的,也就是说对一个FAT表的操作,同样地,也应该在另一个FAT表进行相同的操作,时刻保证它们内容的一致。这样是为了安全起见,当一个FAT因为一些原因而遭到破坏的时候,可以从另一个FAT表进行恢复。

FAT表的内容如下图所示:

文件系统fat32是什么意思(fat32文件系统包含哪些结构)(1)

  上图就是一个实际的FAT表。前8个字节“F8FFFF0FFFFFFFFF”为FAT32的FAT表头标记,用以表示此处是FAT表的开始。后面的数据每四个字节为一个簇项(从第2簇开始),用以标记此簇的下一个簇号。

  上面讲了很多,都是围绕簇这样一个词来讲的,簇又是什么?为什么要将它引入到FAT32里来呢?磁盘上最小可寻址存储单元称为扇区,通常每个扇区为512个字节。由于多数文件比扇区大得多,因此如果对一个文件分配最小的存储空间,将使存储器能存储更多数据,这个最小存储空间即称为簇。根据存储设备(磁盘、闪卡和硬盘)的容量,簇的大小可以不同以使存储空间得到最有效的应用。在早期的360KB磁盘上,簇大小为2个扇区(1,024字节);第一批的10MB硬盘的簇大小增加到8个扇区(4,096字节);现在的小型闪存设备上的典型簇大小是8KB或16KB。2GB以上的硬盘驱动器有32KB的簇。如果对于容量大的存储定义了比较小的簇的话,就会使FAT表的体积很大,从而造成数据的冗余和效率的下降。

  需要指出的是,簇作为FAT32进行数据存储的最小单位,内部扇区是不能进一步细分的,即使一个文件的数据写到一个簇中后,簇中还有容量的剩余(里部扇区没有写满),哪怕这个簇只写了一个字节,其它文件的数据也是不能接在后面继续数据的,而只能另外找没有被占用的簇。

  那么FAT表有多大呢?FAT表中每四个字节表示一个簇,所以FAT表的大小由实际的簇数来决定。从这里也可以看出,如果簇过大,则FAT表比较小,但会造成空间的浪费,而如果簇过小,可以减小空间的浪费,但会使FAT表变得臃肿。FAT表的大小可以从BPB参数BPB_FATSz32读出。

  现在知道了FAT表的地址和FAT表的大小,也知道有两个FAT表就可以计算出第一个文件夹也就是根文件夹的位置,他的位置就在FAT表的正后方,计算方法如下:

FirstDirSector=FirstFATSector+BPB_NumFATs[0]*FATsectors

  其中FirstFATSector表示FAT表的位置,BPB_NumFATs[0]表示FAT表的数量,FATsectors表示的是FAT表占用的扇区数量。其实根目录所在的簇就是第2号簇。计算出了根文件夹的位置就可以从根文件夹中读取数据。在FAT32中其实已经把文件的概念进行扩展,目录同样也是文件,根目录的地位与其它目录是相同的,因此根目录也被看作是文件。既然是文件就会有文件名,根目录的名称就是磁盘的卷标。

  下面所以说根目录文件的内容。首先目录也是文件,它可以看做是特殊文件,这个文件使用来存放其他文件或目录的信息,例如文件名、扩展名、属性、创建时间、最后修改时间、文件起始簇号、文件长度等等。所以我要读取一个文件信息的时候首先要做的就是从目录中读取文件的信息数据。根据上面说的我们已经获取到了根目录的地址,那么就可以从根目录中读取根目录下的文件信息。每个文件/目录在目录文件中使用32个字节的数据表示,具体字段如下所示:

  这样就可以从根目录下读取各个文件,我们作为试验不设计嵌套目录的结构,只在根目录下进行文件查看、读写试验。所以在我的512M的TF卡上根目录下有一个test.txt文件,根目录的数据如下所示:

Offset0123456789ABCDEF0040000042200049006E0066006F000F00727200B.I.n.f.o...rr.004000106D006100740069006F0000006E000000m.a.t.i.o...n...0040002001530079007300740065000F00726D00.S.y.s.t.e...rm.00400030200056006F006C00750000006D006500.V.o.l.u...m.e.0040004053595354454D7E31202020160023BB58SYSTEM~1..#»X004000507E497E490000BC587E49030000000000~I~I..¼X~I......004000605445535420202020545854201823C058TESTTXT.#ÀX004000707E49814900005A577E49050013200000~I.I..ZW~I.....0040008054414E475155414E2020200800000000TANGQUAN.....00400090000000000000DA587E49000000000000......ÚX~I......004000A000000000000000000000000000000000................

  我们可以看到在根目录下的0x60到0x7F处表示的就是根目录下的text.txt文件,0x80到0x9F处则表示的是根目录。前面的两个文件信息表示的可能是一些隐藏的文件,具体我也没了解是什么。反正至此已经可以从FAT32文件系统中成功获取根目录下的文件的信息,下一步就是根据这个文件的信息寻找文件存储的位置,读取文件内容。

  32个字节的文件信息已经给得很明确了,确定了文件的其实簇号之后就可以进入FAT表中寻找那个簇以及文件的簇链,根据文件长度字段可以知道文件占用多少个簇,其实根据簇的链式存储结果就可以知道文件占用的簇数目,但是并不知道文件在最后一个簇中占用了多少个字节,所以文件长度字段还是很有意义的。找到对应的簇之后从对应的簇中读取数据即可,easyis'ntit?


发表评论:

最近发表
网站分类
标签列表