Fdisk 输出看似荒谬的 CHS 值

Bar*_*ead 2 mbr partitioning fdisk

采用以下 fdisk 输入:

o # Create DOS/MBR partition table.
n # Create new partition.
    p # Partition type
    1 # Partition ID
    2048 # Starting sector
    +4M # Ending sector
t # Assign said partition to a FAT12 filesystem.
    1 # FAT12 filesystem.
a # Mark said partition as bootable.
w # Write partition table.
Run Code Online (Sandbox Code Playgroud)

现在,让我们看一下 MBR,特别是分区条目(分区条目从0x80第一行末尾附近开始)。

000001b0: 0000 0000 0000 0000 4a2f 9087 0000 8020  ........J/.....
000001c0: 2100 01a2 2200 0008 0000 0020 0000 0000  !..."...... ....
000001d0: 0000 0000 0000 0000 0000 0000 0000 0000  ................
000001e0: 0000 0000 0000 0000 0000 0000 0000 0000  ................
000001f0: 0000 0000 0000 0000 0000 0000 0000 55aa  ..............U.
Run Code Online (Sandbox Code Playgroud)

根据 MBR 部分条目的布局(在此处此处给出),我们可以从中收集 CHS 元组的值是0x200x210x00

0x20相当简单:它相当于第32个头。

0x21包含起始扇区和起始柱面。0x21-> 0b00100001,给出33扇区,以及柱面的第 8 位和第 9 位,结果为0( 0b00)。

0b00结合(来自0x21) 和 的柱面位0b00000000,我们得到0b0000000000柱面。总而言之,我们最终得到的起始磁头为32,起始扇区为33,起始柱面为0

当我尝试通过 BIOS 中断加载此 CHS 时,它抱怨 CHS 无效(我可以很好地读取其他扇区)。我认为这是因为头是 32;毕竟,为什么要使用 16 盘片硬盘呢?

太长了;博士

Fdisk 输出 MBR 和 CHS 值。

我的问题是我是否误解了 CHS 值是如何编码到分区条目中的,或者这是 fdisk 的一个怪癖。

use*_*686 5

根据 fdisk 本身,C/H/S 值确实应该是:

\n
\n命令(m 用于帮助):x\n\n专家命令(m 用于帮助):p\n\n磁盘测试.磁盘:64 MiB,67108864 字节,131072 扇区\n单位:1 * 512 = 512 字节的扇区\n扇区大小(逻辑/物理):512 字节/512 字节\nI/O 大小(最小/最佳):512 字节/512 字节\n磁盘标签类型:dos\n磁盘标识符:0xd771f127\n\n设备引导开始结束扇区 ID 类型  开始- C/H/S 结束-C/H/S属性\ntest.disk1 * 2048 10239 8192 1 FAT12     0/32/33 0/162/34     80\n
\n

fdisk 不会尝试匹配实际的磁盘几何结构 \xe2\x80\x93,这在 C/H/S 限制内长期以来是不可能的,因此它所做的只是计算一些值,这些值在转换回时会给出正确的结果伦敦银行管理局。

\n

来自 util-linux 的代码include/pt-mbr.h

\n
\nCommand (m for help): x\n\nExpert command (m for help): p\n\nDisk test.disk: 64 MiB, 67108864 bytes, 131072 sectors\nUnits: sectors of 1 * 512 = 512 bytes\nSector size (logical/physical): 512 bytes / 512 bytes\nI/O size (minimum/optimal): 512 bytes / 512 bytes\nDisklabel type: dos\nDisk identifier: 0xd771f127\n\nDevice     Boot Start   End Sectors Id Type  Start-C/H/S End-C/H/S Attrs\ntest.disk1 *     2048 10239    8192  1 FAT12     0/32/33  0/162/34    80\n
\n

来自 util-linux 的评论libfdisk/src/dos.c

\n
static inline void\ndos_partition_sync_chs(struct dos_partition *p,\n                       unsigned long long int part_offset,\n                       unsigned int geom_sectors,\n                       unsigned int geom_heads)\n{\n        unsigned long long int start = part_offset + dos_partition_get_start(p);\n        unsigned long long int stop = start + dos_partition_get_size(p) - 1;\n        unsigned int spc = geom_heads * geom_sectors;\n\n        if (start / spc > 1023)\n                start = spc * 1024 - 1;\n        if (stop / spc > 1023)\n                stop = spc * 1024 - 1;\n\n        p->bc = (start / spc) & 0xff;\n        p->bh = (start / geom_sectors) % geom_heads;\n        p->bs = ((start % geom_sectors + 1) & 0x3f) |\n                (((start / spc) >> 2) & 0xc0);\n\n        p->ec = (stop / spc) & 0xff;\n        p->eh = (stop / geom_sectors) % geom_heads;\n        p->es = ((stop % geom_sectors + 1) & 0x3f) |\n                (((stop / spc) >> 2) & 0xc0);\n}\n
Run Code Online (Sandbox Code Playgroud)\n
\n

为什么要使用 16 盘硬盘?

\n
\n

假装拥有一个 16 盘片硬盘,以便表示比 C/H/S 系统通常可以表示的更多磁盘空间。由于每个盘片只有 64ki 柱面 \xc3\x97 255 个扇区 \xc3\x97 2 个磁头,您所能达到的容量是每个盘片约 8 GB,显然磁盘现在已经稍微超出了这个范围。

\n

操作系统或固件并不单独控制每个磁头,它只是通过 ATA 命令将数字传递到磁盘并获取数据,因此它并不真正关心磁盘是否有 255 个磁头。磁盘本身也不再 \xe2\x80\x93 磁盘现在做的第一件事是使用公式将 C/H/S 值转换为线性 LBA 地址(假设磁盘被指定为 C/H/S 而不是)首先是 LBA)。

\n

因此,即使在 BIOS 和操作系统转而直接处理 LBA 之前,使用“荒谬的”C/H/S 值来访问该格式通常允许的更多磁盘空间已经很常见。

\n

所有当前的操作系统都只是忽略 MBR 中的 C/H/S 字段并专门处理 LBA,显然这就是“OnTrack 磁盘管理器”在 MS-DOS 中所做的事情。(此外,据我所知,SCSI 磁盘从一开始就不支持 C/H/S,它们始终仅支持 LBA。)我有点确定,现在您会发现的几乎所有 BIOS 都具有本机通过“扩展 INT 13h”支持 LBA(正如 Google 告诉我的)。

\n