FAT32文件操作系统(主要针对SD卡)

14 篇文章 16 订阅

   

目录

一、主引导扇区

二、什么是文件系统?

三、对FAT32的简单介绍

        1.保留区

        2.FAT表

        3.数据区

四、总结


    最近的项目用到了SD卡数据读取,了解FAT32系统着实恶心了我一下,分享一下自己的笔记。

    u 盘,sd 卡等小容量存储介质不存在仔细的 分区。但是 在文件系统初始化的开始我们必须通过 MBR 获取分区表项的数据,以获得 CHS、LBA 参数以及分区大小扇区 数,从而得到文件系统的起始物理扇区号。 Microsoft 将使用 DOC 分区体系的磁盘称为“主引导记录(Master Boot recorder, MBR)”磁盘,这 是对于使用“全局 ID 分区表(GUID Partition Table, GPT)磁盘”而言的。

一、主引导扇区

  使用“DOC 分区”体系时,磁盘的第一个——也就是 0 号扇区被称为主引导记录扇区,也称为主引导 记录 MBR(Master Boot recorder,MBR)。 1. MBR 数据结构 MBR 由 446 个字节的引导代码、64 字节的主分区(4 个)表及两个字节的签名值“55 AA”组成。 可以用 WinHex 打开一个 SD 卡的 MBR 查看(即0号扇区)。(注意数据是用高位到低位的方式存储的)

字段定义如下表(BPB 后面的 422 个字节对我们的意义不大,表中省略):

字段名称长度含义偏移量
jumpBoot3跳转指令0
OEMName8标记格式化该分区的操作系统名称与版本号3
BytesPerClus2每扇区字节数11
SecPerClus1每簇扇区数13
RsvdSecCnt2保留扇区数目14
NumFATs1此卷中FAT数16
RootEntCnt2FAT32为017
TotSec162FAT32为019
Media1存储介质21
FATSz162FAT32为022
SecPerTrk2磁道扇区数24
NumHeads2磁头数26
HiddSec4FAT区前隐扇区数28
TotSec324该卷总扇区数32
FATSz324FAT表扇区数36
ExtFlags2FAT32特有40
FSVer2FAT32特有42
RootClus4根目录簇号44
FSInfo2文件系统信息48
BKBootSec2通常为650
Reserved12扩展用52
DrvNum164
Reserved1165
BootSig166
VolID467
FilSysType1171
FilSysType1882

在0号扇区的数据中,只有前90个字节为有用数据,从表中对应的数据含义可以得出文件系统的具体参数。

在C语言中可以简单的定义一个结构体来包含我们想要的参数

struct FAT32_DBR
{
 unsigned char BS_jmpBoot[3]; //跳转指令 offset: 0
 unsigned char BS_OEMName[8]; // offset: 3
 unsigned char BPB_BytesPerSec[2];//每扇区字节数 offset:11
 unsigned char BPB_SecPerClus[1]; //每簇扇区数 offset:13
 unsigned char BPB_RsvdSecCnt[2]; //保留扇区数目 offset:14
 unsigned char BPB_NumFATs[1]; //此卷中 FAT 表数 offset:16
 unsigned char BPB_RootEntCnt[2]; //FAT32 为 0 offset:17
 unsigned char BPB_TotSec16[2]; //FAT32 为 0 offset:19
 unsigned char BPB_Media[1]; //存储介质 offset:21
 unsigned char BPB_FATSz16[2]; //FAT32 为 0 offset:22
 unsigned char BPB_SecPerTrk[2]; //磁道扇区数 offset:24
 unsigned char BPB_NumHeads[2]; //磁头数 offset:26
 unsigned char BPB_HiddSec[4]; //FAT 区前隐扇区数 offset:28 
 unsigned char BPB_TotSec32[4]; //该卷总扇区数 offset:32
 unsigned char BPB_FATSz32[4]; //一个 FAT 表扇区数 offset:36
 unsigned char BPB_ExtFlags[2]; //FAT32 特有 offset:40
 unsigned char BPB_FSVer[2]; //FAT32 特有 offset:42
 unsigned char BPB_RootClus[4]; //根目录簇号 offset:44
 unsigned char FSInfo[2]; //保留扇区 FSINFO 扇区数 offset:48
 unsigned char BPB_BkBootSec[2]; //通常为 6 offset:50
 unsigned char BPB_Reserved[12]; //扩展用 offset:52
 unsigned char BS_DrvNum[1]; // offset:64
 unsigned char BS_Reserved1[1]; // offset:65
 unsigned char BS_BootSig[1]; // offset:66
 unsigned char BS_VolID[4]; // offset:67
 unsigned char BS_FilSysType[11]; // offset:71
 unsigned char BS_FilSysType1[8]; //"FAT32 " offset:82
};

    注意:读回来的字节拼在一起,与实际的数据并不吻合。例如 BPB_BytesPerSec 读出来的内容是“00 02”,在程序中我们把 00 作为 int 型变 量的高字节,把 02 作为其低字节,那么这个变量的值为 2,而实际的 SD 卡里的 扇区大小为 512 个字节,这 512 与 2 之间相去甚远。

   是什么造成这种现象的呢? 这就是大端模式与小端模式在作怪。上面我们合成 int 型变量的方法(00 为 高字节,02 为低字节)为小端模式。而如果我们改用大端模式来进行合成的话, 结果就会不同:将 02 作高字节,而把 00 作低字节,变量值就成了 0x0200(十进 制的 512),这样就和实际数据吻合了。可见 FAT32 中字节的排布是采用小端模式 的。在我们程序中需要将它转为大端模式的表达方式。

二、什么是文件系统?

  文件系统是为了长久的存储和访问数据而为用户提供的一种基于文件和目录的存储机制。

  使用硬盘存储数据之前,首先要进行分区(当然你也可以不分区),然后对分区(或整个硬盘)进行格式 化,其实格式化的过程就是在分区内建立文件系统的过程。一个文件系统由系统结构和按一定规则存放的 用户数据组成。比如,如果在 windows 下当我们要格式化一个分区或是其他存储介质时, windows 会弹出一个对话框,上面有这样一些选择内容:容量、文件系统、分配单元大小、卷标等等。其中文件系统的下拉菜单中就有几种不同的文件系统共供户选择,一般我们都会选择默认、FAT32 或 NTFS 文 件系统,当我们按下格式化按钮后,操作系统就开始为这个分区建立你所选择的文件系统。

   文件系统种类繁多,但所有的文件系统都有一定的共性 :

    1. 数据单元 数据在写入磁盘或从磁盘读取数据时每次操作的数据量称为数据单元,它的大小在建立文件系统时确 定。数据单元在不同的文件系统中有不同的称呼:例如在 FAT 和 NTFS 文件系统中称作“簇(Cluster)”, ExtX 中称作“块(Block)”等。一个数据单元由若干个连续的扇区组成,大小总是 2 的整数次幂个扇区。

    2. 坏数据单元 坏数据单元也就是包含缺陷扇区的数据单元。

    3. 逻辑文件系统地址 磁盘上的一个扇区在不同的情况下会有不同的地址表达形式。 &每个扇区都会有一个 LBA 地址,也就是物理地址 &每个物理卷内的扇区又有一个物理卷地址 &在逻辑卷内部的扇区会有一个逻辑卷地址 (以上几个概念比较容易混淆,注意区分)

    4. 逻辑文件地址 对于每个文件来说,将它按所在文件系统中的数据单元大小为单位进行分割,分割后的每一个部分由 0 开始编号,这个编号就是其对应数据单元的逻辑文件地址。一个文件前后相邻的两个数据单元在物理上 的存储地址可能是不连续的,但它的逻辑文件地址一定是连续的。

    5. 分配策略 【1】第一可用分配策略,即当为一个文件分配了一个存储单元后还要继续为其分配时,操作系统会重新从文件系统的起始处搜索可以使用的空间。

【2】下一可用分配策略,即为文件分配了一个储存单元后并不再回到卷开始处重新寻找可用空间,而是直接向后进行搜索。

【3】最佳分配策略,即在为文件分配空间时,会尽可能找到足够的连续空间以避免其片段化。

   6. 松弛空间 松弛空间分为两种,一种是数据的结尾与为其分配的空间结束处的未使用部分,还有一种就是位于分 区结尾的卷松弛空间。

   7.元数据 任何文件和目录都会有一个名字,我们将其统称为“文件名”。除了文件名外,文件或目录还有其他 一些描述信息,如大小,时间信息,是否加密或压缩,储存位置信息等,我们将这些描述信息统称为文件 或目录的元数据。(这部分数据也是我们读取写入的关键)

 三、对FAT32的简单介绍

    FAT(File Allocation Table,文件分配表)文件系统是 windows 操作系统所使用的一种文件系统, 它的发展过程经历了 FAT12、FAT16、FAT32 三个阶段。

   FAT 文件系统用“簇”作为数据单元。一个“簇”由一组连续的扇区组成,簇所含的扇区数必须是 2 的整数次幂。簇的最大值为 64 个扇区,即 32KB。所有簇从 2 开始进行编号,每个簇都有一个自己的地址 编号。用户文件和目录都存储在簇中。

   FAT 文件系统的数据结构中有两个重要的结构:文件分配表和目录项: &文件和文件夹内容储存在簇中,如果一个文件或文件夹需要多余一个簇的空间,则用 FAT 表来描述 如何找到另外的簇。FAT 结构用于指出文件的下一个簇,同时也说明了簇的分配状态。FAT12、FAT16、FAT32 这三种文件系统之间的主要区别在与 FAT 项的大小不同。 &FAT 文件系统的每一个文件和文件夹都被分配到一个目录项,目录项中记录着文件名、大小、文件内 容起始地址以及其他一些元数据。

   在 FAT 文件系统中,文件系统的数据记录在“引导扇区中(DBR 和MBR其实是一个东西)”中。引导扇区位于整个文件系统的 0 号扇区,是文件系统隐藏区域(也称为保留区)的一部分,我们称其为 DBR(DOS Boot Recorder——DOS 引导记录)扇区,DBR 中记录着文件系统的起始位置、大小、FAT 表个数及大小等相关信息。 在 FAT 文件系统中,同时使用“扇区地址”和“簇地址”两种地址管理方式。这是因为只有存储用户 数据的数据区使用簇进行管理(FAT12 和 FAT16 的根目录除外),所有簇都位于数据区。其他文件系统管理 数据区域是不以簇进行管理的,这部分区域使用扇区地址进行管理。文件系统的起始扇区为 0 号扇区。

说明: 【1】 保留区含有一个重要的数据结构——系统引导扇区(DBR)。FAT12、FAT16 的保留区通常只有 一个扇区,而 FAT32 的保留扇区要多一些,除 0 号扇区外,还有其他一些扇区,其中包括了 DBR 的备份扇区。

【2】 FAT 区由来年各个大小相等的 FAT 表组成——FAT1、FAT2,FAT2 紧跟在 FAT1 之后。

【3】 FAT12、FAT16 的根目录虽然也属于数据区,但是他们并不由簇进行管理。也就是说 FAT12、 FAT16 的根目录是没有簇号的,他们的 2 号簇从根目录之后开始。而 FAT32 的根目录通常位 于 2 号簇。

1.保留区

FAT32 文件系统的开始部分有一个由若干个扇区组成的保留区,保留区的大小会记录在 DBR 扇区中, 比较常见的大小为 32、34 或 38 个扇区。

(1).引导扇区

关于DBR或者MBR中关于磁盘的具体信息可以在第一部分中看到。

(2).引导代码

  FAT 文件系统将引导代码与文件形同数据结构融合在一起,而不像 Unix 文件系统那样各自存在,引导 扇区的前三个字节为一个由机器代码构成的跳转指令,以使 CPU 越过跟在后面的配置数据跳转到配置数据 后面的引导代码处。

  FAT32 文件系统引导扇区的 512 字节中,90~509 字节为引导代码(即在0扇区除了引导扇区的剩余部分),而 FAT12/16 则是 62~509 字节为引 导代码。同时,FAT32 还可以利用引导扇区后的山区空间存放附加的引导代码。 一个 FAT 卷即使不是可引导文件文件系统,也会存在引导代码。

(3)。FSINFO 信息扇区

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

【1】0x00~0x03: 4 个字节,扩展引导标志“52526141”。

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

【3】0x1E4~0x1E7: 4 个字节,FSINFO 签名“72724161”。

【4】0x1E8~0x1EB: 4 个字节,文件系统的空簇数,4294967295(0xFF FF FF FF)。

【5】0x1EC~0x1EF: 4 个字节,下一可用簇号,2(0x 00 00 00 02)。

【6】0x1F0~0x1FD: 14 个字节,未使用。

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

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

2.FAT表

     (1). FAT 表概述 :位于保留区后的是 FAT 区,有两个完全相同的 FAT(File Allocation Table, 文件分配表)表组成, FAT 文件系统的名字也是因此而来。

     重要说明: 1. 对于文件系统来说,FAT 表有两个重要作用:描述簇的分配状态以及标明文件或目录的下一簇的 簇号。

     2. 通常情况下,一个 FAT 把文件系统会有两个 FAT 表,但有时也允许只有一个 FAT 表,FAT表的具体个数记录在引导扇区的偏移 0x10 字节处。

     3. 由于 FAT 区紧跟在文件系统保留区后,所以 FAT1 在文件系统中的位置可以通过引导记录中偏移 0x0E~0x0F 字节处的“保留扇区数”得到。

     4. FAT2 紧跟在FAT1 之后,它的位置可以通过 FAT1 的位置加上 FAT 表的大小扇区数计算出来。

    (2). FAT 表的特性 :

       FAT 表由一系列大小相等的 FAT 表项组成,总的说来 FAT 表有如下特性:

      1. FAT32 中每个簇的簇地址,是有 32bit(4 个字节)记录在 FAT 表中。FAT 表中的所有字节位置以 4 字节为单位进行划分,并对所有划分后的位置由 0 进行地址编号。0 号地址与 1 号地址被系统 保留并存储特殊标志内容。从 2 号地址开始,每个地址对应于数据区的簇号,FAT 表中的地址编 号与数据区中的簇号相同。我们称 FAT 表中的这些地址为 FAT 表项,FAT 表项中记录的值称为 FAT 表项值。

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

       3. 如果某个簇未被分配使用,它所对应的 FAT 表项内的 FAT 表项值即用 0 进行填充,表示该 FAT 表 项所对应的簇未被分配。

       4. 当某个簇已被分配使用时,则它对应的 FAT 表项内的 FAT 表项值也就是该文件的下一个存储位置 的簇号。如果该文件结束于该簇,则在它的 FAT 表项中记录的是一个文件结束标记,对于 FAT32 而言,代表文件结束的 FAT 表项值为 0x0FFFFFFF。         5. 如果某个簇存在坏扇区,则整个簇会用 FAT 表项值 0xFFFFFF7 标记为坏簇,不再使用,这个坏簇 标记就记录在它所对应的 FAT 表项中。

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

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

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

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

        10. 对文件或目录进行操作时,他们所对应的 FAT 表项将会被清空,设置为 0 以表示其所对应的簇处 于未分配状态。

3.数据区

   (1) 根目录

     虽然原则上 FAT32 允许根目录位于数据去的任何位置,但通常情况下它都位于 2 号簇。 1. 定位根目录 在 FAT 文件系统中,寻找第一簇(即 2 号簇)的位置也就是寻找数据区的开始位置,这并不是一件容 易的事,因为它不是位于文件系统开始处,而是位于数据区。在数据区前面是保留区域和 FAT 区域,这两 个区域都不使用 FAT 表进行管理。因此,数据区以前的区域只能使用扇区地址(逻辑卷地址),而无法使用 簇地址。 要想定位一个 FAT32 文件系统的数据起始处,可以通过引导扇区的相关参数计算出来。

     1.从引导扇区 的偏移 0x0E~0x0F 字节处得到保留扇区。

     2.从偏移 0x10 字节处得到 FAT 表的个数。

     3.从偏移 0x24~0x27 字 节处得到每个 FAT 表的大小扇区数。

     4.利用如下公式计算: 保留扇区数 + 每个 FAT 表大小扇区数 × FAT 表个数 = 数据区起始扇区号

     要想计算其他已知簇号的扇区号,还要由引导扇区的偏移 0x0D 字节处查找到每个簇大小扇区数,并 使用如下公式计算: 某簇起始扇区号 = 保留扇区数 + 每个 FAT 表大小扇区数 × FAT 表个数 + (该簇簇号 - 2) × 每簇扇 区数。

(2)文件或子目录

【1】0x00~0x00:1 个字节,如果该目录项正在使用中,则为文件名或子目录名的第一个字符。  0x00:说明该目录项未被分配使用。  0xE5:说明该目录项曾经被使用过,但是现在已被删除。目前处于未分配状态

【2】0x01~0x0A:10 个字节,文件名的第 2 至第 11 个 ASCII 码,除扩展名外,如果文件的名字不足 8 个字符则用 0x20 进行填充。

【3】0x0B~0x0B:1 个字节,所描述文件的属性  0x01-只读  0x02-隐藏  0x04-系统文件  0x08-卷标  0x0F-为此值时表示该目录项为长文件名目录项  0x10-目录  0x20-存档

【4】0x0C~0x0C:1 字节,保留

【5】0x0D~0x0D:1 个字节,文件穿件的时间,精确到创建时刻的十分之一秒

【6】0x0E~0x0F:2 个字节,文件创建的时间——时分秒 两个字节的 16bit 被划分为 3 个部分:  0~4bit 为秒,以 2 秒为单位,有效值为 0~29,可以表示的时刻为 0~58  5~10bit 为分,有效值为 0~59  11~15bit 为时,有效值为 0~23 下面举例说明: 如上图所示,其子目录项偏移 0x0E~0x0F 字节处的内容为“A1A9”,我们来计算一下。由于 FAT 文件系 统数据采用的小端存储方式,因此“A1A9”表示成 16进制为 0xA9A1,换算成 2进制就是 1010 1001 1010 0001, 我们将其分成三部分并计算它的值,如下图所示: 下面我们再回过头来看看丫头这个目录的属性,点击右键选择属性一项可以看到: 可以看到上面的创建时间是 21:13:03,在误差允许的范围内。

【7】0x10~0x11:2 个字节,文件创立的日期,16bit 也划分为三个部分:  0~4bit 为日,有效值为 1~31  5~10bit 为月,有效值为 1~12  11~15bit 为时,有效值为 0~127,这是一个相对于 1980 年的年数值,也就是说该值加上 1980 即为文件创建的日期值。该部分笔者就不再举例就计算了,原理和计算创建时间是一样的。请 读者自己去计算。

【8】0x12~0x13:2 个字节,最后访问日期。

【9】0x14~0x15:2 个字节,文件起始簇号的高两个字节。

【10】0x16~0x17:2 个字节,文件最后修改的时间。

【11】0x18~0x19:2 个字节,文件最后被修改时的日期。

【12】0x1A~0x1B:文件内容起始簇号的低两个字节,与 0x14~0x15 字节处的高两个字节组成文件内容 起始簇号。

【13】0x1C~0x1F:文件内容大小字节数,只对文件有效,子目录的目录项此处全部设置为 0。

四、总结

    这时候我们想要读取SD卡(FAT32系统)中具体某一文件的数据的步骤就很清晰了。

  (1).首先从0扇区中读取出磁盘的基本信息,得到根目录的位置。

  (2).将根目录所在扇区的位置读取出来,找到目标文件的起始簇号。

  (3).找到文件对应的FAT表项对文件进行顺序读取。

  • 5
    点赞
  • 32
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
FAT32文件分配表32)是一种常见的文件系统用于在计算机硬盘驱动器上存储和管理文件。该文件系统最早由微软引入,适用于各种操作系统,包括Windows、macOS和Linux。FAT32文件系统主要用于较小的存储设备,例如闪存驱动器和SD卡FAT32文件系统采用了有趣的文件结构,其中包含了几个重要的组件。首先是引导记录(Boot Record),其位于存储设备的第一个扇区中。引导记录存储了启动硬件的相关信息,并在文件系统初始化时充当重要的角色。 文件分配表(File Allocation Table)是FAT32文件系统的核心组件之一。它记录了存储设备上每个文件的分配信息。文件分配表中的每个表项都指示与文件相关的簇(cluster)号码,用于确定文件在存储设备上的物理位置。 目录条目(Directory Entry)也是FAT32文件系统中重要的组成部分。每个目录条目对应着一个文件或子目录。每个目录条目包含一些元数据信息,例如文件名、扩展名、文件大小、创建日期等。FAT32文件系统使用一种层次结构来组织目录条目,使得用户可以轻松地浏览和查找文件。 在FAT32文件系统中,还有一个名为文件簇(Cluster)的概念。文件簇是最小的可分配存储单位,用于存储文件的内容。文件系统通过在文件分配表中跟踪文件的簇号码来定位文件的内容所在位置。每个簇的大小通常是4KB或8KB,具体取决于存储设备的大小。 总的来说,FAT32文件系统结构包括了引导记录、文件分配表、目录条目和文件簇等关键组件。这些组件紧密配合,使得FAT32文件系统能够在存储设备上高效地存储和管理文件。虽然FAT32文件系统有一些限制,如单个文件的最大大小仅为4GB,但它仍然被广泛应用于移动存储设备等场景中,由于其易于兼容和可靠性的特点。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

daijingxin

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值