从零写OS内核 | Windows MBR+BIOS 启动:BOOTMGR 之前发生了什么,以及怎么修复它
你有没有注意过一个现象:组装一台电脑,装上 Windows 10,系统保留分区(System Reserved)占了 100MB,C 盘占了剩下的一切。这个 100MB 的分区,平时在资源管理器里看不到,只有插上 Windows 安装U盘、进入”修复计算机”时,才隐约感觉到它的存在——里面有几个文件夹,叫 Boot、Recovery,还有一些 .mui 文件。
但如果你仔细看 Disk Management,会发现 System Reserved 的文件系统显示为”FAT32″,而不是 NTFS——这是 Windows 故意为之的,因为 BIOS 启动模式下,BOOTMGR 只能从 FAT 文件系统读取数据。
这一章,我们来把 Windows MBR+BIOS 启动链路彻底拆解——从按下电源键的那一刻,到 Windows 登录界面出现,中间每一个文件、每一步跳转、每一个工具怎么用,全部讲清楚。
BIOS + MBR 模式下 Windows 的启动链路
完整阶段图
① 电源按下
→ CPU CS:IP = 0xFFFF:0x0000
→ BIOS ROM 执行(0xFFFF0)
② POST(Power-On Self Test)
→ CPU 自检、内存检测、显卡初始化
→ 读取 CMOS 中的启动顺序
③ BIOS 按启动顺序查找"可启动设备"
→ 尝试第一块磁盘的 LBA 0(MBR)
④ MBR 的 512 字节
→ 前 446 字节:BOOTMGR 代码(或 GRUB Stage 1)
→ 中间 64 字节:分区表(4 条 × 16 字节)
→ 最后 2 字节:0x55AA(启动标志)
⑤ BIOS 把 CS:IP 跳转到 0x7C00(MBR 被加载的位置)
→ MBR 里的 BOOTMGR 开始执行
⑥ BOOTMGR(BootBOOTMGR,NTFS 压缩)
→ 读取 BootBCD(BCD 注册表配置)
→ 显示启动菜单(如果有多个启动项)
→ 找到 {default} 启动项的 osdevice
⑦ 加载 winload.exe
→ 路径:C:WindowsSystem32winload.exe
→ 验证启动签名(Secure Boot 相关,在 BIOS 模式下会跳过)
→ 读取 SYSTEM 注册表(获取驱动列表)
⑧ winload.exe 加载 ntoskrnl.exe + 驱动
→ 切换到更高特权级
→ 启动 Windows 内核整个链路里,唯一放在 MBR 里的 Windows 代码是 BOOTMGR 的一部分,其余所有东西(C 盘里的 winload.exe、ntoskrnl.exe、BCD)都在分区里。MBR 的 446 字节 bootloader 代码只是”第二阶段加载器”,真正的大头在 System Reserved 分区。
System Reserved 分区:100MB 里到底装了什么
正常情况下的分区结构
System Reserved 分区(也叫”系统分区”)在 MBR 模式下是 Windows 强制创建的。它必须是 FAT32 文件系统(不是 NTFS),因为 BIOS 模式下的 BOOTMGR 只认 FAT。
查看 Windows 系统的系统保留分区(在 Windows 里):
diskpart
list volume
# Volume 1 System Reserved FAT32 100 MB 启动
# Volume 2 C: NTFS 233 GB 活动System Reserved 分区(FAT32)内容结构:
D:(假设 System Reserved 是 D:)
├── Boot
│ ├── BCD ← 启动配置数据(注册表格式)
│ ├── BCD.LOG ← BCD 事务日志
│ ├── BCD.LOG1 ← 上一个版本的日志
│ ├── BCD.LOG2 ← 更早的日志
│ ├── BOOTMGR ← Windows Boot Manager(NTFS 压缩文件)
│ ├── bootmgfw.efi ← UEFI 版本备份(GPT 模式用,MBR 里实际不读)
│ ├── fonts
│ │ ├── boot.ttf ← 启动字体
│ │ └── segui_boot.ttf ← 备用字体
│ ├── Resources
│ │ ├── bootres.dll ← 启动资源(对话框、图标等)
│ │ └── ...
│ └── zh-CN ← 启动菜单中文本地化资源
│ ├── bootmgr.exe.mui
│ └── ...
├── System Volume Information ← 锁定的元数据目录
│ └── MountPointsRemote
└── (隐藏,无盘符,Windows 不分配)注意:如果你的 Windows 不是装在 MBR 盘上(而是 UEFI + GPT),System Reserved 分区不存在,取而代之的是 ESP(EFI System Partition),路径和内容相同,但文件系统是 FAT32,位置在 ESP 而非 System Reserved。
BOOTMGR 是什么
BOOTMGR(Boot Manager)是 Windows 的核心启动文件。它不是一个普通的 .exe,是一个压缩的 Win32 可执行程序(NTFS 压缩属性 C 标志置位)。
# 在 Linux 里查看 BOOTMGR 的属性(需要挂载 System Reserved)
# 假设 /dev/sda1 是 System Reserved
sudo mount -t fat /dev/sda1 /mnt/sysres
ls -la /mnt/sysres/Boot/
# -rwxr-xr-x 1 root root 412KB BOOTMGR ← 注意:NTFS 压缩状态在这里看不到(FAT32 无压缩)在 FAT32 的 System Reserved 里,BOOTMGR 不是压缩的(FAT32 不支持 NTFS 压缩)。但从 NTFS 的 C 盘里读取时,它会被标记为压缩——这是 NTFS 的稀疏文件功能。
BOOTMGR 的职责:
- 读取 BCD(不管 BCD 在哪里)
- 显示”Windows 启动管理器”菜单(超时前默认加载)
- 根据 BCD 里的
device/osdevice找到 Windows 系统分区 - 加载
winload.exe并跳转
BCD:启动配置数据
BCD(Boot Configuration Data)是一个注册表配置单元(Hive),和普通注册表 SYSTEM、SOFTWARE 一样是二进制格式,存储在 BootBCD。
# 在 Windows 里查看 BCD 内容(需要管理员权限)
bcdedit /store C:BootBCD /enum allBCD 里存储的内容(简化版):
{bootmgr}
description = Windows Boot Manager
device = partition=C: ← BCD 存储在 C: 盘的 BootBCD(MBR 模式)
locale = zh-CN ← 启动菜单语言
{default}
description = Windows 10
device = partition=C: ← Windows 在 C: 分区
osdevice = partition=C:
path = Windowssystem32winload.exe
systemroot = Windows
tools = partition=D: ← 指向 System Reserved(D:)
{memdiag}
description = Windows Memory Diagnostic
path = Windowssystem32memdiag.exe
{noide}
description = 禁用 IDE 控制器(故障排除用)winload.exe:真正的内核加载器
winload.exe(在 C:WindowsSystem32)才是 Windows 的第三阶段加载器——BOOTMGR 找到它并跳转执行,它负责:
- 读取注册表
HKLMSYSTEMCurrentControlSetServices*(驱动列表) - 加载内核镜像
ntoskrnl.exe和硬件驱动(*.sys文件) - 验证启动签名(在 UEFI 下强制验证,BIOS 下部分跳过)
- 初始化内存管理、调度器等子系统
- 把控制权交给 ntoskrnl.exe(真正的 Windows 内核)
winload.exe 的启动过程:
BOOTMGR → 读取 {default} 的 osdevice → 定位 C: 分区
→ 加载 WindowsSystem32winload.exe
→ 读取注册表 HKLMSYSTEMSelectCurrent(确定 ControlSet 编号)
→ 读取 HKLMSYSTEMCurrentControlSetServices*
→ 加载内核 + 驱动
→ ntoskrnl.exe 开始执行
→ Windows 登录界面出现工具一:bcdedit —— BCD 的”注册表编辑器”
基础用法
# 查看当前系统 BCD(默认 store)
bcdedit
# 查看详细参数(所有启动项)
bcdedit /enum all
# 查看特定启动项
bcdedit /enum {default}
# 以特定 store 查看(不用管理员也能读)
bcdedit /store C:BootBCD /enum allbcdedit 常用操作
# 修改启动项名称
bcdedit /set {default} description "Windows 10 Pro 22H2"
# 设置默认启动项(按 identifier 选择)
bcdedit /default {current} ← 当前启动项设为默认
# 删除启动项(先查看 identifier)
bcdedit /delete {identifier}
# 设置启动参数(禁用 DEP、启用测试模式等)
bcdedit /set {default} nx AlwaysOff ← 关闭 DEP
bcdedit /set {default} testsigning on ← 允许测试签名驱动
# 复制启动项(创建新的启动配置)
bcdedit /copy {default} /d "Windows 10 Safe Mode"
# 输出:已复制该条目 {identifier},用以下命令修改其设置:
bcdedit /set {identifier} nx AlwaysOff
bcdedit /set {identifier} safeboot minimal
# 开启 F8 高级启动菜单(MBR 模式默认开启)
bcdedit /set {default} bootmenupolicy Legacy
# 关闭(UEFI 默认):
bcdedit /set {default} bootmenupolicy Standardbcdedit 和 GRUB 对比
功能 bcdedit grub-mkconfig / grub.cfg
─────────────────────────────────────────────────────────────
查看配置 bcdedit /enum cat /boot/grub/grub.cfg
修改超时 bcdedit /set ... timeout GRUB_TIMEOUT=5 in /etc/default/grub
添加参数 bcdedit /set ... boot执行 bcdedit /set winload 参数 linux ... ro quiet
删除启动项 bcdedit /delete {id} 删除 grub.cfg 里的 menuentry工具二:bootrec —— MBR 模式的修复神器
bootrec.exe 是 Windows 安装盘/WinRE 环境里才能运行的修复工具,不是普通 Windows 里能用的。它的作用是重建 MBR 和启动扇区。
# 进入 WinRE 的方法:
# 1. 设置 → 更新和安全 → 恢复 → 高级启动 → 立即重启
# 2. 或者强制关机 3 次(触发自动修复)
# 3. 或者用 Windows 安装U盘启动,选"修复计算机"
# bootrec 的四个子命令:
bootrec /fixmbr ← 写入标准 MBR(Windows 自己的,不破坏分区)
bootrec /fixboot ← 写入新的 BOOTMGR 启动扇区
bootrec /scanbus ← 扫描所有可启动的 Windows 安装
bootrec /rebuildbcd ← 重建整个 BCD(从找到的 Windows 安装恢复)
# 完整修复顺序(推荐)
bootrec /fixmbr
bootrec /fixboot
bootrec /rebuildbcdbootrec /fixmbr 原理
/fixmbr 做的事情非常精准:它读取分区表(不改动),然后只在 MBR 的 446 字节代码区写入 Windows 标准 MBR 代码(不是 GRUB,不是第三方 bootloader)。
# Linux 下看 MBR 内容(SYSTEM Reserved 在 /dev/sda1,C: 在 /dev/sda2)
# Windows 标准 MBR 的特征:开头有 0x33 字节 xor 跳转模式
sudo dd if=/dev/sda bs=1 count=446 2>/dev/null | hexdump -C | head -5
# Windows MBR boot code 的特征字节(用于鉴别):
# 常见开头:eb 7c(跳转),33 c0(xor ax,ax),8e d8(mov ds,ax)
# GRUB Stage 1 的特征开头:eb 48(跳转),90 nopbootrec /fixboot 的原理
/fixboot 写入的是活动分区的引导扇区(BOOT sector),不是 MBR。它检查活动分区的文件系统类型(FAT32/NTFS),然后写入对应的引导扇区代码(包括跳转指令 + BPB 参数块 + 引导签名)。
# 如果 /fixboot 失败,可能是因为活动分区不是 FAT32
# 在 diskpart 里检查:
diskpart
list volume
# "System Reserved" 的卷通常是 FAT32,活动标志(boot)是它
# 如果活动分区被误标为 C:,bootrec 可能写到错误的分区工具三:reagentc —— Windows RE 的入口
reagentc 是 Windows RE(Recovery Environment)的配置工具,用来管理 WinRE 镜像的位置和启用状态。
# 查看 WinRE 状态
reagentc /info
# 输出示例:
# Windows Recovery Environment (Windows RE) 状态:
# Windows RE 位置: ?GLOBALROOTdeviceharddisk0partition1RecoveryWindowsRE
# WinRE 已启用: true
# 禁用 WinRE(临时关闭)
reagentc /disable
# 启用 WinRE(指向正确的 WIM 镜像)
reagentc /enable
# 设置 WinRE 镜像位置(如果镜像被移走了)
reagentc /setreimage /path D:RecoveryWindowsRE /device partition=D:
# 从 WIM 文件安装 WinRE(高级)
reagentc /setosimage /path C:WindowsSystem32Recoverywinre.wim /index 1WinRE 的工作原理:
- 镜像文件:
C:WindowsSystem32Recoverywinre.wim(约 200-300MB) reagentc /enable把 winre.wim 挂载到 System Reserved 的RecoveryWindowsRE目录- 启动时按 F8(或强制关机 3 次)触发 WinRE
WinRE 启动条件(MBR 模式):
1. System Reserved 分区存在
2. RecoveryWindowsREwinre.wim 存在且完整
3. BCD 里的 {memdiag} 条目指向 winre.wim
4. BOOTMGR 检测到"上次启动失败"标志(HKLMSYSTEMLastShutdownGood=0)工具四:diskpart —— 分区和启动标记的管理
diskpart 是 Windows 的磁盘管理底层工具,能做 GUI 工具做不了的事,比如设置活动分区(启动标记)。
# 启动 diskpart
diskpart
# 查看所有磁盘
list disk
# 查看所有卷
list volume
# 选择磁盘(看哪个磁盘的分区)
select disk 0
# 查看所选磁盘的分区
list partition
# 选择分区
select partition 1
# 查看分区详情(起始偏移、类型、大小)
detail partition
# 设置活动分区(将当前分区标记为可启动)
active
# 取消活动标记(慎用,取消后该盘无法启动)
inactive活动分区(active)和启动标志的区别:
| MBR 启动标志 | 活动分区 | |
|---|---|---|
| 位置 | MBR 分区表条目(0x80) | MBR 分区表条目(0x80) |
| 作用 | BIOS 据此判断”这个盘的第一扇区可以启动” | BOOTMGR 据此判断”这个分区包含 BOOTMGR 和 BCD” |
| BIOS 依赖 | 读取 MBR 时看 | 分区表必须有 0x80 条目才能启动 |
MBR 分区表 4 条条目,每条的第二个字节(偏移 0x01):
0x80 = 活动分区(可启动)
0x00 = 非活动
多个活动分区会导致"NO OS"错误(BIOS 只认第一个 0x80)工具五:bootsect —— 写入启动扇区的底层工具
bootsect.exe 是 Windows SDK 里的工具,在 WinRE 环境或 Windows 安装盘的命令行里可用。它和 bootrec /fixmbr 的区别是:bootrec 写入的是 Windows 自己的 MBR 代码,而 bootsect 可以指定目标是 MBR 还是特定分区。
# 写 BOOTMGR MBR(恢复 Windows MBR,不破坏分区表)
bootsect /nt60 C: /mbr
# /nt60 = Windows Vista/7/10/11 启动环境
# C: = 系统分区(C 盘,即活动分区)
# /mbr = 同时更新 MBR 代码(446 字节)
# 完整恢复 Windows MBR(在 WinRE 命令行里)
bootsect /nt60 SYS
# SYS = System Reserved 分区(不是 C:)
# 仅更新分区的引导扇区(不碰 MBR)
bootsect /nt60 D:
# D: = System Reserved(在 BIOS MBR 模式下 D: 通常是 System Reserved)bootsect vs bootrec:
bootrec /fixmbr → 只写 MBR 代码(446 字节),分区表不变
bootsect /nt60 X: /mbr → 写 MBR 代码 + 分区引导扇区(更新 X: 的 BOOT sector)工具六:Linux 下读写 MBR 和 BCD
如果你用 Linux Live USB 而非 Windows 安装盘,也有工具可以操作 Windows 启动数据:
dd:读写 MBR/分区表
# 读取 MBR(前 512 字节)
sudo dd if=/dev/sda of=/tmp/mbr-backup.img bs=512 count=1
# 查看 MBR 的分区表部分(446-512 字节)
sudo dd if=/dev/sda bs=1 skip=446 count=64 2>/dev/null | hexdump -C
# 备份 System Reserved 的引导区(前 63 个扇区,通常是 boot sector)
sudo dd if=/dev/sda1 of=/tmp/sysres-boot-backup.img bs=512 count=63
# 恢复 MBR(危险!先确认这是正确的镜像)
sudo dd if=/tmp/mbr-backup.img of=/dev/sda bs=512 count=1hexdump / xxd:直接看二进制内容
# 用 hexdump 看 MBR 内容
sudo dd if=/dev/sda bs=1 count=512 2>/dev/null | hexdump -C
# 看分区表(从 0x01BE 开始,64 字节)
sudo dd if=/dev/sda bs=1 skip=446 count=64 2>/dev/null | hexdump -C
# 解读分区表字节(4 条 × 16 字节):
# 字节 0:0x80=活动,0x00=非活动
# 字节 1-3:起始 CHS(已过时)
# 字节 4:分区类型(0x07=NTFS,0x17=Hidden NTFS,0x0C=FAT32)
# 字节 5-7:结束 CHS
# 字节 8-11:起始扇区(LBA 32位)
# 字节 12-15:分区大小(扇区数)mount:挂载 System Reserved(只读)
# 找到 System Reserved 分区(通常在 C: 前面,大小约 100MB,FAT32)
sudo fdisk -l /dev/sda | grep -E "System|FAT|100M| EFI"
# 挂载(只读,防止误改)
sudo mount -t fat /dev/sda1 /mnt/sysres -o ro
# 查看内容
ls -la /mnt/sysres/Boot/
ls -la /mnt/sysres/Boot/BCD
# 卸载
sudo umount /mnt/sysrestestdisk / photorec:恢复损坏的 BCD
# 如果 BCD 损坏(分区表还正常),用 testdisk 扫描
sudo testdisk /dev/sda
# 选择 [Proceed]
# 选 [Intel](MBR)
# 选 [Analyse] → [Search] 找丢失的分区
# 如果找到 System Reserved,确保挂载后 BCD 文件完整
# testdisk 也可以恢复被删的分区(但不会恢复 BCD 内容)
# BCD 本身是注册表 hive,没有备份的话损坏只能重建完整修复案例:重装 Windows 后 GRUB 消失
这是最常见的双系统问题。Windows 安装时覆盖了 MBR,GRUB 被抹掉,Linux 无法启动。
修复前准备:确认 Linux 分区在哪里
# 用 Linux Live USB 启动(任意 Linux 发行版)
# 列出所有磁盘和分区
sudo fdisk -l /dev/sda | grep -E "Linux|Filesystem"
# 或者用 lsblk
lsblk
# 找到 Linux root 分区(假设是 /dev/sda2)
# 注意:如果 /boot 是独立分区,需要额外挂载 /dev/sda1修复步骤(完整版)
# 1. 挂载 Linux 分区
sudo mount /dev/sda2 /mnt # 假设 /dev/sda2 是 Linux root
# 如果 /boot 是独立分区
sudo mount /dev/sda1 /mnt/boot # /boot 在 /dev/sda1
# 2. 挂载必要的系统目录
sudo mount --bind /dev /mnt/dev
sudo mount --bind /sys /mnt/sys
sudo mount --bind /proc /mnt/proc
# 3. chroot 进入 Linux
sudo chroot /mnt
# 4. 检查当前环境
grub-install --version
# 如果报错,可能是 chroot 里的 /dev 没正确挂载
# 5. 重新安装 GRUB 到 MBR(MBR 模式)
grub-install /dev/sda
# 6. 重建 grub.cfg(自动检测 Windows)
update-grub
# 输出应该包含:
# Found Windows Boot Manager on /dev/sda1
# Generating grub configuration ...
# Found linux ... on /dev/sda2
# 7. 退出重启
exit
sudo reboot如果 update-grub 没有检测到 Windows
# 在 chroot 环境里手动添加 Windows 启动项
# 先确认 Windows System Reserved 分区(假设 /dev/sda1)
blkid | grep -E "sda1|sda2"
# 编辑 /etc/grub.d/40_custom(正确位置,不是 grub.cfg)
cat >> /etc/grub.d/40_custom << 'EOF'
menuentry 'Windows 10 (via bootrec)' {
insmod ntfs
search --no-floppy --fs-uuid --set=root A2B3C4D5E6F7
chainloader +1
}
EOF
# 重新生成 grub.cfg
update-grub
# 如果 Windows 还是没被检测到,检查 UUID 是否正确
# 查看 Windows 分区的 UUID
blkid /dev/sda1 # FAT32 的 System Reserved实战:手动用 dd 重建 System Reserved 引导区
这个操作可以在不重装系统的情况下,修复 System Reserved 分区损坏导致的”启动设备未找到”错误。
步骤 1:确认 System Reserved 是哪个分区
diskpart
list volume
# 找到 FAT32 的"系统保留"卷(假设是 D:,大小 100MB)
# 注意这个分区没有分配盘符,需要先 assign
select volume 0 # 根据 list 的输出调整
assign letter=D # 临时分配 D: 盘符步骤 2:从 Windows 安装盘提取 BOOTMGR
# 在 WinRE 命令行里
# 先确认 C: 是哪个分区(Windows 系统分区)
# D: 是 System Reserved(刚刚 assign 的)
# 从 Windows 安装镜像的 boot.wim 里提取 BOOTMGR(如果本地 BOOTMGR 损坏)
# boot.wim 在镜像的 sourcesboot.wim 里
# 或者从正常工作的同版本 Windows 系统复制
copy C:WindowsBootPCATbootmgr D:Boot
copy C:WindowsBootPCATbootmgr.exe D:Boot 2>nul步骤 3:手动写入 boot sector(高级)
# bootsect 工具在 Windows 安装盘的 boot 目录下
# 在 WinRE 命令行里运行:
bootsect /nt60 D: /mbr
# 把 D:(System Reserved)的引导扇区写成 Windows 7+ 格式
# /mbr 同时更新 MBR 代码踩坑与注意事项
坑 1:System Reserved 被删后 Windows 无法启动
现象:磁盘管理里误删了 System Reserved 分区,然后 Windows 启动时直接报 “BOOTMGR is missing”。
原因:BCD 和 BOOTMGR 都在 System Reserved 分区里,没了这个分区,BOOTMGR 找不到了。
解决:用 Windows 安装盘启动 → 修复计算机 → 命令提示符 → 重建 BCD(不重装):
# 在 WinRE 命令行里
diskpart
list volume # 找到 C: 分区(NTFS)
select volume X # 选 C:
assign letter=C # 确保 C: 指向正确分区
# 创建新的 System Reserved 分区(从未分配空间)
create partition primary size=100
format fs=fat quick
active
assign letter=D
# 从 C:WindowsBootPCAT 复制启动文件到 D:
bcdboot C:Windows /s D: /f BIOS
# /f BIOS = 生成 MBR 模式启动文件(不是 UEFI)
# 或者用完整的 bootrec 流程:
bootrec /fixmbr
bootrec /fixboot
bootrec /rebuildbcd坑 2:bcdedit 改错了参数,系统无法正常启动
现象:执行 bcdedit /set {default} nx AlwaysOff 后,系统变得不稳定或无法进入安全模式。
解决:用 WinRE 启动,运行 bcdedit /deletevalue {default} nx 恢复默认值。
坑 3:活动分区标记错误导致 BOOTMGR 找不到
现象:BIOS 报告 “No bootable device”,但 MBR 的 0x55AA 还在。
原因:活动分区标记被误改(比如用 diskpart 把 C: 标为 active 而 System Reserved 变成 inactive),BOOTMGR 所在分区不再是”活动”的。
解决:用 diskpart 重新标记正确的分区为 active:
diskpart
list disk
select disk 0
list partition
# 找到 System Reserved(通常是最小的 FAT32 分区,100MB 左右)
select partition X
active # 设为活动坑 4:bootsect /nt60 写成 NTFS 分区(而非 System Reserved)
现象:执行 bootsect /nt60 C: 后,C: 盘的引导扇区被改写,但 BOOTMGR 在 System Reserved 里,Windows 仍然无法启动。
原因:BIOS MBR 模式下,BOOTMGR 和 BCD 在 System Reserved(FATE32),不在 C:(NTFS)。bootsect /nt60 C: 只更新 C: 的 boot sector,不管 System Reserved。
解决:确保 bootsect 目标指向正确的分区(System Reserved,即活动分区)。
# 正确顺序:先确定活动分区(System Reserved),再 bootsect
diskpart
list volume
# FAT32 的小分区(100MB)是 System Reserved
# 它的 boot flag = Active
# 用 bootsect /nt60 针对这个盘符写在最后
Windows MBR+BIOS 启动链路,从按下电源键到登录界面,经历了:
POST → MBR(446B BOOTMGR代码) → BootBOOTMGR → BootBCD
→ WindowsSystem32winload.exe → WindowsSystem32ntoskrnl.exeSystem Reserved 分区是这整条链路的”锚点”——没有它,BOOTMGR 无处可读;没有 BCD,BOOTMGR 无从知道该加载哪个 Windows;没有 winload.exe,内核永远不会被执行。
修复 Windows MBR 启动问题的核心工具就四个:bootrec(四板斧:/fixmbr /fixboot /scanos /rebuildbcd)、bcdedit(改 BCD)、bootsect(写引导扇区)、reagentc(管理 WinRE)。记住它们各自的职责,按顺序用,基本没有修不好的 MBR 启动问题。
wandos 目前没有自己的 MBR 启动支持。如果要做 MBR + BIOS 模式下的启动,需要参照 BOOTMGR 的架构:MBR 446 字节放跳转代码,跳转到 System Reserved 或 ESP 的 BOOTMGR,再由后者读取配置文件,找到内核文件。这整个链路比 GRUB 简单,但需要精确的分区表操作和 FAT32 文件系统支持。
下篇预告(365):候选方向——ext2 文件系统:inode、块组与目录项,或者 第一个用户态进程:从内核启动到 /sbin/init 的完整链路。你选哪个?
仓库:https://github.com/golang12306/os-kernel-from-scratch
相关阅读
- Windows BCD Store Format: 微软官方文档 MSBCDS
- bootrec.exe 源码参考:ReactOS 项目
bootvid/bootsect.c - UEFI Spec:BIOS 模式启动部分(Compatibility Support Module)
- Linux Kernel:
block/partitions/msdos.c(MBR 分区解析) - https://github.com/zhangfuwen/wandos — Linux 内核教程
动手环节
想深入理解本文内容?动手实践是最好的方式:
今天的目标:在虚拟机里模拟 System Reserved 损坏,然后修复。
-
创建 Windows 虚拟机(MBR 模式):
# 用 QEMU 创建 MBR 模式的 Windows 虚拟机 qemu-img create -f qcow2 win10-mbr.qcow2 50G # 安装时选择 MBR(不要选 GPT),确认有 System Reserved 分区 -
备份 System Reserved 的内容(Linux 里):
# 找到 System Reserved(/dev/sda1,大小约 100MB,FAT32) sudo mount -t fat /dev/sda1 /mnt/sysres -o ro tar -czf ~/sysres-backup.tar.gz -C /mnt/sysres Boot/ Recovery/ ls -la ~/sysres-backup.tar.gz -
模拟 BOOTMGR 损坏并修复:
# 备份 boot sector sudo dd if=/dev/sda1 of=/tmp/sysres-boot.img bs=512 count=63 # 损坏 boot sector(模拟错误修复) sudo dd if=/dev/zero of=/dev/sda1 bs=512 count=1 # 用 WinPE 启动,运行: # bootsect /nt60 D: /mbr # bootrec /fixmbr # bootrec /rebuildbcd -
用 bcdedit 创建自定义启动项:
bcdedit /copy {default} /d "Windows 10 No DEP" # 复制输出的 {identifier} bcdedit /set {identifier} nx AlwaysOff bcdedit /enum all -
用 reagentc 管理 WinRE:
reagentc /info # 查看当前 WinRE 状态 reagentc /disable # 临时关闭 reagentc /enable # 重新启用 # 触发 WinRE:开机时强制关机 3 次
提示:在实际机器上操作前,务必先在虚拟机里实验。Windows MBR 启动的修复工具(bootrec、bootsect)都是写入磁盘的工具,操作失误可能破坏分区表。用虚拟机可以放心尝试。
评论