当计算机启动时,首先执行的是BIOS中的代码。那么BIOS中的代码是如何加载到RAM中执行的呢?
我曾提到过这个问题——BIOS 是从 BIOS 芯片读取还是在启动时复制到 RAM 中?。但是,这让我更加困惑。如果 BIOS 是从 ROM 加载的,而 ROM 是一个单独的芯片,那么讨论 RAM 中的段地址有什么意义呢?此外,BIOS 代码加载在哪里 - 是在实模式地址空间的最后 1 MiB 中,还是其他位置?
如果有人能列出从计算机启动到执行第一个 BIOS 指令的步骤,包括使用的内存地址,那将非常有帮助
答案1
正如我所写的在我对这个问题的回答中关于这个问题的民间智慧 — — 不幸的是那里的其他答案(以及 SuperUser 的其他地方)也证明了这一点 — — 仍然停留在 1991 年左右的水平,尽管有大量的技术参考资料可以解释现在的情况。
如果您读了我的回答,您就不会这么困惑了,因为您一开始就不会问“从 ROM 加载的 BIOS”。
你的“BIOS 芯片”不是ROM;处理器启动与固件中的第一条指令之间没有机器代码;“RAM”和“ROM”中的“M”都表示“内存”。
正如我之前所写,在现代个人电脑中,机器固件保存在非挥发性记忆体。它不再是 ROM,而是以前的 ROM。有关连接到 LPC 总线的 NVRAM 芯片的详细信息,请参阅上一个答案。(例如:在我输入此内容时,在我旁边的一台拆开的机器上,保存固件的 NVRAM 是 Pm49FL004T,即 LPC 闪存 RAM 芯片。)
32 位 CPU 不会以实模式启动,也不会从 1MiB 线以下的地址开始。这是 16 位 x86 处理器时代几十年前的垃圾。它们以俗称的虚幻模式在我之前的回答中,我再次详细说明了实际情况自 80386 问世以来。它们从实际上位于 32 位地址空间顶部的地址加载第一条指令FFFFFFF0
。
在我之前的回答中,我详细地告诉了你机器固件在 32 位和 64 位 x86 机器上主要映射到物理地址空间的位置。记住:RAM 和 ROM 都是记忆. 物理地址是记忆地址,在系统总线上。它们可以寻址 RAM 或 ROM。(它们甚至可以寻址其他东西,但这只会使讨论复杂化。)物理地址比FFFFFFF0
512KiB 范围的顶部低 16 个字节,其中固件的前 512KiB(在非易失性 RAM 中)是总是由“芯片组”映射到系统总线上。
处理器初始化或重置时,不会从某些神秘的 ROM 芯片进行“加载”。保存固件的芯片是非挥发性记忆体。它保留其内容,在“刷新”时写入,跨电源循环。并且 CPU 只需通过系统总线和通过芯片组连接到系统总线的 LPC 总线(可能还有 LPC/FWH 桥)使用物理内存地址从中读取固件指令和数据。
进一步阅读
- 成化學術。 Pm49FL002 / Pm49FL004 数据表。
- 英特尔公司。“9.1.4 执行第一条指令”。英特尔® 64 和 IA-32 架构软件开发人员手册第 3A 卷:系统编程指南,第 1 部分。
答案2
当计算机启动时,首先执行的是BIOS中的代码。那么BIOS中的代码是如何加载到RAM中执行的呢?
它不需要加载,它就在那里。
保持简单:CPU 具有很大的地址空间。
32 位 CPU 有 2 32 个地址(0 到 4294967295,或 0x00000000 到 0xFFFFFFFF)
在 64 位模式下,64 位 CPU 有 2 64(0 到 18446744073709551999 或 0x0000000000000000 到 0xFFFFFFFFFFFFFFFF)。
外部硬件决定了什么出现在哪里。显然,RAM 将被分配一些地址,但也可以将外部设备映射到地址 - 对于图形适配器来说尤其常见。
我相信芯片组,特别是平台控制器中心,会让固件芯片出现在 CPU 开机时所查看的位置。CPU 将能够运行固件而无需加载它 - 这称为“就地执行”或 XIP。
Intel x86 CPU 在开机时查看 0x00000000FFFFFFF0。这可能是因为 Intel 在 70 年代或 80 年代早期开发了第一个 x86 CPU 8086 时决定将处理器异常向量放在 0x0 处 - 而且您无法告诉 8086 将它们重新定位到其他地方。
之所以称之为 ROM,是因为从历史上看,它很久以前就是一个真正的插座掩模 ROM 芯片,但至少从 90 年代中期开始,它几乎总是一个可以擦除和重新编程的 NOR 或 NAND 闪存芯片。
NVRAM 可以是任何东西,从电池供电的 RAM 到闪存,所以它是一个不精确的术语,但我从未听说过包含固件的芯片被称为“BIOS NVRAM”。
与 DRAM 相比,固件闪存芯片速度较慢,并且固件中的某些代码会经常运行(例如系统管理模式代码 - 管理风扇和电源的代码)。因此,固件会在启动初期将自身复制到 RAM(称为跟踪),并使用额外的芯片组功能来保护该内存区域。
如果有人能列出从计算机启动到执行第一个 BIOS 指令的步骤,包括使用的内存地址,那将非常有帮助
以前是这样的 - 开机后,CPU 会花一些周期进行初始化,然后开始执行 0xFFFF0000 处的代码 - 1981 年,当第一台 PC 开发出来时,CPU 和与之交互的所有东西都在一个公共总线上 - 实际上是连接在一起的 - 所以 ROM 只是在那条总线上,并连接到 CPU 上的正确地址线。在 90 年代初期,PCI 得到了开发,RAM 开始变得更快,所以一切都与控制器和芯片组后面的 CPU 分离。随着英特尔管理引擎和 AMD 的同类产品 - 平台安全处理器的出现,事情变得更加复杂 - 现在这些处理器拥有自己的嵌入式固件(并可以完全访问系统的其余部分),可以启动、验证各种事物并在准备就绪时“打开”CPU。