双系统修复启动引导

3,833 阅读7分钟

问题与现象

我的win10/fedora双系统在fedroa从34升级到36之后,再次开机就没法再进入到win10了。grub引导的选项都在,但是无论选哪个进入的都是fedora。

于是我找来一个win10的U盘启动盘,开机进入到U盘的windows系统中,利用界面工具修复了一下启动引导。(这里情况各不相同,我的这个U盘是一个PE盘,本身有一些修复的工具,一般的U盘安装盘应该也有修复启动引导这样的选项)

重启机器能够进行win10系统了,但是又来了一个新问题:启动引导的选项(按f10进入的系统启动页面,不是grub的黑屏选项页)都在,但是无论选哪个进入的都是windows,和刚才的情况正好相反!

然后开始了几天艰苦卓绝的修复之路……

准备与前提

当前系统是UEFI模式的,这个在BIOS中已经设置好了,现在系统大多是UEFI模式。

fedora的启动partition分区编号是8(GPT8),这里存储的是fedora的各种boot文件。

fedora的系统partition分区编号是9(GPT9),这里有个很不一般的情况:在这个分区中包含了三个逻辑分区lvm-fedora_fedora-lindeer-root, lvm-fedora_fedora-lindeer-home, lvm-fedora_fedora-lindeer-swap。最初这个情况让人不明所以,按照设想,应当有一个专门的partition分区是系统的root, 还有一个分区是home,可能是系统升级造成的,当前这个fedora是从32升级到34又升级到36的。

Windows下修复(失败)

想着在win10下也能用上linux,然后折腾了一下wsl2,发现系统的版本太低。升级win10也费了半天劲,最好就是直接用官方的升级程序Windows10Upgrade9252.exe。然而我在发现这个方法之前,用的是系统设置当中的windows更新,这种方法安装更新没完没了,而且还经常下载失败,这种方法只是打补丁,升级不了版本号。

于是从win10的1803版本升级到了当前最新的22H2版本(19045.2006)。

当时想当然地以为,既然fedora系统本身是好的, 那我在windows的启动引导里添加一个正确的引导入口,不就可以了?于是就是上一篇文章中的一番操作。

另外,bcdedit的方法是首先通过询问chatGPT才找到的方法,chatGPT实在太强大了!

结果是不成功的。

Grub页面手动引导(失败)

于是还是回到grub的老路。先能进入fedora原有系统再说,要进系统先进grub页;要进入grub页,需要借助Live CD的U盘启动,但我原先的Fedora32 U盘启动之后,没有进入正常的grub黑屏启动选项页,而是直接进入到了grub命令页,当时并不知道是U盘的问题。

grub> ls

在这里才查看到了一些分区的细节,ls命令可以方便的罗列已有的磁盘设备。因为是插着U盘,系统把U盘命名成hd0,自带的磁盘是hd1。于是有(hd0,gpt0),(hd1,gpt2),(hd0,gpt8),(hd0,gpt9)一众设备。当时只有(hd1,gpt2)(hd0,gpt8)可以通过ls命令查看目录下文件内容,如grub> ls (hd0,gpt8)/

通过命令才发现路径/boo/eif/下是空的!这就解释了,我不管在windows下bcdedit如何设置path都是无效的,因为根本就没有任何efi文件。

通过这篇文章,了解了一些命令才能引导进入系统。文章中的命令好多没法使用,用的是自己试出来的:

set root=(hd1,gpt8)
linuxefi (hd1,gpt8)/vmlinuz-5.18.11-200.fc36.x86_64 root=/dev/sda8
set prefix=(hd1,gpt8)/grub2
initrdefi (hd1,gpt8)/initramfs-5.18.11-200.fc36.x86_64.img

但这个操作反复试了很多次都没有成功进入系统,显然我没搞清第二个命令里的root是目标系统的根目录,不是启动目录。诡异的是没有文中说的linuxinitrd命令,只有多了个efilinuxefiinitrdefivmlinuzinitramfs都可通过tab键自动完成,选取当前系统对应的即可。

不过通过ls至少知道fedora系统本身是没有出问题的。我这才怀疑是U盘的问题,于是新下载一个Fedora37的iso镜像,并用rufus-2.18.exe重新制作了一个U盘启动盘。

Fedora Live CD系统修复(失败)

用重新制作的U盘启动之后,果然进入到了熟悉的grub黑屏启动选项页,选择Fedora37进入到了Live CD系统当中。

这里主要参考了这篇文章,主要讲的是在Live CD系统下如何修复grub,为了避免混淆,我用/mnt/fedora作为了根目录:

sudo mount /dev/fedora_fedora-lindeer/root /mnt/fedora
sudo mount /dev/sda8 /mnt/fedora/boot

sudo mount --bind /dev /mnt/fedora/dev
sudo mount --bind /proc /mnt/fedora/proc
sudo mount --bind /sys /mnt/fedora/sys
sudo mount --bind /var/run /mnt/fedora/var/run

sudo ls /mnt/fedora/*

这里特别要注意前两个命令。首先要挂载的是root目录,我们的情况有点特殊,那就是root目录不是一个单独的partition分区,而是一个linux lvm;另外,rootboot只有一个字母之差,含义和作用也完全不同。最后一个命令只是为了查验正确挂载。

挂载完成之后就进行修复操作:

sudo chroot /mnt/fedora
sudo cp /boot/grub/grub.cfg /boot/grub/grub.cfg.bk
sudo grub2-mkconfig -o /boot/grub/grub.cfg

按照文章中提及的,可以用grub2-installgrub2-mkconfig,但后者会帮助检测已有的操作系统并添加适当配置,更适合双系统,所以选择了这个。系统重启之后实际并没有成功

于是又来一遍同样的操作,不过最后一个命令改成grub2-install,可是命令执行失败,错误提示似乎有缺少参数的情况,才发现路径/boot下只有i386-pc,改成以下:

sudo grub2-install --target=i386-pc /dev/sda

但是这个方法执行也失败了,真让人崩溃!错误提示grub2-install error: will not proceed with blocklists,真是让人匪夷所思。

Fedora原系统下修复(成功)

既然用那坨复杂的方式是为了切换到原有系统的环境,那我直接进Fedora原系统进行修复不就完了?

于是通过Live CD启动进入grub黑屏选项页,再按字母键'c'进入grub命令页,准备通过手动引导先进入原系统:

grub> ls # 查看已加载的设备
grub> echo $root $prefix # 查看已设置的环境
# 以上命令不重要,是可选的

grub> set root=(hd1,gpt8)
grub> linux (hd1,gpt8)/vmlinuz-5.18.11-200.fc36.x86_64 root=/dev/dm-0
grub> set prefix=(hd1,gpt8)/grub2
grub> insmod normal
grub> initrd (hd1,gpt8)/initramfs-5.18.11-200.fc36.x86_64.img

这一步要确保在/dev目录下有系统启动的root设备,我的设备是/dev/fedora_fedora-lindeer/root,这是一个软链接,实际指向/dev/dm-0。这些信息在准备与前提那节已经提及。

fedora原系统成功启动!但是当前系统里没有grub-update命令。然后参考这篇文章在命令行执行(以root权限):

rm /boot/grub2/grub.cfg

dnf update shim-* grub2-efi-* grub2-common
dnf reinstall shim-* grub2-efi-* grub2-common

因为系统目录/boot/efi之下是空的,所以也无所谓删除,这一步没有按照文章中所说。另外直接运行dnf reinstall shim-* grub2-efi-* grub2-common报了一个错误,错误信息已经找不到了,不过用update能够找到对应的升级包,于是先运行update。

如上运行再次启动后,终于成功了,一切恢复如初!可以说,这个方法是之前好几个方法的一个综合!/boot/efi下也有路径了/boot/efi/EFI/fedora/,各种efi文件也都存在。

也就是说,这样的情况处理的基本步骤应当是:

  1. 先要能够正确进入到linux原系统当中(无论是通过启动U盘的方式,还是手动编辑grub的方式)
  2. 再更新grub并重装grub

我因为各种情况叠加,使得情况变得有点复杂,再加上一知半解,绕了一个大圈子,耗费了太长时间,但这个整体过程应当是不会变的。结束吧,再也不想整这坨东西了!