解决方案

解决方案

在 VirtualBox 机器上安装 Parrot 时,我手动创建了一个 32 MiB 分区(因为我不打算多重启动或升级虚拟机,这对于单个操作系统来说已经足够了),用作 EFI 系统分区,并将其格式化为 FAT32 并设置了标志。但是UEFIboot无法将其识别(显示/访问)为可启动(FS*例如)设备。FS0

该分区具有正确的 EFI 系统分区类型 GUID

# fdisk -x /dev/sda
Disk /dev/sda: 64 GiB, 68719476736 bytes, 134217728 sectors
Disk model: VBOX HARDDISK   
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: gpt
Disk identifier: 503DB523-B5BE-6141-AC9A-20EBB03A1F51
First LBA: 2048
Last LBA: 134217694
Alternative LBA: 134217727
Partition entries LBA: 2
Allocated partition entries: 128

Device     Start       End   Sectors Type-UUID                            UUID                                 Name Attrs
/dev/sda1   2048     67583     65536 C12A7328-F81F-11D2-BA4B-00A0C93EC93B 9C0E08DE-D160-314E-8BB2-F9AC2D5E4243      RequiredPartition
/dev/sda2  67584 134206976 134139393 0FC63DAF-8483-4772-8E79-3D69D8477DE4 24F77F2E-EFC0-E040-96F8-054E9D2BD063      RequiredPartition

UEFI 无法启动操作系统,它只是无法进入 UEFI Shell,其中分区显示为设备BLK*,但没有FS*映射。因此,常见的“运行”建议FS0:\EFI\boot\bootx64.efi(及其变体)均不适用。

UEFI shell 截图

进入 UEFI 启动菜单并手动选择分区中与 EFI 文件相对应的配置条目只会闪烁黑屏,瞬间切换视频模式,然后返回菜单。

UEFI 启动菜单截图

答案1

要将分区识别为 EFI 分区:

  • 对于 GPT 磁盘,分区类型应设置为 GUID C12A7328-F81F-11D2-BA4B-00A0C93EC93B

  • 对于 MBR 磁盘,分区类型 ID 应设置为EF

EFI 系统分区

答案2

解决方案

将 EFI 系统分区格式化为 FAT16。

  • 最大 16 MiB 的分区应格式化为 FAT12。
  • 16-32 MiB(含)范围内的分区应格式化为 FAT16。
  • 对于大于 32 MiB 的内容 —建议使用 FAT32。尽管从技术上讲,FAT16 支持最大 2 GB 的卷大小(在特定操作系统上甚至更大)。

请注意,由于 FAT 的三种类型中UEFI 规范仅有的需要FAT32 用于系统分区,有些工具选择不支持 FAT12 分区(<16 MiB)。因此,对于小于 16 MiB 的分区,可能无法正常工作,并且您可能无法安装 GRUB(撰写本文时 Parrot 使用的 Calamares 版本有同样的问题)。

脚本

下面只有档案创建和分区检查(lsblkpartprobe)操作可以由非特权用户执行,因此如果您可以在 root shell 中运行所有这些操作,效果会更好。

#!/bin/sh

ESP=/dev/sda1                    ## EFI system partition (ESP).
ROOT=/dev/sda2                   ## The partition of the root file system.
MNT=$(mktemp -d --suffix=-mnt)   ## Mount point path.
TGZ=$(mktemp --suffix=-eps.tgz)  ## ESP backup archive.
FSTAB=$MNT/etc/fstab             ## The`fstab` of the root file system.
(
    set -e  ## Abort on error.

    mount $ESP "$MNT"                             ## (2.1)
    (cd "$MNT" && tar -czf "$TGZ" *)              ## (2.2)
    umount "$MNT"                                 ## (2.3)

    OLD=$(lsblk -no UUID $ESP)                    ## (3.1)
    mkfs.vfat -F 16 $ESP                          ## (3.2)
    partprobe $ESP                                ## (3.3)
    NEW=$(lsblk -no UUID $ESP)                    ## (3.4)

    mount $ROOT "$MNT"                            ## (4.1)
    sed -Ei'' "s/^(UUID)=$OLD/\1=$NEW/" "$FSTAB"  ## (4.2)
    umount "$MNT"                                 ## (4.3)

    mount $ESP "$MNT"                             ## (5.1)
    tar -C "$MNT" -xf "$TGZ"                      ## (5.2)
    umount "$MNT"                                 ## (5.3)

    TYPE=$(lsblk -no PARTTYPENAME $ESP)  ## Partition type name.
    if [ "$TYPE" != "EFI System" ]; then          ## (6.1)
        DEV=${ESP%%[0-9]*}
        parted $DEV set ${ESP#$DEV} esp on        ## (6.2)
    fi
)

与我们可以确保安全的其它变量不同,,MNTTGZFSTAB这里被引用是因为生成的临时名称有可能包含可能破坏命令调用的字符,尽管这种可能性很小。

详细步骤

  1. 从具有该实用程序的 Live CD/DVD/USB 启动系统mkfs.vfat(您安装的那个应该可以)。

  2. 备份 EFI 系统分区的内容。

    1. 挂载分区。

      我们在这里使用一个临时目录,但是您可以使用,例如/mnt(除非它已被其他东西使用 - 请先检查)。

    2. 将其内容存档到 gzip 压缩的 TAR 存档中。

      您也可以将所有内容复制到某个本地目录,但存档更安全。

    3. 卸载分区。

  3. 将ESP的文件系统格式化为FAT16。

    1. 备份 ESP 的当前文件系统 UUID。

      如果您打算手动执行接下来的步骤 4.2,则可以跳过此步骤。

    2. 用于mkfs.vfat格式化分区。

      如果您的 ESP 小于 16 MiB,则应该通过传递 12 作为参数将其格式化为 FAT12 -F

      这会改变分区的文件系统 UUID。

    3. 确保操作系统记录上述更改。

    4. 获取 ESP 的新文件系统 UUID。

      为了简化接下来的步骤 4.2,我们在这里将其分配给一个 shell 变量,但您也可以通过执行以下命令来查看该值

      lsblk -o UUID $ESP
      
  4. /etc/fstab使用新的 UUID 在根分区中更新

    1. 挂载根分区。

    2. /etc/fstab用新值替换根分区中的旧 UUID 。

      或者,您可以编辑fstab文件并手动替换该值。

    3. 卸载分区。

  5. 恢复备份的 ESP 内容。

    1. 再次安装 ESP。

    2. 提取存档的内容。

    3. 卸载分区。

  6. 确保 ESP 确实具有正确的分区类型。

    1. 检查分区类型名称是否匹配EFI System

      或者,你可以将c12a7328-f81f-11d2-ba4b-00a0c93ec93b其与返回的内容进行比较

      lsblk -no PARTTYPE $ESP
      

      无论如何,如果我们在这里匹配成功,下一步就没有必要了。

    2. 用于parted设置分区类型(如有必要)。

      在调用时,我们使用粗略的 shell 模式匹配来分隔设备名称(例如/dev/sda)和分区号(例如) ,因为这是它所需的参数格式。1parted

核实

您可以(也可能应该)通过运行以下命令来验证分区现在是否具有有效的格式和类型lsblk

$ lsblk -o PATH,FSTYPE,FSVER,PARTTYPE,PARTTYPENAME $ESP
PATH      FSTYPE FSVER PARTTYPE                             PARTTYPENAME
/dev/sda1 vfat   FAT16 c12a7328-f81f-11d2-ba4b-00a0c93ec93b EFI System

FAT12如果这就是您想要的,那么您应该在该输出中看到它,而不是FAT16

重启

UEFI 现在应该能够识别该分区并成功启动系统。

相关内容