Windows 2008 R2 启动过程

Windows 2008 R2 启动过程

我一直试图理解我所经历的一些行为,我希望有人能帮助我一点启发。

我认为我的问题可以归结为:Windows 启动过程具体如何确定 Windows 2008 R2 中“启动”分区的 VBR/引导扇区在磁盘上的位置?

我提出问题的背景如下。

我有一个运行良好的 2008R2 (VM) 安装,其中包含标准的 100 MB 系统保留分区,后面是“启动”( C:\) 分区。出于教学目的,我将C:\分区移动到系统分区“右侧”正好 1MB(使用 gparted),从而在两个分区之间插入了 1MB(2048 扇区)的间隙。

此过程正确更新了 MBR 中的分区条目,并修改了C:\引导扇区的“保留/隐藏扇区”字段。

但现在 Windows 无法启动(它显示启动管理器错误“ 0xc0000225- 所需设备无法访问。”)。修复安装甚至找不到要修复的 Windows 安装。请注意,如果我在另一台 Windows 机器上安装驱动器,卷是健康且可行的。此外,如果我将分区移C:\回其原始位置,一切都会立即启动。

那么,假设 MBR 指向正确的偏移量,为什么C:\在移动分区后 Windows 无法找到/加载该分区?

答案1

首先,您应该注意到 C: 分区上的 VBR 不参与启动过程。“系统”分区上的 VBR 加载 bootmgr,后者从 C: 分区加载 Windows 内核。

我刚刚亲自尝试过。很方便的是,运行 bcdboot 会在 BCD 中生成一个新的启动项,因此我们可以轻松地将旧项与新项进行比较,以查看发生了什么变化。

使用 bcdedit 我们可以看到设备和 osdevice 选项是不同的:

C:\Windows\system32>bcdedit /enum /v

Windows Boot Manager
--------------------
identifier              {9dea862c-5cdd-4e70-acc1-f32b344d4795}
device                  partition=\Device\HarddiskVolume1
description             Windows Boot Manager
locale                  en-us
inherit                 {7ea2e1ac-2e61-4728-aaa3-896d9d0a9f0e}
default                 {fde483f1-1482-11e2-90a1-00505698002c}
resumeobject            {fde483f0-1482-11e2-90a1-00505698002c}
displayorder            {fde483f1-1482-11e2-90a1-00505698002c}
                        {7409376c-f38e-11e1-bc89-00505698002c}
toolsdisplayorder       {b2721d73-1db4-4c62-bf78-c548a880142d}
timeout                 30

Windows Boot Loader
-------------------
identifier              {fde483f1-1482-11e2-90a1-00505698002c}
device                  partition=C:
path                    \Windows\system32\winload.exe
description             Windows 7
locale                  en-us
inherit                 {6efb52bf-1766-41db-a6b3-0ee5eff72bd7}
osdevice                partition=C:
systemroot              \Windows
resumeobject            {fde483f0-1482-11e2-90a1-00505698002c}
nx                      OptIn
detecthal               Yes

Windows Boot Loader
-------------------
identifier              {7409376c-f38e-11e1-bc89-00505698002c}
device                  unknown
path                    \Windows\system32\winload.exe
description             Windows 7
locale                  en-US
inherit                 {6efb52bf-1766-41db-a6b3-0ee5eff72bd7}
recoverysequence        {7409376d-f38e-11e1-bc89-00505698002c}
recoveryenabled         Yes
osdevice                unknown
systemroot              \Windows
resumeobject            {7409376b-f38e-11e1-bc89-00505698002c}
nx                      OptIn

不幸的是,bcdedit 不会告诉我们信息是如何存储的,所以我们必须查看 BCD 文件本身。您可能已经知道,BCD 文件实际上是一个注册表配置单元,它通常会加载到 中HKLM\BCD00000000,因此我们可以使用 regedit 或使用 reg export 来检查它。

每个条目的标识符是包含设置的注册表项的名称。设置本身是子项,排列顺序与它们在 bcdedit 输出中出现的顺序相同。结果发现(不出所料)在每个条目中,设备和 osdevice 包含相同的数据,并且这些数据对于功能条目和旧条目是不同的。

在我的系统上,这出现在功能条目中:

"Element"=hex:00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,06,00,00,00,00,\
  00,00,00,48,00,00,00,00,00,00,00,00,00,80,06,00,00,00,00,00,00,00,00,00,00,\
  00,00,00,00,00,00,01,00,00,00,b0,5d,de,33,00,00,00,00,00,00,00,00,00,00,00,\
  00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00

旧条目中出现了以下内容:

"Element"=hex:00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,06,00,00,00,00,\
  00,00,00,48,00,00,00,00,00,00,00,00,00,50,06,00,00,00,00,00,00,00,00,00,00,\
  00,00,00,00,00,00,01,00,00,00,b0,5d,de,33,00,00,00,00,00,00,00,00,00,00,00,\
  00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00

只有一个区别。让我们将旧条目的格式变得更美观一些:

0000 00,00,00,00,00,00,00,00,
0008 00,00,00,00,00,00,00,00,
0010 06,00,00,00,00,00,00,00,
0018 48,00,00,00,00,00,00,00,
0020 00,00,50,06,00,00,00,00,
0028 00,00,00,00,00,00,00,00,
0030 00,00,00,00,01,00,00,00,
0038 b0,5d,de,33,00,00,00,00,
0040 00,00,00,00,00,00,00,00,
0048 00,00,00,00,00,00,00,00,
0050 00,00,00,00,00,00,00,00

在新条目中,字节 0x0022 是 0x80,而不是 0x50。碰巧的是,我将分区移动了 3MB,所以我怀疑这是偏移的一部分。让我们看看如果我再移动 4MB(总共 7MB)并创建一个新的 BCD 条目会发生什么,好吗?好的……0x80 变成了 0xC0,所以这是一致的。

合理的猜测是,从 0x0020 开始的八个字节(或者可能是十六个?)是分区起始处的字节偏移量。0x06C00000 的值是 113246208,或者正好是 108MB;检查分区表后,我发现这确实是分区的起始处。QED。:-)

相关内容