记录一次失败的系统抢救/折腾经历_zifehng的博客-程序员宅基地

技术标签: MediaCreationTool  NTFS磁盘修复  bootres.dll  GRUB  系统安装与修复  EFI引导修复  

一、事故起因

大概描述下事故起因:
WIN10/Ubuntu16.04双系统,分别安装在两块256Gb大小的NVME SSD上,以UEFI模式Grub2引导。某天我心血来潮,想要验证核显与独显是否能一起工作,多次在系统启动过程中强制下电(作死行为。。。),终于在一次强制下电后,WIN无法启动了,而且连安全模式都无法进入,一直卡在蓝屏界面,蓝屏界面提示如下:

你的设备/电脑需要修复

在这里插入图片描述作为一名技术型宅男,当然不甘心重装系统,况且还有很多数据不能丢失,于是开始了对win10的抢救之路。

二、WIN10抢救记录

既然能进入BIOS,说明硬件没出问题,然后“又提示文件丢失”,因此我猜测很可能是SSD开启了写入缓存策略,在强制下电的过程中数据来不及刷入硬盘,导致一些系统启动文件受损。

当然一般好一些的SSD都会内置电容蓄电,在断电时为I/O争取最后的时间,只不过这是最后一道防线,不能保证100%不会出问题,虽然我用的是将近1000块的浦科特M8PEG,在多次强制下电后还是中招了。。。

在此也提醒看到这篇文章的朋友:数据无价,请保持良好的电脑使用习惯,千万不要像我一样作死,最重要的一点是——要关闭写入缓存!

废话不多说了,既然问题已经发生了,那就开始修复吧!

修复NTFS磁盘

进入PE系统,发现系统盘居然无法访问了,然后用DiskGenius工具查看,磁盘显示“未格式化”,如下图:
在这里插入图片描述
可能有些人看到这步就要格式化硬盘了,但我推测:强制下电最多导致部分文件受损,数据不可能全部消失,磁盘用工具修复下应该就可以访问了。

一开始我使用GRUB2下的ntfs-3g工具尝试修复,发现并没有什么卵用。NTFS是Windows家的私有格式,并不开源,还是用WIN10自带的磁盘修复工具吧,由于原系统已经彻底崩溃(磁盘都无法访问),只能借助于WIN10系统安装U盘,步骤如下:

  • 插入WIN10系统安装U盘,在BIOS中设其为启动项
  • 进入安装界面,跳过安装步骤
  • 选择疑难解答->高级工具->磁盘修复

等修复结束,再进入PE系统,发现系统盘已经可以访问了,数据也都还在,抢救成功了一小步~

重建WIN10 EFI引导

然而我还是高兴地太早了,虽然系统盘可以访问了,但还是无法启动WIN10,这次仍然卡在蓝屏界面,提示如下:

“自动修复”无法修复你的电脑
日志文件:D:\WINDOWS\System32\Logfiles\Srt\SrtTrail.txt

找到log文件并打开,错误提示如下:

启动关键文件 d:\boot\resources\custom\bootres.dll 损坏

已经很明显了,启动文件损坏。
头疼医头、脚疼医脚,找到问题了就该对症下药,重建EFI引导吧!

重建EFI引导其实就是将系统盘Windows\Boot\EFI目录下的文件复制至EFI分区中,当然,我们实际应用的时候不用这么原始地复制一个一个文件,WIN10已经替我们集成了一个命令(PE下执行),如下:

bcdboot C:\windows /s H: /f uefi /l zh-cn

具体参数要根据实际情况修改,其中:

  • C:\windows指定系统盘目录
  • /s H:指定EFI分区
  • /f uefi指定UEFI启动方式
  • /l zh-cn指定UEFI图形界面语言为简体中文

修复受损系统文件

重建EFI引导后,仍然无法启动,错误提示也和上述一致。

实际上到这一步我已经放弃了,不得已含泪重装了系统,但是后来根据提示信息在Google搜索,居然找到了Windows官方的QA界面,问题和我99%相似,并且Windows开发者提供了解决方案,因此记录下来,链接为:
Microsoft 支持 - bootres.dll损坏

简单描述下微软官方人员的回答,大意为:

该提示信息意味着系统的.dll文件出现问题,需要重新注册

这就解释了即使我重建EFI引导还是无法启动的原因——系统盘中的EFI相关源文件已经损坏,因此重建的EFI引导也是有问题的。

微软官方提供的解决方案如下:

  • 首先尝试注册系统文件,执行以下命令:
cmd /c for %i in (%windir%\system32\*.dll) do regsvr32.exe /s %i
cmd /c for %i in (%windir%\system32\*.ocx) do regsvr32.exe /s %i
  • 若问题依旧则需要扫描全盘并修复系统文件,执行以下命令:
sfc /SCANNOW

后记:
当用Google搜到这个QA界面的时候,我想如果我当时执行这些步骤,应该就大功告成了,也用不着重装系统,不得不感慨:百度误我!

使用MediaCreationTool制作WIN10启动U盘

在失败的系统抢救之后,不得已只能重装系统。

其实我已经有WIN10 17.03的启动U盘了,但一想到大量的更新就脑壳疼,干脆用最新的镜像制作安装盘,但是惊讶的发现18.09的镜像竟然无法用UltraISO写入U盘,上网一查方知18.09镜像中有单个大小超过4Gb的文件,受FAT32格式限制无法写入。

不知微软为什么要如此设计,总之是无法用UltraISO制作启动U盘了。

天无绝人之路,微软总算提供了官方工具MediaCreationTool制作启动U盘,下载链接:
Download MediaCreationTool
在这里插入图片描述
使用很简单,值得一提的是该工具提供的是一条龙服务——会帮你下载最新的镜像然后直接写入U盘,但是却没有选择本地镜像的入口(意味着我之前下载的18.09镜像做了无用功)。

不错,这很“微软”,就像自动更新一样,根本不给用户选择的余地。

三、Ubuntu抢救记录

重建Ubuntu EFI系统分区及EFI引导

在WIN10崩溃的时候,我想切到Ubuntu,发现Ubuntu居然也无法启动,提示:

Could't get size: 0x800000000000000e
MODSIGN: Couldn't get UEFI db list

其实这个问题以前也出现过,原因是WIN10某些更新会更改EFI分区的文件,导致Ubuntu的引导被破坏。

这种情况只有重建EFI引导了,但这也是治标不治本,指不定WIN10的哪次更新又会搞破坏。

有鉴于WIN10经常更新并祸及EFI系统分区,我决定刮骨疗伤,为Ubuntu单独再建立一个EFI系统分区,让两者井水不犯河水。

先介绍下之前Ubuntu与Win10分区结构吧,两块SSD分别安装了两个系统,但是共享一个EFI系统分区,Window Boot Mangager与GRUB2“共居一室”,如下图:
在这里插入图片描述
这种分区的弊端在前文已经介绍过了(WIN10更新破坏Ubuntu引导),因此我想做一些调整,如下图:
在这里插入图片描述
这个方案在另一块SSD上新建了一个EFI分区,并将GRUB2安装到其中,理论上来说再也不会受WIN10的更新的影响了。具体步骤如下:

1. 通过LiveCD(Ubuntu启动U盘)进入系统

2. 新建EFI系统分区
使用GPart工具在硬盘上划分一个100Mb大小的分区,分区Label设置为“Boot,esp”。

3. chroot切换根目录(LiveCD->待修复的Ubuntu)

  • 将待修复的Ubuntu系统的根分区挂载至/mnt/ubuntu
# mount /dev/nvme1n1p2 /mnt/ubuntu
  • 将新建的EFI分区挂载至/mount/ubuntu/boot/efi
# mount /dev/nvme1n1p1 /mount/ubuntu/boot/efi
  • 将LiveCD的虚拟文件系统devfs、procfs、sysfs挂载至待修复的Ubuntu对应目录下,否则使用chroot后无法访问一些硬件资源
# mount -o bind /dev /mnt/ubuntu/dev
# mount -o bind /proc /mnt/ubuntu/proc
# mount -o bind /sys /mnt/ubuntu/sys
  • 使用chroot切换根目录
# chroot /mnt/ubuntu

4. 安装EFI引导

# grub-install --target=x86_64-efi --efi-directory=/boot/efi

5. 修改fstab文件
使用blkid命令获取新建EFI系统分区的UUID,然后修改/etc/fstab文件,替换之前EFI分区的UUID,否则系统无法启动。

经过上述操作,Ubuntu顺利启动~

GRUB2命令行引导WIN10

GRUB2是可以引导WIN10的,相反Windows Boot Manager却不能引导Ubuntu,但是在我安装GRUB2时,不知为何没有自动添加WIN10入口,不过这不打紧,可以先试试GRUB2命令行引导WIN10。

准确地说,GRUB2无法直接引导WIN10,只能通过Windows Boot Manager间接引导,这几者的加载关系如下:
BIOS->GRUB2->Windows Boot Manager->WIN10

理顺了这个关系,就清楚接下来要干的事情了,以下为GRUB2命令行引导WIN10所需要执行的命令:

insmod part_gpt
insmod fat
$ set root=(hd0, gpt1)
$ chainloader /efi/Microsoft/Boot/bootmgfw.efi
  • insmod part_gpt &insmod fat
    GRUB2为了减少自身体积,启动时一些模块是默认不安装的,启动WIN10需要支持GPT与FAT32格式,这里我们手动安装这两个模块。
  • set root=(hd0, gpt1)
    该命令效果和shell下的chroot一样,可以更改当前运行系统的根目录,需要注意的是(hd0,gpt1)并不是WIN10的系统盘所在分区,而是WIN10的EFI分区,这点在前文已经解释了(GRUB2无法直接引导WIN10)。
  • chainloader /efi/Microsoft/Boot/bootmgfw.efi
    顾名思义,该命令是一个链式装载启动工具,通过引导Windows Boot Manager间接引导WIN10

GRUB2添加WIN10启动项

GRUB2命令行成功引导WIN10,那就意味着可以更进一步——在GRUB2中添加WIN10启动项了。有想过手动在GRUB2配置文件中添加WIN10的menuentry,却总觉得不太完美(鄙人强烈的强迫症在作祟)。
有没有让GRUB2侦测WIN10自动生成配置文件的方法呢?答案是Yes。
通过GRUB2官方文档了解到如果在第一次安装时os-probe没有侦测到WIN10,有两种方法可以补救:

  • 挂载WIN10的EFI系统分区,然后执行update-grub
  • 先执行lsblk获取硬盘信息,然后执行update-grub

我用的是第二种方法,果然在update-grub时侦测到了WIN10,然后自动生成了相关的启动配置。查看/boot/grub/grub.conf文件,自动生成的WIN10配置如下:

### BEGIN /etc/grub.d/30_os-prober ###
menuentry 'Windows Boot Manager (on /dev/nvme0n1p2)' --class windows --class os $menuentry_id_option 'osprober-efi-181C-9F4B' {
	insmod part_gpt
	insmod fat
	if [ x$feature_platform_search_hint = xy ]; then
	  search --no-floppy --fs-uuid --set=root  181C-9F4B
	else
	  search --no-floppy --fs-uuid --set=root 181C-9F4B
	fi
	chainloader /efi/Microsoft/Boot/bootmgfw.efi
}
set timeout_style=menu
if [ "${timeout}" = 0 ]; then
  set timeout=10
fi
### END /etc/grub.d/30_os-prober ###

update-grub 与 grub-mkconfig
grub-mkconfig会读取/etc/default/grub文件内容,然后通过os-prober扫描所有分区侦测OS,最终生成相关配置并写入/boot/efi/grub.conf,而update-grub则是一个脚本文件,调用的是grub-mkconfig。

四、小结

生命的意义在于折腾,如果不折腾,那么跟咸鱼有什么区别呢?
虽然折腾到最后还是重装了系统,但从中也获得了许多知识,满足感爆棚,因此写下本文,一为记录折腾过程防止自己问题重犯、二为碰到相同问题的朋友们提供小小的帮助。


参考:

  1. Microsoft 支持 - bootres.dll损坏
  2. GRUB (简体中文) - ArchWiki
  3. the GNU GRUB manual
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/zifehng/article/details/86657514

智能推荐

spring的@Transaction使用注意事项_守拙的小黑的博客-程序员宅基地

加@Transaction的方法必须是public,否则失效项目启动类添加@EnableTransactionManagement注解默认只在RuntimeException(也就是运行时异常)异常才会回滚,如果要所有异常都回滚,需要手动指定@Transactional(rollbackFor= Exception.class) 不管检查异常还是非检查异常都会回滚A方法调用B方法,B方法加上@Transaction注解,如果A,B方法在同一个类里,则方法B的@Transaction注解失效。因为@T._@transaction

Android腾讯浏览服务打开PDF,腾讯浏览服务_衤刀的博客-程序员宅基地

1. 基础配置1.1 SDK接入jar包方式集成您可将官网下载的jar包复制到您的App的libs目录,并且通过Add As Library的方式集成TBS SDKGradle方式集成您可以在使用SDK的模块的dependencies中添加引用进行集成: api 'com.tencent.tbs.tbssdk:sdk:43939'1.2 权限配置为了保障内核的动态下发和正常使用,您需要在您的And...

用C语言开发webservice_c语言实现webservice-程序员宅基地

写在转载之前:在用C语言开发webservice时,首先建立一个大的框架,然后再进行开发,这样在出现问题的时候,自己心里才有底,鉴于个人比较懒,不喜欢动笔,所以文章的内容就采用转载的方式!1 在进行开发前需要明白的几个概念:(1) 什么是webservice?(2) 什么是soap协议?(3) 什么是wsdl?2 开发借助的工具:gsoap3 利用gsoap快速开发一个_c语言实现webservice

目标规划---解目标规划的单纯形法-程序员宅基地

2019独角兽企业重金招聘Python工程师标准>>> ..._解目标规划的单纯形法

环信集成导入详细介绍与填坑(一)-程序员宅基地

环信集成导入详细介绍与填坑(一)公司需求,目前项目需求需要集成及时聊天通讯,几次对比之后选择用环信,关于环信就不多说了,想了解的环信及时通讯的小伙伴们,可以直接访问环信官网 。由于此次项目只需要实现简单的聊天,简单咨询了下环信客服,我们只需要导入环信easyui在这基础上进行简单的修改行了,不多扯了,下面直接说步骤(一)首先我们在官网里面下载环信sdk,下载之后的目录结构这是环信SDK的完整版

Uncaught TypeError: $(...).eq(...).show(...).siblings.hide is not a function at HT_$('.news_nr .newsbox').eq(num).show().siblings().h-程序员宅基地

$("#content div").eq(index).show().siblings().hide();在写淘宝轮播图时出现报错index.html:56 Uncaught TypeError: $(…).eq(…).show(…).siblings.hide is not a function at HT问题在于siblings没有加()._$('.news_nr .newsbox').eq(num).show().siblings().hide();

随便推点

形容计算机专业的诗句,形容工具好用诗句-程序员宅基地

形容“做一件事必须要借助好的的工具”的古诗语句有哪些表示工具好用,以提高效率的词语可以是“工欲善其事,必先利其器”工欲善其事,必先利其器是说:工匠想要使他的工作做好,一定要先让工具锋利。常言说得好:“磨刀不误砍柴工”。工匠在做工前打磨好工具,操作起来就能得心应手,就能达到事半功倍的效果,最好用的搓澡工具是什么最好用的搓澡工具,我个人认为,肯定是搓澡巾呢,但是搓澡巾一定要选择那种比较柔软的,不会伤害...

修改openwrt 终端登录欢迎界面-程序员宅基地

链接:https://blog.csdn.net/u011641885/article/details/47129363?utm_source=blogxgwz4转载于:https://www.cnblogs.com/hzijone/p/11452595.html_openwrt登录界面修改

python对excel数据可视化 plotly_Python利用Plotly实现对MySQL中的数据可视化-程序员宅基地

Mysql表数据:demo.sql内容create table demo(id int,product varchar(50),price decimal(18,2),quantity int,amount decimal(18,2),orderdate datetime);insert into demoselect 1,'AAA',15.2,5,76,'2017-09-09' union al..._python plotly table

WIN7中文专业版安装日文语言包的方法-程序员宅基地

1、首先下载安装语言包的工具,名字叫:Vistalizator,下载地址如下: http://www.froggie.sk/download.html2.下载适合你的操作系统的语言包 3.选择安装,系统会提示你等待20分钟左右即可完成安装工作4.安装完毕语言包后,系统会提示你需呀重新启动电脑5.根据提示重新启动后,会发现已经进入了日文语言的操作界面, 转载于:htt...

java注解怎么写_java自定义注解-程序员宅基地

注解说明Java注解又称Java标注,是Java语言5.0版本开始支持加入源代码的特殊语法元数据。为我们在代码中添加信息提供了一种形式化的方法,使我们可以在稍后某个时刻非常方便的使用这些数据。Java语言中的类、方法、变量、参数和包等都可以被标注。和Javadoc不同,Java标注可以通过反射获取注解内容。在编译器生成类文件时,注解可以被嵌入到字节码中。Java虚拟机可以保留注解内容,在运行时可以..._java注解怎么写

记梅县三及第老板娘-程序员宅基地

今天在三亚湾第一次吃梅县三及第我问老板娘,什么是三及第老板娘说,猪肝、粉肠、瘦肉。三及第枸杞叶汤和腌面我进到店里,出于好奇点了一份三及第枸杞叶汤和一份腌面。吃的味道感觉还不错,...

推荐文章

热门文章

相关标签