grub rescue>, Oops!
<p>教你如何修复丢失的 Linux GRUB 启动引导。</p>
<h2 id="起因">起因</h2>
<p>为了再将神船 Z7 用起来,笔者决定扩展其仅有 200GB 的游戏分区空间。然而由于可用空间的位置并不连续,Windows 自带磁盘工具无法处理这种情况,且笔者并不希望将分区转为动态分区,因此使用了一个第三方软件 <a href="https://www.easeus.com/partition-manager/epm-free.html">EaseUS Partition Master Free</a> 来完成磁盘数据的迁移和分区重分配工作。就在设置好分区,重启了之后,屏幕上赫然显示着一个命令行界面:</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt" id="hl-0-1"><a style="outline: none; text-decoration:none; color:inherit" href="#hl-0-1">1</a>
</span><span class="lnt" id="hl-0-2"><a style="outline: none; text-decoration:none; color:inherit" href="#hl-0-2">2</a>
</span><span class="lnt" id="hl-0-3"><a style="outline: none; text-decoration:none; color:inherit" href="#hl-0-3">3</a>
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-shell" data-lang="shell"><span class="line"><span class="cl">error: unknown filesystem.
</span></span><span class="line"><span class="cl">Entering rescue mode...
</span></span><span class="line"><span class="cl">grub rescue>
</span></span></code></pre></td></tr></table>
</div>
</div><p>Oops!难道重新分个区就把系统搞挂了吗?!<code>grub rescue></code> 这个命令行界面在我心中一直是噩梦般的存在,之前遇到都只能选择计算机三大法宝之一:重装来解决问题。</p>
<p>既然双系统里的 Linux 进不去了,那我试试直接进 Windows?于是重启了一下机器,通过 BIOS 直接进入了系统盘位于 SSD 中的 Windows。好家伙,这能正常启动,那问题就不大了。</p>
<p>Windows 磁盘分区的重分配工作得到了验证,看上去非常完美。笔者用于存储游戏的专用分区已经扩容至 ~450GB ,那接下来还是修复下 Linux 启动引导的问题吧。</p>
<p>经过一番简单的搜索,笔者摸清了其中大概的原因:在进行 Windows 磁盘操作时,对整个 HDD 做了分区、合并等处理,导致 GPT 元数据发生了改变,Linux 的引导程序 GRUB 自然就无法找到之前的 <code>/boot</code> 启动分区了,这也是报出 <code>error: unknown filesystem</code> 的原因。</p>
<h2 id="在-grub-rescue-中修复启动项">在 grub rescue 中修复启动项</h2>
<p>由于是硬盘元数据发生了改变导致 GRUB 失效,那我们的思路就是更新 GRUB 中的配置。</p>
<p>首先要找到目前 Linux 的 <code>/boot</code> 启动分区的位置,在 <code>grub rescue</code> 中,可以用 <code>ls</code> 来寻找:</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt" id="hl-1-1"><a style="outline: none; text-decoration:none; color:inherit" href="#hl-1-1">1</a>
</span><span class="lnt" id="hl-1-2"><a style="outline: none; text-decoration:none; color:inherit" href="#hl-1-2">2</a>
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-shell" data-lang="shell"><span class="line"><span class="cl">grub rescue> ls
</span></span><span class="line"><span class="cl"><span class="o">(</span>hd0<span class="o">)</span> <span class="o">(</span>hd0,gpt7<span class="o">)</span> <span class="o">(</span>hd0,gpt6<span class="o">)</span> <span class="o">(</span>hd0,gpt5<span class="o">)</span> <span class="o">(</span>hd0,gpt4<span class="o">)</span> <span class="o">(</span>hd0,gpt3<span class="o">)</span> <span class="o">(</span>hd0,gpt2<span class="o">)</span> <span class="o">(</span>hd0,gpt1<span class="o">)</span> <span class="o">(</span>hd1<span class="o">)</span> <span class="o">(</span>hd1,gpt3<span class="o">)</span> <span class="o">(</span>hd1,gpt2<span class="o">)</span> <span class="o">(</span>hd1,gpt1<span class="o">)</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>直接输入 <code>ls</code> ,即可得到所有的分区位置。但是启动分区到底是哪个呢?我们可以继续用 <code>ls</code> 来查找,先试试 <code>(hd0,gpt1)</code> 这个分区吧。</p>
<blockquote>
<p>此处要注意的是,我们要查找的是 <code>/boot/grub</code> 这个文件夹目录存在的分区。由于笔者的 <code>/boot</code> 启动分区是单独挂载的,所以查找的路径是 <code><partition>/grub</code> 。若安装的 Linux 并没有单独挂载 <code>/boot</code> 启动分区,则查找路径应为 <code><partition>/boot/grub</code>。</p>
</blockquote>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt" id="hl-2-1"><a style="outline: none; text-decoration:none; color:inherit" href="#hl-2-1">1</a>
</span><span class="lnt" id="hl-2-2"><a style="outline: none; text-decoration:none; color:inherit" href="#hl-2-2">2</a>
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-shell" data-lang="shell"><span class="line"><span class="cl">grub rescue> ls <span class="o">(</span>hd0,gpt1<span class="o">)</span>/grub
</span></span><span class="line"><span class="cl">error: unknown filesystem.
</span></span></code></pre></td></tr></table>
</div>
</div><p>输出为 <code>error: unknown filesystem.</code> ,说明这个分区并不是我们想要的启动分区,那再试试下一个分区。</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt" id="hl-3-1"><a style="outline: none; text-decoration:none; color:inherit" href="#hl-3-1">1</a>
</span><span class="lnt" id="hl-3-2"><a style="outline: none; text-decoration:none; color:inherit" href="#hl-3-2">2</a>
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-shell" data-lang="shell"><span class="line"><span class="cl">grub rescue> ls <span class="o">(</span>hd0,gpt2<span class="o">)</span>/grub
</span></span><span class="line"><span class="cl">./ ../ x86_64-efi/ grubenv themes/ fonts/ grub.cfg
</span></span></code></pre></td></tr></table>
</div>
</div><p>Bingo!这就是我们要找的东西丫!好,记下这个分区 <code>(hd0,gpt2)</code>,它就是我们宝贵的启动分区。</p>
<p>接下来就是给 GRUB 修改启动配置,只要改两个参数即可:</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt" id="hl-4-1"><a style="outline: none; text-decoration:none; color:inherit" href="#hl-4-1">1</a>
</span><span class="lnt" id="hl-4-2"><a style="outline: none; text-decoration:none; color:inherit" href="#hl-4-2">2</a>
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-shell" data-lang="shell"><span class="line"><span class="cl">grub rescue> <span class="nb">set</span> <span class="nv">root</span><span class="o">=(</span>hd0,gpt2<span class="o">)</span>
</span></span><span class="line"><span class="cl">grub rescue> <span class="nb">set</span> <span class="nv">prefix</span><span class="o">=(</span>hd0,gpt2<span class="o">)</span>/grub
</span></span></code></pre></td></tr></table>
</div>
</div><ul>
<li>将 <code>root</code> 设置为启动分区。</li>
<li>将 <code>prefix</code> 设置为 <code>grub</code> 安装文件夹。若 <code>/boot</code> 未挂载单独分区,也可能为 <code><partition>/boot/grub</code>。</li>
</ul>
<p>配置也修改好了之后,重新使 GRUB 进入普通模式就可以找回我们的启动项了!</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt" id="hl-5-1"><a style="outline: none; text-decoration:none; color:inherit" href="#hl-5-1">1</a>
</span><span class="lnt" id="hl-5-2"><a style="outline: none; text-decoration:none; color:inherit" href="#hl-5-2">2</a>
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-shell" data-lang="shell"><span class="line"><span class="cl">grub rescue> insmod normal
</span></span><span class="line"><span class="cl">grub rescue> normal
</span></span></code></pre></td></tr></table>
</div>
</div><p>执行完后,应该能看到我们熟悉的 GRUB 引导界面了。</p>
<h2 id="持久化">持久化</h2>
<p>事实上,这样的修复只是暂时的,我们还需要对 GRUB 配置进行持久化的更新,否则每次开机都要这样操作一遍。</p>
<p>进入 Linux,打开终端,输入如下命令,GRUB 就会自动更新配置。</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt" id="hl-6-1"><a style="outline: none; text-decoration:none; color:inherit" href="#hl-6-1">1</a>
</span><span class="lnt" id="hl-6-2"><a style="outline: none; text-decoration:none; color:inherit" href="#hl-6-2">2</a>
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-shell" data-lang="shell"><span class="line"><span class="cl">$ sudo update-grub
</span></span><span class="line"><span class="cl">$ sudo grub-install /dev/sda
</span></span></code></pre></td></tr></table>
</div>
</div><p><code>/dev/sda</code> 为 Linux 的安装磁盘。</p>
<p>可以再重启一次计算机,验证 Linux 启动引导是否修复成功。</p>
<h2 id="references">References</h2>
<ul>
<li>Repair Linux boot failures in GRUB 2 rescue mode</br>
<a href="https://www.howtoforge.com/tutorial/repair-linux-boot-with-grub-rescue/">https://www.howtoforge.com/tutorial/repair-linux-boot-with-grub-rescue/</a></li>
<li>grub rescue 救援模式的处理</br>
<a href="http://xstarcd.github.io/wiki/Linux/grub_rescue.html">http://xstarcd.github.io/wiki/Linux/grub_rescue.html</a></li>
<li>Linux 系统引导失败,出现 grub rescue 恢复界面 - 少数派</br>
<a href="https://sspai.com/post/55875">https://sspai.com/post/55875</a></li>
</ul>