Arch Win11 Dualboot 手动重建 EFI 分区
/ 7 min read
Table of Contents
前情提要: 硬盘上已经有 Windows 11 和 ArchLinux 两个系统, 因为 Windows 自带的 EFI 只有 100MB 塞不下,所以我直接把他给格式化了, 现在需要重新建立引导.
但是我的os-prober无法识别 Windows 11 然后他每次跑卡住了, 所以我准备手写 grub
我的磁盘分区表都是GPT
下面命令我都不会写sudo, 需要自己加上就好了
TODO:
- Arch 用 chainlaoder 引导
0. 准备
- Arch 安装盘
- 一个 Windows PE 盘, 我是刷的 Hiren’s BootCD PE, 可以想办法进 Arch 里面(通过
arch-chroot) 然后用下面的方法刷 - 硬盘还有 300MB 左右的空间分一个独立的 EFI 分区, 位置无所谓, 我上放在 ArchLinux 的分区前
0.0 刷 Hiren’s BootCD PE
- 在 ArchLinux 中
- 下载 Hiren’s BootCD PE 的 ISO
- 格式化一个 U 盘:
- 先用
lsblk看 USB 的标识, 假设是/dev/sdb - 用
cfdisk /dev/sdb把里面的都删除了, 然后写入新分区 - 用
mkfs.fat -F 32 /dev/sdb格式化成 FAT32 - 用
sudo dd bs=4M if=HBCD_PE_x64.iso of=/dev/sdb conv=fsync oflag=direct status=progress烧录 ISO
- 先用
0.1 格式化 EFI 分区
- 在 ArchLinux 中
- 用
lsblk看 EFI 分区的标识, 假设是/dev/nvme0n1下 - 用
cfdisk /dev/nvme0n1在里面分一个 300MB 左右的 EFI 分区 - 用
mkfs.fat -F 32 /dev/nvme0n1p7格式化 EFI 分区成 FAT32 (或者不用-F 32格式化成 FAT16 也行)
1. 重建 Arch 引导
-
在 ArchLinux 中
-
用
mount /dev/nvme0n1p7 /boot挂载 EFI 分区, 如果还没挂载 -
grub-install --target=x86_64-efi --efi-directory=/boot --bootloader-id=GRUB来装grub文件, 参考 ArchWiki- 会在
/boot/grub下创建grub文件夹
- 会在
-
pacman -S linux intel-ucode把内核和 ucode 的 img 都写入到 EFI 分区 (如果不是 intel 的就装对应 ucode, 然后你要是用linux-lts也可以装linux-lts)- 会在
/boot下创建intel-ucode.img,vmlinuz-linux,initramfs-linux.img和initramfs-linux-fallback.img
- 会在
-
记得把
/etc/default/grub里的GRUB_DISABLE_OS_PROBER="false"给注释掉, 因为我们不打算用os-prober -
进入
/etc/grub.d/下, 用cp 40_custom 10_linux复制一份 (前面的数字 10 是优先级, 10 会在 grub menu 中显示在 40 的前面, 后面的 linux 是名字可以随便取) -
cat /etc/fstab看一下 EFI 分区和 ArchLinux 分区的 UUID, 假设是1111-A1B2和11111111-1111-1111-1111-111111111111 -
编辑
/etc/grub.d/10_linux, 改成#!/bin/shexec tail -n +3 $0# This file provides an easy way to add custom menu entries. Simply type the# menu entries you want to add after this comment. Be careful not to change# the 'exec tail' line above.menuentry "Arch" {insmod part_gptinsmod fatinsmod ext2insmod gzioset root='<EFI DISK PARTISION ID>'search --no-floppy --fs-uuid --set=root <EFI UUID>linux /vmlinuz-linux root=UUID=<ARCH UUID> rw loglevel=3initrd /intel-ucode.img /initramfs-linux.img}其中
<EFI DISK PARTISION ID>是 EFI 分区的硬盘表达 (一般来说不准没什么用, 因为如果你插入了其他 USB, 他硬盘顺序就乱了) 比如在lsblk下/dev/nvme0n1是第一个磁盘,/dev/nvme0n1p7就代表第7块扇区, 所以他的表达就是'hd1,7'或者'hd1,gpt7'或者(hd1,gpt7);<EFI UUID>是 EFI 分区的 UUID;<ARCH UUID>是 ArchLinux 分区的 UUID
/vmilinuz-linux是内核文件,/intel-ucode.img是 ucode 文件,/initramfs-linux.img是内核镜像文件, 他们都在/boot下 (在 #1.3 中安装) 填入后就像:#!/bin/shexec tail -n +3 $0# This file provides an easy way to add custom menu entries. Simply type the# menu entries you want to add after this comment. Be careful not to change# the 'exec tail' line above.menuentry "Arch" {insmod part_gptinsmod fatinsmod ext2insmod gzioset root='hd1,gpt7'search --no-floppy --fs-uuid --set=root 1111-A1B2linux /vmlinuz-linux root=UUID=11111111-1111-1111-1111-111111111111 rw loglevel=3initrd /intel-ucode.img /initramfs-linux.img} -
grub-mkconfig -o /boot/grub/grub.cfg生成grub.cfg -
到目前为止, ArchLinux 的引导就重建好了
2. 重建 Windows 引导
- 在 Windows PE 中
diskpart进入磁盘管理- 参考之前看的 EFI 分区的位置, 选中 EFI 分区, 假设是
hd1,gpt7, 就select disk 1然后select partition 7 assign把 EFI 分区挂载- 进资源管理器看 EFI 的盘符, 假设是
E: - 进控制台,
bcdboot C:\Windows /s E: /f UEFI重建引导 - 进挂载的 EFI 分区, 里面应该有
/EFI/Microsoft/Boot, 然后下面都是 Windows 的引导文件 - 目前为止, Windows 的引导就重建好了
3. 重建 grub 引导 Windows
-
在 ArchLinux 中
-
mount /dev/nvme0n1p7 /boot挂载 EFI 分区, 如果还没挂载 -
cp /etc/grub.d/10_linux /etc/grub.d/10_windows复制一份 -
修改
/etc/grub.d/10_windows为#!/bin/shexec tail -n +3 $0# This file provides an easy way to add custom menu entries. Simply type the# menu entries you want to add after this comment. Be careful not to change# the 'exec tail' line above.menuentry "Windows 11" {insmod part_gptinsmod fat# set root=<EFI DISK PARTITION ID> # manually set root# or searchsearch --no-floppy --fs-uuid --set=root <EFI UUID>insmod chainchainloader /EFI/Microsoft/Boot/bootmgfw.efiboot}其中
<EFI DISK PARTITION ID>是 EFI 分区的硬盘表达;<EFI UUID>是 EFI 分区的 UUID
/EFI/Microsoft/Boot/bootmgfw.efi是第2节中 Windows PE 安装的引导文件
填入后就像:#!/bin/shexec tail -n +3 $0# This file provides an easy way to add custom menu entries. Simply type the# menu entries you want to add after this comment. Be careful not to change# the 'exec tail' line above.menuentry "Windows 11" {insmod part_gptinsmod fat# set root='hd1,gpt7' # manually set root# or searchsearch --no-floppy --fs-uuid --set=root 1111-A1B2insmod chainchainloader /EFI/Microsoft/Boot/bootmgfw.efiboot} -
grub-mkconfig -o /boot/grub/grub.cfg生成grub.cfg -
到目前为止, grub 的引导就重建好了
4. Security Boot
-
进 BIOS 界面关闭安全启动, 清除平台安全密钥
-
安装
sbctl, 然后检查sbctl status应该是 Setup Mode Enabled -
sudo sbctl create-keys和sudo sbctl enroll-keys -m -
sudo sbctl verify能看到有很多 Boot 文件没有被签名, 可以用import reimport osimport subprocessif __name__ == "__main__":inp = subprocess.run(["sudo", "sbctl", "verify"], capture_output=True, text=True, check=True).stdoutpattern = r"✗ (.+?) is not signed"unsigned_files = re.findall(pattern, inp)for file in unsigned_files:print(file)print(f"Total unsigned files: {len(unsigned_files)}")input("Press Enter to sign...")for file in unsigned_files:os.system(f"sudo sbctl sign -s {file}") -
然后再运行
sudo sbctl verify应该是全签名的, 忽略 header 报错 -
重启然后开启安全启动即可