将存储在 FAT 表(FAT12 文件系统)中的簇号转换为从软盘读取

Posted

技术标签:

【中文标题】将存储在 FAT 表(FAT12 文件系统)中的簇号转换为从软盘读取【英文标题】:Converting the cluster number stored in FAT table (of FAT12 filesystem) for reading from a floppy disk 【发布时间】:2013-01-24 23:53:15 【问题描述】:

我正在为 FAT12 文件系统编写一个两阶段引导加载程序。引导加载程序的 stage1 从 FAT12 文件系统中的软盘加载 stage2。现在我在将簇号(我从 FAT 表中获得)转换为包含磁道、磁头和扇区号的格式时遇到问题。我正在按照教程 http://www.brokenthorn.com/Resources/OSDev6.html 制作引导加载程序。

我的困惑是,在教程中,从 FAT 获得的簇号首先转换为 LBA(线性块地址)格式,然后转换为 CHS(气缸盖扇区)格式,然后再将扇区读入内存。

为什么不能直接将Cluster Number转换成CHS格式?? FAT表不是线性存储簇号吗?我想确切地知道我在这里缺少什么??

教程中使用的bootloader的源代码链接在http://www.brokenthorn.com/Resources/OSDev6.html链接的页面末尾。

【问题讨论】:

【参考方案1】:

簇数是线性的,但 - 如前所述 - 与数据区域相关,簇 2 是数据区域的第一个簇。然而,从磁盘读取是根据磁盘扇区,每个 FAT 簇可能包含多个扇区 - 这就是转换为 LBA 的目的 - 从簇号转换为扇区号(因此,从所需的簇数中减去 2 - 说明簇 2 是数据区的第一个簇,然后乘以每个簇的磁盘扇区数,然后在数据区之前加上正在使用的磁盘扇区数, 得出存储我们数据的绝对磁盘扇区。

旧的 Bios int 0x13 函数并没有从磁盘读取绝对扇区 - 它们读取特定磁头上特定柱面的特定扇区 (http://en.wikipedia.org/wiki/Cylinder-head-sector)。因此,如果您使用这些功能,您需要采取额外的步骤来确定哪个柱面/磁头/扇区对应于您要读取的绝对扇区。另一种方法是 - 如果可用 - 使用 extended read int 0x13 函数,该函数直接获取绝对扇区 (LBA) 地址。

【讨论】:

【参考方案2】:

LBACHS 用于唯一标识磁盘上的所有物理扇区。

簇号 OTOH 仅在分区内有意义,它与分区的开头(其数据区域)相关,它可以唯一标识分区内多个扇区的块。

所以,尽管它们的功能相似,但两者之间还是有很大区别的。

而且硬件(或 BIOS)不知道也不应该知道关于集群的任何事情。因此,您必须将簇号转换为LBAs(然后可能转换为CHS)才能访问存储设备上的数据。

【讨论】:

当您说“簇号,....,是相对于分区(其数据区域)的开头...”时,您的意思是FAT表中的簇号是相对于根目录之后的 FAT12 数据区域的开头?? 查看微软关于 FAT12/16/32 的官方文档,fatgen103.doc。 我对此有点困惑。我所理解的是,FAT 提供了一个相对于数据区域开始的簇号。所以现在如果我的数据区从簇 32 开始(引导扇区、FAT1、FAT2、RootDirectory 使用 32 个扇区,我有 1 个扇区/簇)并且我从 FAT 表中得到了簇号 4,那么我如何计算线性地址集群?如果我把它放在公式 (cluster-2)*sectorsPerCluster 中,我得到的答案是簇 2,这显然是不正确的。你能告诉我FAT表中的簇号是什么吗?? 在这种情况下,一个明显的方法是将 FAT 中的簇号添加到数据区的起始簇(即 31)。但我知道这是错误的方式。我无法准确理解 FAT 提供的簇号类型。请帮忙! 集群编号从 2,AFAIR 开始,0 和 1 被保留。簇 2 是数据区域内的第一个簇。不反映引导扇区、分配表副本、根目录等前面部分的大小。

以上是关于将存储在 FAT 表(FAT12 文件系统)中的簇号转换为从软盘读取的主要内容,如果未能解决你的问题,请参考以下文章

FAT32文件系统的数据结构

文件系统

FAT和EXFAT文件系统

FAT和EXFAT文件系统

FAT32文件系统的存储组织结构

两个一样的硬盘(除了分区表不一样)一样的文件 占用空间为啥不一致?