为什么 GNU parted 将数据写入 MBR 的前 440 个字节?

为什么 GNU parted 将数据写入 MBR 的前 440 个字节?

我的理解是 MBR 是 512 字节。前 440 个字节或者A很少 字节(取决于具体实现)包含引导加载程序/引导代码区域。剩余的字节包含有关分区表的信息。

如果我将磁盘的 MBR 清零...

# Zero out the MBR
dd if=/dev/zero of=/dev/sdX bs=1 count=512

然后,使用fdisk写入分区表到/dev/sdX...

# Create a 2GiB partition starting at 2048 (default).
fdisk /dev/sdX

...
Device does not contain a recognized partition table.
Created a new DOS disklabel with disk identifier ...
...

(fdisk) n
(fdisk) p
(fdisk) 1
(fdisk) 2048
(fdisk) +2G
(fdisk) w

然后读回前440个字节......

dd if=/dev/sdX bs=1 count=440

第一个440字节仍然全为零。fdisk没有触碰它们,这根据我上面发布的链接是有意义的。fdisk正在写入分区信息,因此它应该/不需要触碰第一个440

接下来的6字节不为零。我假设这些字节是现代标准 MBR 的磁盘签名

$ dd if=/dev/sdX bs=1 count=6 skip=440 | hexdump -e '4/1 "%02x " "\n"'
9a 29 97 e7

到目前为止,我对 MBR 布局的理解是合理的。这些前几个440字节被忽略,fdisk因为它们是引导加载程序的域,并且fdisk只与分区表有关。

然而,parted却让我大吃一惊。

如果我再次将同一磁盘的 MBR 清零...

# Zero out the MBR
dd if=/dev/zero of=/dev/sdX bs=1 count=512

然后,使用 parted 创建磁盘标签(fdisk上面似乎已经自动为我完成了)...

parted /dev/sdX mklabel msdos

然后读回第一个440字节......

$ dd if=/dev/sdX bs=1 count=440 | hexdump -e '16/1 "%02x " "\n"'
fa b8 00 10 8e d0 bc 00 b0 b8 00 00 8e d8 8e c0
fb be 00 7c bf 00 06 b9 00 02 f3 a4 ea 21 06 00
00 be be 07 38 04 75 0b 83 c6 10 81 fe fe 07 75
f3 eb 16 b4 02 b0 01 bb 00 7c b2 80 8a 74 01 8b
4c 02 cd 13 ea 00 7c 00 00 eb fe 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

有非零字节!这似乎与我目前对 MBR 布局方式和 GNU parted 的理解不符应该实现

GNU Parted 是一个用于创建和操作分区表的程序。

为什么要将parted数据写入前几个440字节?这些字节不是用于引导加载程序的吗?parted 不应该像fdisk以前那样保留这些字节吗?

答案1

看来我是不是仅有的一至注意arm这种行为。在某些环境中,如果磁盘上有引导加载程序,则可能会引发问题,这似乎尤其会成为一个问题。

问题是 parted 本身(并且默默地)将代码放在那里,因此嵌入式系统认为有一个有效的引导加载程序代码并愉快地挂起。

...和...

有没有什么选项可以让 parted 避免添加此代码(并且像 fdisk 一样运行)?

似乎这种parted行为故意的. 邮件列表中有位用户parted问道:

问题在于 parted 从 MBR 的最开始处生成了以下代码:

...

此代码的用途是什么?为何将其放在此处?

答案似乎是:

这是通常用于引导 BIOS 系统的 MBR 引导代码。如果它在非 x86 系统上导致问题,则应将其清零(或在分区后写入系统引导加载程序)。

似乎旨在将通用引导加载程序写入磁盘。至少,当使用mklabel标签时。我msdos认为这是有道理的,但是从fdisk和来看syslinux,分区管理器修改引导加载程序扇区似乎有点不寻常。

似乎就像parted应该不是如果存在非零数据,则会覆盖这些扇区。

不会,只有在已经存在某些内容时才会写入(例如,不是 0x00)。因此,如果您可以让 SDK 先写入其引导加载程序,然后对其进行分区,parted 将不会对其进行任何改动。

然而,这是不是我看到的行为。如果我从 写入垃圾/dev/urandom,然后运行parted mklabel​​,我的非零数据肯定会被破坏。

如果我mbr.slibpartedparted 仓库,我知道这些字节来自哪里。

$ as86 -b /dev/stdout mbr.s | hexdump -e '16/1 "%02x " "\n"'
fa b8 00 10 8e d0 bc 00 b0 b8 00 00 8e d8 8e c0
fb be 00 7c bf 00 06 b9 00 02 f3 a4 ea 21 06 00
00 be be 07 38 04 75 0b 83 c6 10 81 fe fe 07 75
f3 eb 16 b4 02 b0 01 bb 00 7c b2 80 8a 74 01 8b
4c 02 cd 13 ea 00 7c 00 00 eb fe

那是确切地parted似乎在我的磁盘上生成的字节序列。

相关内容