Windows bcdedit 将配置参数存储在 NVRAM 中?这是什么意思?

Windows bcdedit 将配置参数存储在 NVRAM 中?这是什么意思?

在 Win10 中bcdedit /?,帮助文本说它将把启动配置参数存储在非易失性 RAM (NVRAM) 条目中。

bcdedit /?

这太荒谬了吧?据我所知,bcdedit 将配置存储在磁盘文件中。

具体来说……

※ 如果典型的 x64 PC 的 BIOS 确定它应该以传统 BIOS 模式启动 PC,

  1. 它将第一个磁盘扇区(MBR 扇区)加载到 RAM 中并执行。
  2. 该 MBR 代码依次将活动分区的第一个扇区(OS 引导扇区)加载到 RAM 中并执行。
  3. 操作系统引导扇区依次将\bootmgr文件(无文件扩展名)加载到 RAM 中并执行。
  4. 代码bootmgr发现\Boot\BCD(再次没有文件扩展名)以获取[我们之前通过运行设置的启动配置bcdedit]。

※ 如果典型的 x64 PC 的 BIOS 确定它应该以 UEFI 模式启动 PC,

  1. 它找到一个 EFI 系统分区并加载\EFI\Boot\bootx64.efi到 RAM 中并执行。
  2. 然后 bootx64.efi 读取\EFI\Microsoft\Boot\BCD启动配置参数。

似乎与 NVRAM 无关。它是否意味着(在 bcdedit 上下文中)硬盘上不存在但某些 PC 主板芯片上存在的东西(我称之为 BIOS 区域)?

如果bcdedit真的可以在 BIOS 区域存储/更改某些数据,请举个例子。我的意思是,什么样的bcdedit参数会导致 BIOS 区域数据被更改?

答案1

您跳过了 UEFI 模式的很多步骤。您说得对,“它找到 EFI 系统分区并加载 \EFI\Boot\bootx64.efi”是其中之一,但它是倒退行为(正式的说法是“可移动磁盘”行为)——在达到这一点之前,有一两步涉及主板的 NVRAM。

首先,正如UEFI 规范PDF),固件提供了广泛的“启动”和“运行时”服务(原理上类似于 BIOS 中断),其中包括“变量服务”(第8.2节) 允许操作系统在系统 NVRAM 中保存各种键值对。(通常,它是固件用于其自身设置的同一闪存,又称“CMOS”,许多系统实际上存储全部固件设置作为 EFI 变量。

通常操作系统会以某种方式将变量服务 API 暴露给用户空间程序,例如 Windows 提供设置固件环境变量()而Linux有一个虚拟文件系统/sys/firmware/efi/efivars

此外,正如第2.1节第3节,固件有自己的启动管理器它“将尝试按照全局 NVRAM 变量定义的顺序加载 UEFI 驱动程序和 UEFI 应用程序(包括 UEFI OS 引导加载程序)。”固件引导管理器基本上与您可能使用过的 F8 或 F10“引导菜单”相同,但除了列出整个磁盘外,现在它还列出了操作系统的单个 .efi 文件。

(这个功能实际上早于 UEFI相当多——你引用的“以前”指的是阿尔法AXP和/或 Itanium IA64 EFI,两者都运行 Windows;两者都与 Boot.ini 同时存在(即在 BCD 之前);并且两者都有固件启动管理器。不过,我都没有两者的规格链接。)

EFI“启动管理器”主要使用 NVRAM 变量命名Boot####(4 位数字)BootOrderBootNext列出已安装的操作系统。每当 Windows 安装自己的 BOOTMGR(可以使用 手动完成bcdboot.exe)时,它还会使用 EFI 变量服务(通过 Windows 提供的 API)创建指向 的 Boot0000 条目\EFI\Microsoft\Boot\Bootmgfw.efi,标题为“Windows 启动管理器”。

实际上,你可以通过 查看这些条目bcdedit /enum firmware,尽管它们将被大量转换为类似 Windows BCD 的格式(因为同一个工具可以处理两个都efibootmgr [-v]EFI 和 BCD 条目),或者在 Linux 或 FreeBSD 内部运行:

BootCurrent: 0003
Timeout: 0 seconds
BootOrder: 0003,0005,2003,0002,2001,2002
Boot0000* UEFI Onboard LAN IPv4     PciRoot(0x0)/Pci(0x1c,0x0)/Pci(0x0,0x0)/MAC(3417eb7eda76,0)/IPv4(0.0.0.00.0.0.0,0,0)RC
Boot0001* UEFI Onboard LAN IPv6     PciRoot(0x0)/Pci(0x1c,0x0)/Pci(0x0,0x0)/MAC(3417eb7eda76,0)/IPv6([::]:<->[::]:,0,0)RC
Boot0002* HDD1-1 (Samsung SSD 860)  PciRoot(0x0)/Pci(0x1f,0x2)/Sata(0,0,0)/HD(1,GPT,b7245b9a-d13f-4d97-8bff-901255bfd7ad,0x1000,0x100000)RC
Boot0003* Linux Boot Manager        HD(1,GPT,b7245b9a-d13f-4d97-8bff-901255bfd7ad,0x1000,0x80000)/File(\EFI\systemd\systemd-bootx64.efi)
Boot0004* Arch Linux LTS            HD(1,GPT,b7245b9a-d13f-4d97-8bff-901255bfd7ad,0x1000,0x100000)/File(\EFI\Linux\vmlinuz-linux-lts.efi)
Boot0005* EFI Shell                 HD(1,GPT,b7245b9a-d13f-4d97-8bff-901255bfd7ad,0x1000,0x80000)/File(\shellx64.efi)

因此,UEFI 固件的真正步骤(再次描述在第3节) 是:

  1. Boot####它从 BootNext 或 BootOrder 指示的变量中读取 EFI 文件系统路径,然后尝试按指定顺序将每个文件作为 .efi 可执行文件加载和运行。(BootOrder 中未列出的启动项处于非活动状态。)

  2. 如果任何活动的 Boot#### 变量都无法执行,则通常回到“可移动磁盘”扫描所有磁盘以查找包含 EFI 系统分区\EFI\Boot\Boot[cpuarch].efi并执行该分区的行为。如果您从固件的启动菜单中手动选择整个磁盘,也会发生这种情况。

    (实际上我见过的所有系统也都将其应用于固定内部磁盘。这样,当磁盘移动到另一个主板或 NVRAM 数据由于某种原因丢失时,就可以启动已安装的操作系统,以及为 EFI 安装操作系统,即使安装介质由于某种原因无法在 EFI 模式下启动,因此可变服务不可用。)

  3. (作为最后的手段,一些固件(主要是基于 EDK2 构建的固件)将运行 EFI Shell 的嵌入式副本,这是一个与 MS-DOS 有点类似的交互式 CLI,可让您手动运行 .efi 文件。其他一些固件将打开文件浏览器 GUI,您可以在其中选择要运行哪个 .efi 文件。其他固件则直接进入固件设置屏幕。)

这个 EFI 启动过程很大程度上受到了以下启发:在 Alpha 中发现的(这是 x86 之前的主要 WinNT 平台)。在某种程度上,Windows NT/2000/XP 中的 NTLDR 和 Boot.ini 模仿了 Alpha AXP基于固件的启动项,甚至包括系统磁盘使用 ARC 路径。

类似地,Windows XP 也可用于 Itanium IA64 上的 EFI,它完全依赖于 EFI 启动管理器(据我所知,它没有自己的启动菜单),因此“这些参数以前在......”很可能是指 XP 使用本机 EFI 启动管理器功能以及使用 Boot.ini 的 x86 版本。

(因此我怀疑当前的 Windows 启动管理器及其 BCD 的创建是因为微软一直发现 AXP 和 EFI 提供的接口不够充分,但它仍然在某种程度上模仿 EFI 风格的启动,例如,即使 BIOS 安装现在也有专用的“系统分区”并且不再将 BOOTMGR 直接放在 C:\ 上。)

也许是因为后者,该bcdedit工具通过统一的界面管理两种类型的启动条目 - EFI 固件以及 Windows BCD。例如,默认情况下bcdedit将列出 BOOTMGR 使用的 Windows BCD 条目,但如果您指定该/enum firmware选项,则它将列出固件启动菜单使用的 EFI NVRAM 条目(尽管格式与真实格式非常不同)。

相关内容