windows常见的启动问题包含以下类型:
主引导记录损坏(mbr corruption)
现象:主引导记录损坏的系统会在bios上电自检(post)阶段显示黑屏,并展示bios版本信息和oem品牌标识,之后系统卡住(hang)。根据mbr损坏的类型的不同,用户可能会看到系列的信息:“无效的分区表(Invalid partition table)”、“加载操作系统异常(Error loading operating system)”或者“操作系统缺失(Missing operating system)”。
成因:硬盘异常、windows运行时由于驱动bug造成的磁盘损坏或者病毒的蓄意破坏都会造成主引导记录损坏。
修复:开机进入windows恢复环境(windows recovery environment),选择“命令提示符(Command Prompt)”选项,之后运行“bootrec /fixmbr”命令。该命令会替换主引导记录中的运行代码。
引导扇区损坏(Boot Sector Corruption)
现象:引导扇区损坏的现象与主引导记录损坏相似,在bios上电自检后,系统卡在黑屏状态,此时可能在屏幕上显示“磁盘读取异常(A disk read error occurred)”、“bootmgr文件缺失(BOOTMGR is missing)”或“bootmgr文件被压缩(BOOTMGR is compressed)”等异常信息。
成因:硬盘异常、windows运行时由于驱动bug造成的磁盘损坏或者病毒的蓄意破坏都会造成引导扇区损坏。
修复:开机进入windows恢复环境(windows recovery environment),选择“命令提示符(Command Prompt)”选项,之后运行“bootrec /fixboot”命令。该命令会重写用户指定的卷的引导扇区。如果系统卷和引导卷不一致,那就需要在两个卷上都运行这个命令。
bcd配置错误(BCD Misconfiguration)
现象:在bios上电自检后,用户可能会看到如下的错误信息“windows因为计算机磁盘硬件配置问题无法启动(Windows could not start because of a computer disk hardware configuration problem)”、“无法从选定的引导磁盘上读取文件(Could not read from selected boot disk)”或“检查引导路径和磁盘硬件(Check boot path and disk hardware)”
成因:bcd被删除、bcd损坏或着由于分区的卷名称的改变造成不再指向引导卷都会造成该问题。
修复:开机进入windows恢复环境(windows recovery environment),选择“命令提示符(Command Prompt)”选项,之后运行“bootrec /scanos”和“bootrec /rebuildbcd”命令。这些命令会扫描每一个卷查找windows安装文件。如果发现了安装文件,就会询问用户是否将其作为引导配置项加入到bcd中,是否在引导菜单中展示对应的安装程序名称。对于其他的bcd相关的损坏情况,用户也可以使用Bcdedit.exe工具进行构建新的bcd或者复制现有的良好bcd文件的操作。
系统文件损坏(System File Corruption)
现象:系统文件损坏包含多种方式,例如可执行文件损坏、驱动损坏或dll损坏等。一种方式是在bios上电自检后,黑屏上会显示如下的信息“windows无法启动因为下列文件缺失或损坏(Windows could not start because the following file is missing or corrupt)”,后续会跟着对应文件的名称,并请求重新安装对应文件。另一种方式是引导阶段产生一个蓝屏崩溃,并伴随着如下的文本信息“停止码:0xC0000135(无法定位组件)”(STOP: 0xC0000135 {Unable to Locate Component})。
成因:系统文件所在的卷损坏、系统文件被删除或损坏都会造成该问题。
修复:开机进入windows恢复环境(windows recovery environment),选择“命令提示符(Command Prompt)”选项,之后运行“chkdsk”命令。chkdsk程序会尝试修复卷损坏。如果chkdsk程序没有报告任何问题,请获取有问题的系统文件的备份。可以检查%SystemRoot%\winsxs\Backup目录。windows会把windows资源保护访问的许多系统文件的备份纺织在这里。如果无法在该路径下找到对应的系统文件备份,可以尝试从互联网上获取对应的文件。注意备份文件必须与正在替换的文件来自同一系统版本或补丁程序。
在某些情况下,多个系统文件被删除或损坏,因此修复进程在用户逐个修复系统文件时需要进行多次重启和启动失败。如果用户认为系统文件损坏范围较大,建议从系统的备份中进行系统恢复,例如从windows备份程序产生或来自于一个系统恢复点的系统备份文件。
当用户运行备份与恢复(backup and restore)程序(位于开始菜单的维护文件夹中)时,会产生一个系统镜像恢复镜像,该镜像包含系统卷和引导卷中的全部文件,并伴随着一个存储了系统磁盘和卷信息的软盘。为了从这样一个镜像中恢复系统,从windows安装媒介中引导启动并在出现提示时选择对应的选项(或者使用更早之前展示的winre)。
如果没有可以用来进行恢复的备份镜像,最后的手段就是运行windows修复安装:从windows安装媒介中引导启动,按照向导如同进行新系统安装一样操作。向导会向使用者询问时进行系统修复还是重新安装系统。选择进行系统修复,安装程序将会重安装全部的系统文件,保留用户的应用程序数据和注册表设置。
系统注册表文件损坏(System Hive Corruption)
现象:如果系统注册表文件缺失或损坏,系统会在bios上电自检后显示黑屏,winload会在屏幕上显示如下信息“windows因为下列文件缺失或损坏而无法启动:\WINDOWS\SYSTEM32\CONFIG\SYSTEM”(Windows could not start because the following file is missing or corrupt: \WINDOWS\SYSTEM32\CONFIG\SYSTEM)。
成因:包含系统引导启动所需的配置文件的注册表文件损坏或被删除。
修复:开机进入windows恢复环境(windows recovery environment),选择“命令提示符(Command Prompt)”选项,之后运行“chkdsk”命令。如果问题未被修复,就去获取系统注册表文件的备份。windows每隔12小时会把系统注册表文件备份到%SystemRoot%\System32\Config\RegBack路径下(先前的备份文件会被重命名,带有一个.old的扩展后缀名称),因此就可以复制该路径下的文件到%SystemRoot%\System32\Config文件夹中覆盖异常的注册表文件。
如果启用了系统恢复功能,用户可以从恢复点获取一个时间上更加接近当前时间的注册表备份文件,该文件包含system注册表文件。
启动后崩溃或卡顿(Post–Splash Screen Crash or Hang)
现象:windows启动界面展示,桌面出现或者用户成功登录后发生了异常,出现了蓝屏崩溃或卡顿,整个系统被冻结或者鼠标光标可以移动但是系统没有任何反应。
成因:这个问题通常是由设备驱动程序的异常引发,但是有时也可能是系统注册表文件(不是system注册表文件)的损坏引起。
修复:用户可以使用多种方法尝试修复该问题。首先可以尝试使用最后已知正确的配置文件。最后已知正确(LKG:Last known good)就是指最后一次成功引导启动系统的注册表控制集。因为控制集包含了核心系统配置、设备驱动程序和服务注册表数据库,因此使用该版本将不会受到新增系统更改或新安装的驱动或服务的影响,避免因这些问题产生的异常。用户也可以在引导启动过程中按下f8按键访问之前进入安全引导模式的相同菜单中,在这里选择使用最后已知正确的配置文件进行系统启动。
如果使用LKG配置文件启动系统,系统会保存用户拒绝的控制集,并为其添加失败(failed)控制集的标签。在使用后LKG配置文件成功启动系统后,用户也可以将成功启动的控制集与失败的控制集配置导出到.reg文件中,并进行比较以确定系统启动失败的原因。用户可以通过使用regedit的导出功能实现这一操作,可以参考如下的文件菜单操作:
(1)运行regedit打开注册表,选择HKLM\SYSTEM\CurrentControlSet路径;
(2)在file菜单中选择export,将控制集保存在一个自命名的good.reg后缀的文件中;
(3)打开HKLM\SYSTEM\Select路径,读取failed的值xxx,选择名称为HKLM\SYSTEM\Controlxxx的子健;
(4)将控制集配置导出到名为bad.reg的文件中;
(5)使用WordPad程序把good.reg中的全部CurrentControlSet实例全局替换为ControlSet;
(6)使用WordPad程序把bad.reg中的全部Controlxxx实例全局替换为ControlSet;
(7)运行支持工具Windiff比较两个文件;
failed控制集和正常控制集可能会存在多处不同,因此用户需要把检查集中在control子键、驱动的parameters子键和services子键中注册的服务上。忽略控制集的services分支中的驱动注册表的enum子键的更改。
如果问题是上次成功启动前就已存在的驱动程序或服务造成的,那么lkg也无法成功启动系统。与之类似,如果控制集外存在异常配置设置或者在上次成功启动前问题就已存在,那么lkg也不会起作用。在这种情况下,下一步就是尝试安全模式启动。如果系统成功在安全模式下启动,就可以确认是特定的驱动程序造成了系统启动失败,用户可以通过使用设备管理器禁用设备驱动程序。可以通过选择异常驱动并从action菜单选择disable操作实现。如果用户最近更新了驱动程序,可以认为是更新引入了异常,用户可以在设备管理器中将对应的驱动程序回滚到先前版本。双击对应设备打开起属性对话框,点击驱动标签页中的“Roll Back Driver”即可实现驱动回滚。
在启用了系统还原(System Restore)功能的系统中,如果lkg无法启动系统,可以将系统回滚到先前的时间点。安全模式会检查恢复点是否存在,如果存在就会询问用户是否登录到安装文件中进行人工检查或修复,或者直接加载系统还原(System Restore)向导程序。如果用户知道问题成因并想要自动修复,或者用户不知道问题成因但不想浪费过多时间调查原因,那使用系统还原(System Restore)使得系统恢复正常是十分有吸引力的。
如果系统还原不可用或者用户以安全模式成功启动系统后想要明确系统崩溃的成因,可以在不成功的开机启动时通过f8进入特殊的引导菜单并选择引导记录(boot logging)选项获取引导日志记录。会话管理器(%SystemRoot%\System32\Smss.exe)会把记录引导启动过程中系统加载与不加载的设备驱动程序的相关记录信息保存到%SystemRoot%\ntbtlog.txt文件中,因此会话管理器初始化完成后,如果发生了系统崩溃或卡顿,用户就可以获得对应的引导日志。当用户重启进入安全模式后,系统就会把新条目添加到现有的引导日志中。摘录指向异常开机与安全模式开机的相关信息,并保存在不同的文件中。删除那些包含“未加载驱动”(Did not load driver)的文本行,之后使用例如windiff之类的文本比较工具进行比较。逐一禁用那些正常启动中加载但是安全模式启动中未加载的驱动程序,直到系统可以成功开机启动。(之后重启启用那些与问题无关的驱动程序。)
如果用户无法获得正常开机时的引导日志(例如系统在会话管理器初始化前就崩溃)、如果系统在安全模式也发生崩溃或者正常模式和安全模式的启动日志对比未显示任何明显不同(例如造成启动异常的驱动程序在会话管理器初始化完成后才被加载启动),下一个工具就是驱动验证器与崩溃转储文件分析同时进行。
备注
(1)上述描述主要来自于对于《Windows Internals》第六版第13章《stratup and Shutdown》中《Solving Common Boot Problems》章节的翻译,读者可以查询对应的原文获取原版的相关描述;
(2)上述方法在当前虚拟化背景下有些不可用,最主要的就是云厂商在云环境下使用了特定驱动(例如virtio)的存储器,而winre中不包含对应的驱动文件,因此在引导开机异常进入winre后,winre因为驱动问题无法识别系统磁盘,自然也无法进行相关的修复动作;
(3)可以通过向winre中打入对应的驱动文件解决该问题(详细方法可以在网上搜索),但是云厂商驱动不一,且更新频率无法保证,而且会有修改系统原始文件的风险,基于这一点,可能很多用户不会选择修改winre原始文件的方法;
(4)其次就可以选择常见的winpe修复方法,制作专用的winpe,在其中可以添加所需的驱动程序,再使用winpe进行系统修复,winpe的制作方法网络上有很多资源,这里也不再赘述;