在Ubuntu ISO MBR中,为什么GPT分区会与引导分区重叠,并使MBR无法编辑?

问题和背景:

在像ubuntu-16.04-desktop-amd64.iso这样的发行版的MBR分区表中,为什么GPT分区似乎与主引导分区重叠?如果我尝试以任何方式编辑分区表,这似乎会产生错误。

我想编辑MBR以添加USB持久性(如其他地方所述),必须添加一个分区或扩大引导分区。

我相信这曾经有效,但是在这个和类似的发行版中,重叠的GPT #2分区似乎严重困扰了fdisk、sfdisk、parted、gparted和partprobe。

我的机器是MBR,而不是GPT BIOS。

我错过了什么?


以下是发行版的MBR分区表(直接来自ISO文件):
cat ubuntu-16.04-desktop-amd64.iso | xxd | head -32 | tail -5

给:

00001b0: 28db 2b00 0000 0000 708e 0e0e 0000 8000  (.+.....p.......
00001c0: 0100 0058 e0fa 0000 0000 6048 2c00 00fe  ...X......`H,...
00001d0: ffff effe ffff 4411 2c00 8012 0000 0000  ......D.,.......
00001e0: 0000 0000 0000 0000 0000 0000 0000 0000  ................
00001f0: 0000 0000 0000 0000 0000 0000 0000 55aa  ..............U.

(要解码,请参见https://en.wikipedia.org/wiki/Master_boot_record。)
  • 表格从地址01be开始,您会看到"80",表示第一个主引导分区。

  • 然后请注意地址01d2处的"ef",表示第二个主分区的类型为GPT。


这是一个按分区(小端)的表格细分:
partition#1 (normal MBR):
  80        = 'boot' partition flag
  00 01 00  = starting HSC (head, sector, cylindar)
  00        =  partition type ("Empty partition entry")
  58 e0 fa  = last     HSC (head, sector, cylindar)

  0000 0000 = LBA (logical block address) of first absolute sector in the 
  6048 2c00 = number of sectors in partition

partition #2 (GPT):
  00        = non-boot partition
  fe ff ff  = starting HSC (head, sector, cylindar)
  ef        = partition type ("EFI system partition")
  fe ff ff  = last HSC

  4411 2c00 = LBA (logical block adr) of first abs sector in part.
  8012 0000 = number of sectors in partition

尝试编辑分区表:
  • fdisk报告这些分区重叠。请注意,sdb2的起始位置[2927216]在sdb1 [0-2955679]内。

    sudo fdisk -l /dev/sdb
    

    输出如下:

      Disk /dev/sdb: 14.5 GiB, 15527313408 bytes, 30326784 sectors
      Units: sectors of 1 * 512 = 512 bytes
      Sector size (logical/physical): 512 bytes / 512 bytes
      I/O size (minimum/optimal): 512 bytes / 512 bytes
      Disklabel type: dos
      Disk identifier: 0x40a863e7
    
      Device     Boot   Start     End Sectors  Size Id Type
      /dev/sdb1  *          0 2955679 2955680  1.4G  0 Empty
      /dev/sdb2       2927216 2931951    4736  2.3M ef EFI (FAT-12/16/32)
    
  • 根据我所了解,拥有GPT分区是可以的,但是分区重叠是不允许的。

  • 当我尝试将ISO文件复制到USB闪存驱动器时,问题就开始了。闪存驱动器可以正常启动Ubuntu Live,但是无论我使用哪个分区编辑器,在未引导和未挂载的情况下都无法编辑分区表。

  • 此外,即使我删除了分区表并将USB闪存驱动器恢复到正常状态,也需要进行以下冗长的步骤:

    dd if=/dev/zero of=/dev/sdb bs=[类似512或2048的数字;无关紧要] count=[类似100000的大数字]
    

    ^较小的数字似乎并不能解决这个问题。我怀疑您不仅需要清除主要的文件系统块,还需要清除次要的文件系统块。

    然后使用fdisk在闪存驱动器上创建一个新的MS-DOS分区表。

    请注意,如果在创建新的分区表之前不执行上述dd命令以进行擦除,则在尝试编辑分区映射时(无论是来自debian8还是ubuntu-16),都会收到以下错误消息或类似消息:

    Libparted Warning The driver descriptor says the physical block size
    is 2048 bytes, but Linux says it is 512 bytes.
    
  • 另外,在ubuntu-12中,我收到了这条最有启发性的消息

    gparted -l /dev/sdb:  libparted : 2.3 Could not stat device -l -- No
    such file or directory. /dev/sdb contains GPT signatures, indicating
    that it has a GPT table.  However, it does not have a valid fake msdos
    partition table, as it should.  Perhaps it was corrupted -- possibly
    by a program that doesn't understand GPT partition tables.  Or perhaps
    you deleted the GPT table, and are now using an msdos partition table.
    Is this a GPT partition table?  Both the primary and backup GPT tables
    are corrupt.  Try making a fresh table, and using Parted's rescue
    feature to recover partitions.
    

所以我该如何编辑发行版的MBR?
顺便说一下,我不是在问如何修复重叠的问题,因为这实际上是发行版的方式,并且从外观上看,已经有一段时间了(我还看过Ub-v16、14和12),我只是想弄清楚是否可能编辑它。
想法:
- 这可能是由于使用isohybrid太多次(用于将ms-dos MBR添加到CDROM 9660 iso以便在USB上引导)引起的吗? - 是否有其他可能更新的分区表编辑器可供使用? - 是否有其他不会出现此问题的不同版本的Ubuntu发行版?

所以,我决定使用fdisk来处理GPT分区,因为它似乎是最少出问题的方法,只需删除分区,然后用xxd查看结果的分区表。现在GPT项目已经消失了(全部变成了零)。另外,我尝试使用parted来调整大小(gparted立即报错:"libparted warning - The driver descriptor says the physical block size is 2048 bytes, but Linux says it is 512 bytes.")。但是当你尝试调整第一个分区的大小时,parted也会给出同样的警告。此外,parted报告逻辑和物理顺序相反,并显示现在有两个分区。其中一个是"Apple"。 - Elliptical view
2个回答

Ubuntu的.iso镜像文件使用了一个弗兰肯斯坦怪物的格式,旨在支持多种引导方法和设备:
- 引导介质: - 将镜像写入DVD以使用ISO-9660和El Torito进行引导 - 将镜像“原始”复制到USB闪存驱动器或类似介质以使用传统磁盘分区系统进行引导
- 引导模式: - BIOS模式引导 - EFI模式引导
为了处理这么多格式和引导方法,开发人员对数据结构进行了一些技巧性操作。这些镜像不应该被视为“普通”的磁盘镜像,尤其是除非你是这些数据结构的顶级专家,否则绝对不要尝试以任何方式修改这些镜像。顺便说一下,我编写了GPT fdisk(gdisk、cgdisk和sgdisk)分区工具,而我自己也不会尝试你所说的那样做!
相反,如果你需要修改安装介质,你应该选择以下两种方法之一:
使用类似于Rufus, Pen Drive LinuxUNetbootin这样的工具将镜像文件写入USB闪存驱动器,然后修改USB闪存驱动器。之所以能够实现这一点,是因为这些工具不会简单地将镜像的内容复制到磁盘上,而是将镜像中的文件复制到一个带有预先存在的文件系统(或者有时是工具创建的文件系统)的“常规分区磁盘”中。结果是得到了一个更正常的磁盘,可以使用正常的分区表编辑器和其他实用工具对其进行修改。
准备自己的定制镜像。我没有关于如何做到这一点的文档指南,但Ubuntu镜像当然是由自动化工具创建的,而不是通过手动使用十六进制编辑器编辑分区表。如果你找到用于创建镜像的工具和脚本,也许可以创建一个按照你想要的方式进行修改的镜像。这种方法被那些创建Ubuntu“衍生版”的人使用,所以你可以从寻找如何做到这一点的文档开始。
在这两种方法中,第一种可能更适合你的需求。实际上,我相当确定有一些类似的工具提供了你想要的选项。(虽然我不记得哪个工具提供了这样的功能。)第二种方法更适用于像向自定义安装映像添加软件包这样的任务。
如果你以前曾经能够做到这种事情,那么很有可能因为开发人员发现需要制作一个更庞大的数据结构来解决特定系统的问题而进行了更改。例如,如果X品牌的计算机无法解析弗兰肯斯坦的怪物分区表,开发人员可能会对其进行调整,使其适用于X品牌的计算机,即使这意味着数据结构比以前更奇怪。不过,这只是我的猜测,我无法确切地回答你所描述的具体情况。

谢谢。在这几周里,我一直摸索着并阅读了100页关于这个的内容,你的解释是唯一让我有所理解的。我曾经尝试过unetbootin和其他两种方法,一个月前成功使用了一个带持久化功能的USB,但后来不小心丢失了(在备份时出了问题)。依我之见,Ubuntu镜像应该预先配置好持久化功能。(我知道这会磨损USB芯片,所以可以使用单层芯片)。最近unetbootin和Ubuntu上的创建工具都无法正常工作,所以我备份了数据,试图用dd命令来做,现在我明白这样做太天真了...但我学到了很多 :-) - Elliptical view
@RodSmith +1!非常有见地的回答! - user595510
这让我感到害怕,因为我正在处理一个混合的ISO,并且gdisk显示出的两个问题之一是分区重叠。所以作为gdisk的创建者,你是说我不能通过编辑GPT来解决这个问题吗?我的问题是目标系统有一个非常新的BIOS,它没有传统模式,并且无法识别这个混合ISO闪存驱动器作为可引导设备。 - Csaba Toth

解决方法

如果您不使用USB制作工具来创建U盘,而是仅使用终端命令从头开始构建U盘,那么您可以调整U盘的分区大小。以下是详细的说明,适用于使用BIOS的系统:

如何仅使用终端创建带有持久性的Ubuntu USB启动盘(适用于BIOS)


使用USB闪存驱动器进行备份的使用技巧:我保留了两个完全相同的USB备份操作系统闪存驱动器,用于备份我的主要Debian双启动W10系统。在进行备份时,我希望我的系统不在运行状态。我还希望有两个完全相同的闪存驱动器,因为有时候一个闪存驱动器会磨损。这样,我可以通过将剩余好的闪存驱动器上的dd复制到新的闪存驱动器上轻松制作一个新的备份。
当我的系统出现无法修复的严重故障时,它们曾经多次拯救了我!而且,我在上面提供的链接中包含的增量备份和恢复过程也非常快速。然而,您应该定期进行完整备份,因为可能会发生系统缺陷写入增量备份中导致其损坏的情况。我现在尽量每周进行一次完整备份。