Converting the cluster number stored in FAT table (of FAT12 filesystem) for reading from a floppy disk
我正在为 FAT12 文件系统编写一个两阶段引导加载程序。引导加载程序的 stage1 从 FAT12 文件系统中的软盘加载 stage2。现在我在将簇号(我从 FAT 表中获得)转换为包含磁道、磁头和扇区号的格式时遇到问题。我正在按照教程 http://www.brokenthorn.com/Resources/OSDev6.html 制作引导加载程序。
我的困惑是,在教程中,从 FAT 获得的簇号首先转换为 LBA(线性块地址)格式,然后转换为 CHS(气缸盖扇区)格式,然后再将扇区读入内存。
为什么不能直接将Cluster Number转换成CHS格式?? FAT表不是线性存储簇号吗?我想确切地知道我在这里缺少什么??
教程中使用的引导加载程序的源代码链接在链接页面的末尾http://www.brokenthorn.com/Resources/OSDev6.html。
簇编号是线性的,但 - 如前所述 - 与数据区域相关,簇 2 是数据区域的第一个簇。然而,从磁盘读取数据是根据磁盘扇区进行的,每个 FAT 簇可能包含多个扇区——这就是转换为 LBA 的目的——从簇号转换为扇区号(因此,从所需簇数 - 考虑簇 2 是数据区的第一个簇,然后乘以每个簇的磁盘扇区数,然后在数据区之前加上正在使用的磁盘扇区数,得出绝对值存储数据的磁盘扇区。
旧的 BIOS int 0x13 函数并没有从磁盘中读取绝对扇区 - 它们读取特定磁头上特定柱面的特定扇区 (http://en.wikipedia.org/ wiki/气缸盖扇区)。因此,如果您使用这些功能,您需要采取额外的步骤来确定哪个柱面/磁头/扇区对应于您要读取的绝对扇区。另一种方法是 - 如果可用 - 使用扩展读取 int 0x13 函数,该函数直接获取绝对扇区 (LBA) 地址。
LBA 和 CHS 用于唯一标识磁盘上的所有物理扇区。
簇号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 是数据区域内的第一个簇。它不反映引导扇区、分配表副本和根目录等前面部分的大小。
-
好的.. 那么当我有一个 4 号簇时,这意味着我需要访问数据区的 4 号簇吗?但是当我看到整个磁盘并想访问集群 4 时,我不应该在做 startCluster(data area) Cluster Number 吗? 【抱歉没那么容易理解!】
-
你从簇数中减去 2,乘以每个簇的扇区数,这就是数据区域内的扇区数。 FirstSectorofCluster = ((N a€" 2) * BPB_SecPerClus) + FirstDataSector; 是文档中的公式。开始阅读文档。它都在那里。仔细阅读并思考。
-
我现在明白了!我错过了您所说的"Cluster 2 is the first cluster in data area"这一行。我以为 Cluster 的 0 和 1 是保留在数据区的。但事实上,簇"数字"0 和 1 是保留的,因此簇号 2 对应于数据区域中的第一个簇,因此公式中的 (N-2)!谢谢@Alexey Frunze .. :-)
-
只有这两个值被保留,分配表本身中的两个对应条目。数据扇区不会因为这个"2"而被浪费。