Windows系统启动问题排查

Windows系统启动问题排查

马草原 1,229 2022-02-07

Windows系统启动问题排查

对于我们计算机行业的从业人员来讲,费时费力的去排查Window系统的启动问题似乎很不划算(毕竟Windows出现一些奇奇古怪的问题很常见 疑难杂症)。我们一般的解决思路是进PE,备份下磁盘的数据然后重新装个系统就完了,现在都是固态硬盘装个系统几分钟搞定。

问题就出在过年期间,管你是做Java的还是做前端的,在亲戚眼里你学电脑的一定会修电脑🙄…

刚好也是疫情封控,很多要用电脑上网课,各种Window疑难杂症就朝我抛过来了(我不是修电脑的啊😭),他们的电脑普遍都很久没装过系统了,而且资料也是存的乱七八糟的(C盘都红了🤬),重装系统对于他们来说接受不了,而且他们的系统五花八门Win7 Win10 甚至还有用Win8的。。。

对于不能正常启动的,还不能装系统的Windows电脑,该怎么排查问题呢?

Windows系统启动过程

要想排查问题出在哪,首先要知道Windows怎么启动的,有几个步骤,然后找到卡在哪个步骤,知道问题了才能对症下药。

  1. 开机
  2. 加电自检(POST)
  3. 寻找引导盘
  4. 从引导盘加载执行MBR
  5. MBR code从DPT查找活动分区
  6. 控制权交给活动分区的PBR代码
  7. PBR代码查找并启动boormgr
  8. BootMgr读取BCD配置文件
  9. 根据BCD配置启动winload.exe
  10. 载入windows内核
  11. 载入system注册表,根据注册表配置加载设备驱动
  12. 启动smss.exe
  13. 初始化子系统,创建session进程,启动服务;
  14. 启动桌面
  15. 启动完成

Windows启动整体上划分为:

BIOS阶段 --> Boot阶段(MBR到ntos kernel加载之前)--> kernel阶段 --> 应用服务启动阶段

以上任务一个步骤异常都有可能造成系统启动失败,下面根据实例启动过程,依次讲解实例启动故障以及对应的排查手段(BIOS一般和硬件相关,我不会修硬件 我也更不愿意去碰他们那些能倒出来3斤灰的机箱🙄)。

Boot阶段故障排查手段

在PE环境中依次运行

diskpart
list disk
list volume

如下图,磁盘和系统盘分区C盘都存在并且都是正常的
boot

确定磁盘是否可以访问

有些人用的机械硬盘 用久了磁盘都出故障了。。。 而且是个偶现的
这里建议拉一个大文件拷贝到C盘,如果能完整写入那代表磁盘没太大问题。
如果写入一半突然出错了 那基本就是硬盘废了。 没得跑了。

确定C盘是否为活动分区

在PE环境中依次运行

diskpart
list disk
select disk 0
select partition 1
detail  PARTITION

partition

如果显示不是活动分区执行以下命令设置:

active

active

确定以下Windows核心文件是否存在

C:\bootmgr
C:\Boot\BCD
C:\Windows\System32\winload.exe
C:\Windows\System32\ntoskrnl.exe
C:\Windows\System32\config\SYSTEM

以上几个文件是windows启动过程中必须的核心文件,如果不存在把缺少的从正常的Windows系统中复制一个过来基本可以解决问题。

尝试修复MBR和BootSector

执行命令:bootrec /fixmbr,该命令仅仅修复mbr boot代码,不会动DPT
bootrec

执行命令:bootrec /fixboot,该命令会覆盖整个boot sector,修复强度高于fixmbr
fixboot

尝试修复BCD

执行bcdedit命令,检查BCD启动项配置,如下图:
bcd

正常情况下,至少有两个启动项,一个是{bootmgr},一个是{default},如果安装了多个操作系统,这里会存在2个以上的项目;{default}项代表系统默认启动的操作系统,其中重点关注4个配置:

device partition=C:
path \Windows\system32\winload.exe
osdevice partition=C:
systemroot \Windows

这4项决定了系统启动时选择的加载器和操作系统内核,如果其中某个配置错误,可以通过如下命令修改:

bcdedit /set *{identifier}* option value

举例,将启动设备改为D盘:

bcdedit /set {default} device partition=D

也可以通过Bootrec进行修复

执行命令:

Bootrec /ScanOS

重启系统,检查问题是否修复;
如果问题未解决,继续运行如下命令:

Bootrec /rebuildbcd

重启系统查看系统是否启动成功

kernel阶段故障排查手段

尝试替换系统注册表

在PE环境下将文件夹C:\Windows\System32\config\RegBack的所有文件
拷贝到 C:\Windows\System32\config目录,重启系统查看系统是否启动成功。

替换注册表可能会导致某些软件打不开但是先进系统再说吧,现在问题是系统都起不来了😂。。。

尝试修复受损的磁盘或者文件

修复受损的系统文件

SFC /Scannow /OffBootDir=C:\ /OffWinDir=C:\Windows 

修复受损磁盘

chkdsk /f /r c:

修复系统镜像

dism /image:C:\ /cleanup-image /restorehealth

确定存储链路核心服务是否正常

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services

检查注册表上面路径的磁盘相关核心服务是否存在:

  • ACPI
  • DISK
  • VOLMGR
  • PARTMGR
  • VOLSNAP
  • VOLUME
  • viostor

接下来依次检测以上每个服务的Start类型是否为0(为0代表Boot启动):
acpi

确定是否存在异常的磁盘过滤驱动

需要检测的地方有2处:

第一处为:

HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Control\Class\{4d36e967-e325-11ce-bfc1-08002be10318}

可以对所有的磁盘进行过滤,以下是正常的情况:
HKEY_LOCAL_MACHINE

如果我们添加一个不存在的过滤服务,系统将会无法启动,例如:
testfilter

第二处为

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\SCSI

此处可以对单块磁盘进行过滤
HKEY_LOCAL_MACHINE1

如果我们对某一块盘增加一个不存在的过滤器,磁盘设备将会异常,无法访问:
diskerror

检查设备驱动如果我们对某一块盘增加一个不存在的过滤器,磁盘设备将会异常,无法访问
diskerror2

和正常镜像比对关键设备配置

上面都没问题那就知道上对比大法了。。
把出问题的机器配置和正常机器的配置对比一下,看看哪里不一样。

对比windows设备树

windows操作系统的PNP管理器维护了一个设备树用于管理跟踪系统中的所有设备
如下图:
WindowsPNP

设备树包含了系统中所有接入设备的信息,实例启动时PNP管理器根据设备驱动提供的信息构建设备树,实例启动后,当有设备接入或者移除时,设备树动态更新。Windows实例自带的设备管理器能查看系统设备树,以磁盘设备为例,上下两图图所体现的路径完全一致:
acpi-1700464621978

设备树中部分核心设备在启动过程中就需要初始化,如果初始化失败,系统启动也会失败,其中磁盘存储设备就属于这一类核心设备;系统启动时会从设备树根部一直检查到磁盘,路径为:

Root Device-->APCI-->PCI Bus-->SCSI Adapter-->Disk

整个路径如果有任何一个节点异常,启动就会失败,错误码为INACCESSIBLE_BOOT_DEVICE,因此INACCESSIBLE_BOOT_DEVICE错误的原因很复杂,不一定发生在磁盘上。

设备配置信息

设备树中所有设备节点的配置信息都保存在注册表的固定位置,实例启动过程中会去读取设备配置信息,初始化设备,启动设备驱动服务,如果配置丢失或者配置错误,就会导致设备初始化失败,Windows是如何查找对应设备的配置信息的?以viostor磁盘控制器为例,Windows是这样一步步将设备和驱动对应起来的:

1、在设备管理器上找到设备ID

PCI\VEN_1AF4&DEV_1001&SUBSYS_00021AF4&REV_00\3&13C0B0C5&1&20

13C0B0C

2、在注册下根据设备ID找到对应设备INF配置项名称oem6.inf
注册表路径:

HKEY_LOCAL_MACHINE\SYSTEM\DriverDatabase\DeviceIds

oem6

3、在注册表下根据oem6.inf找到原始的inf信息:viostor.inf_amd64_8552d5091096a501

注册表路径:

HKEY_LOCAL_MACHINE\SYSTEM\DriverDatabase\DriverInfFiles\

8552d5091096a501

4、在注册表下根据viostor.inf_amd64_8552d5091096a501找到最终的配置信息:

注册表路径:

HKEY_LOCAL_MACHINE\SYSTEM\DriverDatabase\DriverPackages\

inf_amd64_8552d5091096a501

5、根据配置信息中服务名称启动对应的驱动服务:

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\viostor

viostor21

从上述过程中可以看出virtio磁盘设备初始化过程中涉及以下关键注册表配置的读取:

HKEY_LOCAL_MACHINE\SYSTEM\DriverDatabase\DeviceIds
HKEY_LOCAL_MACHINE\SYSTEM\DriverDatabase\DriverInfFiles
HKEY_LOCAL_MACHINE\SYSTEM\DriverDatabase\DriverPackages
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services

以上任何一处注册表配置异常都会导致磁盘设备初始化失败
造成启动的时候 蓝屏错误码:INACCESSIBLE_BOOT_DEVICE

系统更新被打断造成下次启动失败

升级系统图中停电了。然后再也启动不了了

  1. 进入PE,然后获取package列表,找出pengding状态的package
Dism /Image:C: /Get-packages

pending

  1. 删除pending状态的package:
dism /Image:C:\ /Cleanup-Image /RevertPendingActions

RevertPendingActions

大概率会遇到删除失败的情况:
RevertPendingActionsError

删除失败就直接删注册表:
8d604724-b784-4871-9e48-a2f90fd68352

4、检查C:\Windows\WinSxS目录,如果存在pending.xml文件,则重命名为pending.xml.old

5、Win+R然后打开regedit程序,选中HKEY_LOCAL_MACHINE,然后菜单栏依次选择 文件–>加载配置单元,弹框中选中C:\Windows\System32\config\COMPONENT
regedit

6、展开HKEY_LOCAL_MACHINE\OfflineComponentHive,检查PendingXmlIdentifier是否存在,如果存在则删除

7、卸载注册表,选中OfflineComponentHive,菜单栏依次选择 文件–>卸载配置单元

8、检查注册表是否存在PendingFileRenameOperations键值,如果存在,则删除
注册表路径:

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager

9、删除C:\windows\System32\Config\TxR目录下的一些文件:

cd /d C:\Windows\System32\Config\TxR
attrib -s -h *
del *.blf
del *.regtrans-ms

10、删除C:\Windows\System32\Config目录下的.blf.regtrans-ms

cd /d C:\Windows\System32\Config
attrib -s -h *
del *.blf
del *.regtrans-ms

11、删除C:\Windows\System32\SMI\Store\Machine目录下的.blf.regtrans-ms

cd /d C:\Windows\System32\SMI\Store\Machine
attrib -s -h *
del *.blf
del *.regtrans-ms

12、删除SessionsPending

加载注册表缓存拉取SessionsPending 命令输入完成后按回车

reg load hklm\temp c:\windows\system32\config\software

删除SessionsPending注册表项 命令输入完成后按回车

reg delete "HKLM\temp\Microsoft\Windows\CurrentVersion\Component Based Servicing\SessionsPending"/v Exclusive

卸载此前加载的注册表缓存 命令输入完成后按回车

reg unload HKLM\temp

Windowssss