下面讲讲最重要的一个DBR(DOS BOOT RECORD 操作系统引导记录区) 。DBR 是我们进军 FAT32 的首道防线 。其实 DBR 中的 BPB 部分才是这一区域的核心部分(第12~90 字节为 BPB),只有深入详实地理解了 BPB 的意义,才能够更好地实现和操控 FAT32 。关于 DBR 在 FAT32 中的地位就不多说了,上面的数据中的前90个字节是BPB的主要部分 。BPB的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中数据是以小端模式存储的,所以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 表的内容如下图所示:
文章插图
上图就是一个实际的 FAT 表 。前 8 个字节“F8 FF FF 0F FF FF FF FF”为FAT32 的 FAT 表头标记,用以表示此处是 FAT 表的开始 。后面的数据每四个字节为一个簇项(从第 2 簇开始),用以标记此簇的下一个簇号 。
上面讲了很多,都是围绕簇这样一个词来讲的,簇又是什么?为什么要将它引入到 FAT32 里来呢?磁盘上最小可寻址存储单元称为扇区,通常每个扇区为 512 个字节 。由于多数文件比扇区大得多,因此如果对一个文件分配最小的存储空间,将使存储器能存储更多数据,这个最小存储空间即称为簇 。根据存储设备(磁盘、闪卡和硬盘)的容量,簇的大小可以不同以使存储空间得到最有效的应用 。在早期的 360KB 磁盘上,簇大小为 2 个扇区(1,024 字节);第一批的 10MB 硬盘的簇大小增加到8个扇区(4,096字节); 现在的小型闪存设备上的典型簇大小是8KB或 16KB 。2GB 以上的硬盘驱动器有 32KB 的簇 。如果对于容量大的存储定义了比较小的簇的话,就会使 FAT 表的体积很大,从而造成数据的冗余和效率的下降 。
需要指出的是,簇作为 FAT32 进行数据存储的最小单位,内部扇区是不能进一步细分的,即使一个文件的数据写到一个簇中后,簇中还有容量的剩余(里部扇区没有写满),哪怕这个簇只写了一个字节,其它文件的数据也是不能接在后面继续数据的,而只能另外找没有被占用的簇 。
推荐阅读
- C# 获取网络路径文件大小信息的方法
- Windows系统如何设置并连接远程桌面?详细教程来了
- 亿级流量电商系统JVM模型参数二次优化
- 文字、图片、文件 Python发送微信消息给指定好友和微信群
- 如何将Mac系统设置为简体中文?
- 提高windows10系统运行速度的几种方法
- python 用os库和xlrd、xlwd库快速合并相同n个Excel文件操作实例
- 一分钟学会在Mac中如何将文件批量重命名
- word文档怎么做红头文件,word制作红头文件详细操作-
- 读写文件 Python csv模块