教你如何修复丢失的 Linux GRUB 启动引导。

起因

为了再将神船 Z7 用起来,笔者决定扩展其仅有 200GB 的游戏分区空间。然而由于可用空间的位置并不连续,Windows 自带磁盘工具无法处理这种情况,且笔者并不希望将分区转为动态分区,因此使用了一个第三方软件 EaseUS Partition Master Free 来完成磁盘数据的迁移和分区重分配工作。就在设置好分区,重启了之后,屏幕上赫然显示着一个命令行界面:

error: unknown filesystem.
Entering rescue mode...
grub rescue> 

Oops!难道重新分个区就把系统搞挂了吗?!grub rescue> 这个命令行界面在我心中一直是噩梦般的存在,之前遇到都只能选择计算机三大法宝之一:重装来解决问题。

既然双系统里的 Linux 进不去了,那我试试直接进 Windows?于是重启了一下机器,通过 BIOS 直接进入了系统盘位于 SSD 中的 Windows。好家伙,这能正常启动,那问题就不大了。

Windows 磁盘分区的重分配工作得到了验证,看上去非常完美。笔者用于存储游戏的专用分区已经扩容至 ~450GB ,那接下来还是修复下 Linux 启动引导的问题吧。

经过一番简单的搜索,笔者摸清了其中大概的原因:在进行 Windows 磁盘操作时,对整个 HDD 做了分区、合并等处理,导致 GPT 元数据发生了改变,Linux 的引导程序 GRUB 自然就无法找到之前的 /boot 启动分区了,这也是报出 error: unknown filesystem 的原因。

在 grub rescue 中修复启动项

由于是硬盘元数据发生了改变导致 GRUB 失效,那我们的思路就是更新 GRUB 中的配置。

首先要找到目前 Linux 的 /boot 启动分区的位置,在 grub rescue 中,可以用 ls 来寻找:

grub rescue> ls
(hd0) (hd0,gpt7) (hd0,gpt6) (hd0,gpt5) (hd0,gpt4) (hd0,gpt3) (hd0,gpt2) (hd0,gpt1) (hd1) (hd1,gpt3) (hd1,gpt2) (hd1,gpt1)

直接输入 ls ,即可得到所有的分区位置。但是启动分区到底是哪个呢?我们可以继续用 ls 来查找,先试试 (hd0,gpt1) 这个分区吧。

此处要注意的是,我们要查找的是 /boot/grub 这个文件夹目录存在的分区。由于笔者的 /boot 启动分区是单独挂载的,所以查找的路径是 <partition>/grub 。若安装的 Linux 并没有单独挂载 /boot 启动分区,则查找路径应为 <partition>/boot/grub

grub rescue> ls (hd0,gpt1)/grub
error: unknown filesystem.

输出为 error: unknown filesystem. ,说明这个分区并不是我们想要的启动分区,那再试试下一个分区。

grub rescue> ls (hd0,gpt2)/grub
./ ../ x86_64-efi/ grubenv themes/ fonts/ grub.cfg

Bingo!这就是我们要找的东西丫!好,记下这个分区 (hd0,gpt2),它就是我们宝贵的启动分区。

接下来就是给 GRUB 修改启动配置,只要改两个参数即可:

grub rescue> set root=(hd0,gpt2)
grub rescue> set prefix=(hd0,gpt2)/grub
  • root 设置为启动分区。
  • prefix 设置为 grub 安装文件夹。若 /boot 未挂载单独分区,也可能为 <partition>/boot/grub

配置也修改好了之后,重新使 GRUB 进入普通模式就可以找回我们的启动项了!

grub rescue> insmod normal
grub rescue> normal

执行完后,应该能看到我们熟悉的 GRUB 引导界面了。

持久化

事实上,这样的修复只是暂时的,我们还需要对 GRUB 配置进行持久化的更新,否则每次开机都要这样操作一遍。

进入 Linux,打开终端,输入如下命令,GRUB 就会自动更新配置。

$ sudo update-grub
$ sudo grub-install /dev/sda

/dev/sda 为 Linux 的安装磁盘。

可以再重启一次计算机,验证 Linux 启动引导是否修复成功。

References


知识共享许可协议
本作品采用知识共享署名-相同方式共享 4.0 国际许可协议进行许可。