Windows 10 升级导致 grub rescue。

我在我的台式机上双启动了Windows 7和Linux Ubuntu,今天是他们免费提供Windows 10升级的日子。多么令人兴奋!我得到了更新,并且正在安装中,然后我离开去睡了30分钟的午觉。然而,当我回来时,它让我进入了grub救援提示符。
error: no such partition.
Entering rescue mode...
grub rescue>

当我输入 ls 时,我得到以下结果:

grub rescue> ls
(hd0) (hd0,msdos5) (hd0,msdos3) (hd0,msdos2) (hd0,msdos1)

在快速查看遇到 grub rescue 提示的人群后,我输入了 set 并得到了以下结果。
grub rescue> set
cmdpath=(hd0)
prefix=(hd0,msdos6)/boot/grub
root=hd0,msdos6

我在发现像normal这样的某些命令无法正常工作后,还是有点迷茫。然后我找到了一个视频教程,在其中使用Linux镜像光盘引导并在终端上运行一些命令。幸运的是,我带着我的光盘,并从那里引导。然而,当我在终端中输入sudo fdisk -l时,得到的结果是这样的:
ubuntu@ubuntu:~$ sudo fdisk -l

Disk /dev/sda: 1000.2 GB, 1000204886016 bytes
255 heads, 63 sectors/track, 121601 cylinders, total 1953525168 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0xc03ede74

   Device Boot      Start         End      Blocks   Id  System
/dev/sda1   *        2048      206847      102400    7  HPFS/NTFS/exFAT
/dev/sda2          206848  1547022335   773407744    7  HPFS/NTFS/exFAT
/dev/sda3      1547022336  1547943935      460800   27  Hidden NTFS WinRE
/dev/sda4      1547945982  1953521663   202787841    f  W95 Ext'd (LBA)
/dev/sda5      1915731968  1953521663    18894848    7  HPFS/NTFS/exFAT

这里说我的设备中没有Linux系统!而且我对视频教程的跟进也不够...
我稍微思考了一下,确定sda2包含了我的Windows系统(因为我记得我的C盘大约有700多GB的空间)。再思考一下,我记得在安装Ubuntu时,我将大约200多GB的硬盘空间分配给了与Ubuntu相关的东西。我不太记得具体是哪个,但我想它基本上是Ubuntu的“硬盘空间”,里面没有任何引导文件。我还为Linux分配了另外两个很小的东西,它们的大小都很小(还没有超过1 GB)。
所以,有谁能帮我重新启动我的升级计划吗?如果最终必须完全删除包含Linux的分区,我也不介意。

1如果Linux分区是逻辑分区,Windows不会重写分区表。使用testdisk工具。有些人使用testdisk来恢复分区并重新安装grub到MBR,一切都恢复正常了。但是你必须正确地将所有分区标记为主分区和逻辑分区才能使其正常工作。http://www.cgsecurity.org/wiki/TestDisk_Step_By_Step - oldfred
在上面的布局中,看起来在新的/dev/sda5(hd0,msdos5)分区之后,磁盘末尾只剩下3505个扇区,大约相当于1.7 MB,所以Linux分区几乎不可能隐藏在那里。我最好的猜测是Linux分区条目以某种方式被移到了那个位置(第5个而不是第6个),并且其类型发生了莫名其妙的变化。首先尝试的是在GRUB救援提示符下输入ls (hd0,msdos5)/ - Josip Rodin
1又一个不使用Windows的理由,这是一个无知的操作系统。 - Aydin K.
5个回答

我的电脑是预装了Windows 8的,所以我缩小了Windows分区来为Ubuntu腾出空间。这样就一直运行了一年。 在升级到Windows 10后的第二次重启时,电脑无法启动了。GRUB只显示了一个"grub rescue"命令提示符。后来我发现问题是因为Windows不知何故改变了分区方案。引导分区(包含正常的GRUB数据)不再位于GRUB期望的位置上。我不知道这是怎么发生的,也不知道为什么会发生。
在救援模式下,你可以使用"ls"命令查看分区情况。我的分区如下:
- (hd0,gpt1) - (hd0,gpt2) - 等等
尝试找出哪个分区是你的引导分区。没有"Tab"自动补全,你必须完整地输入。我尝试了以下命令,直到找到正确的分区:
ls (hd0,gpt1)/
ls (hd0,gpt1)/boot
ls (hd0,gpt2)/

等等。

然后在同一个提示符中键入set。它将显示GRUB寻找其文件的位置。在我的情况下,(hd0,gpt6)已经移动到(hd0,gpt7)。set命令显示:

prefix=(hd0,gpt6)/boot/grub
root=hd0,gpt6

要恢复正常的GRUB,请首先将prefix设置更改为指向正确的分区。在我的情况下,命令是:
set prefix=(hd0,gpt7)/boot/grub

然后你可以从救援模式切换到正常模式。
insmod normal
normal

也可以使用以下方式来修复root设置:
set root=(hd0,gpt7)

但这并不是必需的,因为对于Windows链式加载项来说并不重要。一旦进入正常的GRUB菜单,您可以启动Windows并完成Windows升级。问题在于您必须在每次重新启动时告诉grub rescue正确的分区。这就是我做的。我把GRUB的问题留到以后解决,因为我不确定Windows是否会对分区或引导进行更多的更改。
当Windows完成后,我开始解决GRUB的问题。按下e键编辑Ubuntu的启动选项。我将所有的(hd0,gpt6)都改成了(hd0,gpt7),然后Ubuntu成功启动了。
然而,我使用的是加密分区和cryptswap。在启动Ubuntu时,它要求我输入密码。幸运的是,在安装Ubuntu时我保存了密码,并在启动时输入了它。Ubuntu顺利启动,没有任何问题。
然后,我纠正了/boot/grub/grub.cfg文件,将其中的(hd0,gpt6)替换为(hd0,gpt7),并执行了以下操作:
sudo grub-install

那时唯一剩下的问题就是加密。由于根Ubuntu分区号增加了一个(7而不是6),交换分区也遭受了类似的变化。我必须修改/etc/crypttab文件,将其指向/dev/sda8而不是/dev/sda7
我只为Ubuntu使用了两个分区(根和交换)。如果与Windows共存的其他操作系统使用了更多的分区,可能需要进行更多的更改。特别是如果分区按照它们的编号而不是UUID挂载。查看一下你的/etc/fstab。如果分区通过UUID进行标识,应该没有问题。但是如果有/dev/...行,如果这些分区已被重新编号,那么数字应该进行修正。

2这个答案对我来说很棒。我没有Ubuntu的光盘,而且我正在将我的Windows从8.1升级到10时遇到了同样的问题。所以对于我来说,这个答案获得了额外的赞扬,因为我能够直接输入它并继续进行更新直至完成。感谢你帮我解决了这个麻烦。 - dibs
3当Win 10决定升级并搞乱了引导记录时,这个解决方案对我来说完美地起作用了(我的从7升级到10一切顺利)。 - pedorro
11尝试了ls (hd0,msdos1)/ ls (hd0,msdos1)/boot ls (hd0,msdos2)/ 等等命令中的所有条目,并且每次都出现错误:未知文件系统 - Jacques MALAPRADE
2谢谢,那真的帮了我很多。有一件事对我来说不太清楚(因为我对Ubuntu和Grub都很陌生),就是编辑grub配置文件需要在进入Ubuntu后进行(而不是在迷你Emacs中,因为它显然不支持保存文件)。所以我先启动了系统,然后编辑了配置文件sudo nano /boot/grub/grub.cfg,接着运行了sudo grub-install /dev/sda(不知道为什么,没有参数的调用对我来说失败了)。只有这样,永久性的更改才生效。 - Nikita R.
1尝试对所有条目使用ls(hdo,msdos1)等命令。出现未知文件系统错误。 - Lemon Bacon
1@Ash G 你试过hdo或hd0了吗? - nobody
1我认为这种情况发生在我身上是因为Windows 10升级添加了另一个小的(1G)分区,并带有“diag”标志,意味着它是一个诊断或恢复分区。 - dfrankow
现在连Windows更新也这样了。我用Windows已经有一段时间了。 - a.j. tawleed
就像其他评论中所说的,我遇到了未知的文件系统错误,因为我输入的是'hdO'而不是'hd0'。 - laurent
这对我来说有效,除了最后编辑grub配置文件。你提到你用(hd0,gpt6)替换了(hd0,gpt7),但是我的grub配置文件中没有这样的行。我正在使用Arch,看起来配置文件是从一个.d文件夹生成的。那行具体是什么样子?我猜在我的情况下它是缺失的。 - exhuma
@exhuma,很抱歉我不知道Arch中grub及其文件的组织方式。你需要自己弄清楚这个问题。我认为你可以在这里找到答案:https://wiki.archlinux.org/index.php/GRUB#Configuration - nobody
@nobody 这并不完全是关于细节结构,而是关于你需要修改的实际“行”。那行是什么样子的?你需要修改的设置叫什么名字? - exhuma
@exhuma 我很久以前就完成了这个任务,现在我的电脑上安装的是更新的Ubuntu 19.10。不过,我找到了一些备份文件,其中记录了我如何更改grub.cfg中的“set root=…”和“search…”行。现在似乎grub.cfg是由一些高级脚本生成的,我不知道它们是如何确定分区号并将其写入grub.cfg的。 - nobody
啊,真遗憾。不过还是谢谢你费心去找出来。我会继续寻找的。 - exhuma
我刚刚在2020年4月经历了这个常规的Windows 10更新过程。我的grub.cfg是从/etc中的各种文件自动生成的(用于一个古老的Debian Jessy安装),但我忽略了所有这些,只是在自动生成的grub.cfg文件中进行了搜索替换,将每个字符串"gpt5"都替换为"gpt6"。总共有20个字符串需要替换。这样做起作用了。这可能不正确,但可以帮助某人重新进入Windows... - Dan

安装Windows(或升级)与Linux并存可能会有问题。
试试这个: https://help.ubuntu.com/community/Boot-Repair 我在安装Windows 10技术预览后使用它来解决问题,它起作用了。基本上,它重新安装grub以使其与所有当前安装的操作系统兼容。确保告诉它将grub安装到你的Linux分区(sd#)。
祝好运!

嗨!谢谢你抽出时间来帮忙!实际上,我不太确定是哪个分区!但我会试着调整一下看看是否有效。 - LChaos2
没问题!非常乐意帮助。 - user345524
嗨!所以我启动了boot-repair-disk并使用了推荐的修复选项。我这样做并重新启动了电脑,但它却进入了Windows引导管理器,并告诉我最近可能安装了一个签名不正确或损坏的文件。该文件是\Windows\system32\winload.exe,状态为0xc0000428。按下回车键会让我进入引导管理器选择要启动的操作系统,只显示Windows 7。在Windows 7上按下回车键会让我回到相同的错误屏幕,导致循环。 - LChaos2
经过一些研究,听起来错误代码(0xc000428)与winload.exe没有通过某个数字签名的验证有关。它有提到这方面的任何信息吗? - user345524
1@LChaos2,情况有任何更新吗? - hg8
有没有任何更新? - Veridian

在更改分区之前,请先备份并保存到另一个设备上。如果不是sda,请更改为正确的驱动器。然后,如果您使用testdisk恢复了错误的设置,您可以重新开始。在使用testdisk进行恢复时,您只需要当前的所有内容以及丢失的逻辑内容。
sudo sfdisk -d /dev/sda > parts.txt

你丢失的分区可能在这里,或者在扩展分区的起始位置(1547...)和第一个显示的分区之间(1915...)。
/dev/sda4      1547945982  1953521663   202787841    f  W95 Ext'd (LBA)
/dev/sda5      1915731968  1953521663    18894848    7  HPFS/NTFS/exFAT

你可以使用testdisk,但它使用CHS。你必须选择所有现有的分区和丢失的分区作为逻辑分区。根据你改变分区的次数,它可能会显示很多版本。所以选择与丢失的分区大小相匹配的大小,而不重叠其他当前分区。 一些成功恢复的人只需重新启动即可,而其他人则需要重新安装grub。还有一些无法正确恢复分区。

http://www.cgsecurity.org/wiki/TestDisk_Step_By_Step

另一个恢复工具是parted rescue。它使用扇区,但你提供的范围必须刚好在丢失的分区之外,并且不与当前分区重叠。最好如果你知道确切的起始和结束位置。请参阅parted的手册。

http://www.gnu.org/software/parted/manual/html_node/rescue.html

使用parted rescue的用户:

http://ubuntuforums.org/showthread.php?t=1775331&p=10905969#post10905969


3我遇到了完全相同的问题, parted 显示“空闲空间”,而以前是 Linux 的位置。 运行救援程序并指定“空闲空间”的起点/终点,就可以恢复 ext4 了! - speedogoo
3只是想插一句话说,gparted显示了ext4曾经所占用的空间。运行parted,并设置为扇区,打印分区,利用“空闲空间”的起始和结束位置进行恢复(别忘了在值后面添加一个s来表示扇区),ext4就会回来,与@speedogoo完全相同。完全不需要调整grub。 - Amedee Van Gasse
2由于越来越多的人遇到分区丢失的问题,Windows 10 到底在搞什么鬼分区表?在我的情况下,ext4 是在一个逻辑分区中。 - Amedee Van Gasse
感谢这个线索。我能够使用parted rescue恢复我妻子丢失的Linux分区。经过grub-install之后,我们又回到了正常状态。 - bheeshmar

这是Windows分区器中的一个恶心的错误,而不是特定于Linux。讽刺的是,在我的情况下,它删除了一个NTFS分区。
Windows 10安装程序会在主Windows分区(sda2)的末尾创建一个新分区(/dev/sda3),如果Windows引导分区(sda1)太小无法容纳Windows 10恢复环境。
当它重写分区表时,对于扩展分区表(sda4)中的每个逻辑分区,如果它位于磁盘上前一个分区号之前,它就会放弃。
在你的情况下,你的Linux分区位于你的新分区sda5之前,但分区号比重新分区之前的sda5要高。
如果你浏览庞大的Windows 10升级日志,你会看到类似“6 before 5, Nothing to do”的消息,以及旧和新的分区表。

Windows不会覆盖删除的分区内容,因此如果您能找到它们的位置,就有可能恢复它们。在我的情况下,我备份了分区表,但是使用testdisk(如oldfred的回答所述)可以很好地找到它们。在您的情况下,使用Parted rescue可能比较困难,因为删除了多个分区。

要在Ubuntu Live CD中使用testdisk,在终端中输入sudo apt-get install testdisk来安装它,然后输入sudo testdisk来运行。

修复分区表后,包含GRUB的Linux分区号码可能与之前不同,因此您可能仍然会进入GRUB Rescue提示符。如果出现这种情况,Boot Repair现在可以修复GRUB。

再次使用您的Ubuntu Live CD,输入:

sudo add-apt-repository ppa:yannubuntu/boot-repair
sudo apt-get update
sudo apt-get install -y boot-repair && boot-repair

安装并运行它。
现在Windows可以完成升级。

非常感谢清晰地解释问题所在,这对我帮助很大。我曾经处于与问题描述中相同的情况。然而,Testdisk 无法找到已删除的 Linux 分区。对我来说,Parted Rescue 起了作用,之后我能够继续进行 Windows 10 升级。 - toby
Windows在删除分区时不会覆盖其内容。这怎么可能呢?它为我创建的新分区(在删除我的Linux分区后)占据了整个磁盘。这难道不意味着写入可以发生在任何地方吗? - Greg Bell
我无法表达我有多么爱你 - aviggiano
这个帖子已经很多年了,但是在2020年6月的Win 10更新后,我也遇到了这个问题,所以显然微软多年来没有修复这个漏洞。有没有办法可以防止下次再次发生这种情况?你的第二句话似乎暗示着拥有足够大的sda1分区可能会有所帮助。但是什么样的大小才算足够大呢? - spirit

使用boot-repair之前,您需要在BIOS中进行以下设置:
  • 启用UEFI(在我的BIOS中是:)

    禁用传统支持

  • 禁用安全启动

可能您已经启用了安全启动,所以会出现“文件签名错误”的问题。

  • 相关问题