在 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 启动菜单并手动选择分区中与 EFI 文件相对应的配置条目只会闪烁黑屏,瞬间切换视频模式,然后返回菜单。
答案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 版本有同样的问题)。
脚本
下面只有档案创建和分区检查(lsblk
和partprobe
)操作可以由非特权用户执行,因此如果您可以在 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
)
与我们可以确保安全的其它变量不同,,MNT
和TGZ
在FSTAB
这里被引用是因为生成的临时名称有可能包含可能破坏命令调用的字符,尽管这种可能性很小。
详细步骤
从具有该实用程序的 Live CD/DVD/USB 启动系统
mkfs.vfat
(您安装的那个应该可以)。备份 EFI 系统分区的内容。
挂载分区。
我们在这里使用一个临时目录,但是您可以使用,例如
/mnt
(除非它已被其他东西使用 - 请先检查)。将其内容存档到 gzip 压缩的 TAR 存档中。
您也可以将所有内容复制到某个本地目录,但存档更安全。
卸载分区。
将ESP的文件系统格式化为FAT16。
备份 ESP 的当前文件系统 UUID。
如果您打算手动执行接下来的步骤 4.2,则可以跳过此步骤。
用于
mkfs.vfat
格式化分区。如果您的 ESP 小于 16 MiB,则应该通过传递 12 作为参数将其格式化为 FAT12
-F
。这会改变分区的文件系统 UUID。
确保操作系统记录上述更改。
获取 ESP 的新文件系统 UUID。
为了简化接下来的步骤 4.2,我们在这里将其分配给一个 shell 变量,但您也可以通过执行以下命令来查看该值
lsblk -o UUID $ESP
/etc/fstab
使用新的 UUID 在根分区中更新挂载根分区。
/etc/fstab
用新值替换根分区中的旧 UUID 。或者,您可以编辑
fstab
文件并手动替换该值。卸载分区。
恢复备份的 ESP 内容。
再次安装 ESP。
提取存档的内容。
卸载分区。
确保 ESP 确实具有正确的分区类型。
检查分区类型名称是否匹配
EFI System
。或者,你可以将
c12a7328-f81f-11d2-ba4b-00a0c93ec93b
其与返回的内容进行比较lsblk -no PARTTYPE $ESP
无论如何,如果我们在这里匹配成功,下一步就没有必要了。
用于
parted
设置分区类型(如有必要)。在调用时,我们使用粗略的 shell 模式匹配来分隔设备名称(例如
/dev/sda
)和分区号(例如) ,因为这是它所需的参数格式。1
parted
核实
您可以(也可能应该)通过运行以下命令来验证分区现在是否具有有效的格式和类型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 现在应该能够识别该分区并成功启动系统。