想想 8086……BIOS 是永久存储在内存中,还是复制到 RAM 中?

Vin*_*nny 8 bios cpu bare-metal

我有一个关于 BIOS 是如何加载和执行的问题。我知道CPU从0xFFFF0开始执行BIOS,但是BIOS在那里是怎样的呢?

BIOS 是否硬连接到 CPU 上的那个地址,到了你无法覆盖它的地方,

或者它被复制到该内存地址,就好像它只是您可以读/写的常规内存一样。

如果是这样,如果没有现有程序,它如何复制到该地址?

上下文:我正在为自定义 CPU 编写模拟器,我想知道 BIOS 如何在内存中存储和加载。

Fiz*_*izz 22

在 8088/8086 系统中,这通常是通过物理映射/连接 A16-A19 线来实现的,以启用(通过 74138 芯片启用/选择线)连接到 ROM 芯片启用线的正确 74138 型解码器。板上的其他 74138 的芯片启用/选择线的接线方式不同,因此当 RAM 的地址位于(地址)总线上时,后者被启用。在那个时代,您还拥有多个物理 ROM 芯片(小于 64Kb),因此这就是使用解码器的原因:A13-A15 行通常由同一个 74138 解码,以从集合中选择 ROM 芯片。

下面是一个类似的完整内存系统的图表()(139 是同一封装中的两个 138)。我怀疑这更像是一个学术系统而不是真正的系统:它的下半部分使用 4x16Kb ROM 芯片(27128)图中的上半部分是SRAM(62256芯片)。第一台真正的 IBM PC 使用 DRAM 作为 RAM,这就是为什么这更像是学术性的而不是真实的。

在此输入图像描述


或者它被复制到该内存地址,就好像它只是您可以读/写的常规内存一样。

我认为,它曾经被称为“影子 RAM”,直到386 时代才出现。(注意,有些后期的 286 芯片组也有它,例如 VLSI 82C202,尽管一些早期的芯片组,例如82C101显然没有它。)这是如何完成的(在一个 [Headland] 实现中):

当系统启动时,系统 BIOS 中的例程通过将 BIOS 复制回自身来将 ROM 模块复制到 RAM。内存控制器以将 ROM 内容复制到影子 RAM 中的方式安排读和写操作。[...]

其余的描述[对我来说]有些令人困惑,但本质上似乎那个时代的内存控制器在初始引导/复制模式下重定向了 ROM 地址写入 RAM。然后 BIOS 将控制器切换到“影子模式”,从该模式对这些地址的读取也从 RAM 进行(在复制完成后)。显然,在后一种/“影子”模式下,对 ROM 寻址的写入被禁用/忽略[在内存控制器级别],因此 BIOS 的 RAM 副本在此之后无法更改。但这可能相当依赖于内存控制器。

控制启动与稍后/“影子”模式的位位于 I/O 空间中的某个位置,例如在该特定控制器上,在进行自复制之后,BIOS 例程必须执行以下操作:

在此输入图像描述

82C202 使用了类似的“自复制”技术,但写保护是独立的(当然,用于访问控制器寄存器的 I/O 端口也不同。)

为清楚起见,“386”[或“286]”处理器的影子模式工作方式并没有什么特别之处。这一切都在[外部]内存控制器级别。只是据我所知,早期的IBM PC 中不存在该功能。


小智 10

具体细节当然取决于系统设计,但例如 IBM PC(具有更便宜但功能相似的 8088)具有8kb ROM 芯片。正如您所建议的,这是硬连线到较高内存地址的。因此,在复位时,CPU 会直接从 ROM 中读取数据。写入 ROM 存储空间显然不会影响 ROM 内容。


小智 7

简单来说,设备的 BIOS 或固件并不物理存储在处理器中。PCB上有一个专用芯片来存储它。该固件旨在通过与 PCB 上的所有主要组件“对话”来检查并启动所有必需的测试和流程。

固件从芯片启动并存入内存(RAM)以供主动使用。设备上任何其他组件上的关联地址仅仅是 BIOS 用于运行/启动启动期间所需执行的任何进程的地址。


由于您已经编辑并指定了更多信息,我认为以下现有帖子可能会帮助您更好地理解,因此我不必全部写出来:

  • 通过简化你的答案,你可以方便地避免“*固件从芯片启动并进入内存。“*固件启动*”是什么意思?DRAM控制器是如何初始化的?“*固件被设计为检查并启动所有必需的测试和过程*” - 固件无法自行执行。什么处理器正在执行该固件? (2认同)
  • 它当然不是“带入记忆”的。 (2认同)

Ral*_*edl 7

要回答有关仿真的问题,请在 0xFFFF0 处启动仿真 CPU 之前,将所需的 BIOS 加载到所需的地址(0x100000 减去 BIOS 的大小)。

背景:

8086(及兼容)从地址 0xFFFF0 开始执行。由此可见,必须已经有一条有意义的指令(通常是跳转到 BIOS 的开头)。BIOS 不是 CPU 的一部分,因为 BIOS 是特定于系统的。如果CPU中有BIOS,则CPU只能在该系统中使用。

因此,为 BIOS 提供指令超出了 CPU 的范围,系统必须在 CPU 进行任何初始化之前向 CPU 提供这些指令。

当时常见的解决方案是在 ROM 芯片中提供 BIOS。8086 的地址空间为 1MB 或 0x100000,因此 0xFFFF0 位于顶部下方。当CPU要读取内存时,它会将所需的地址放置在地址总线上,系统必须根据该地址的高位来决定如何反应该地址。要选择 ROM 芯片,您只需要一个解码器来检测顶部地址位全部设置为 1,因此带有几个输入的简单与门就可以了。需要多少位取决于 BIOS 的大小。8kB或0x2000的BIOS将从0x100000-0x2000=0xFE000开始,因此需要顶部7个地址线来解码0xFE。

访问 ROM 的速度相当慢,因此后来的系统决定将内容复制到 RAM,然后从 RAM 运行 BIOS。但这并不适用于早期系统。最初的 IBM PC 配备 16kB RAM,可扩展至 64kB。仅仅为了更快地执行 BIOS 而浪费 8kB RAM 是没有意义的。浪费实现这一点所需的电路也是没有意义的。由于无论如何你的模拟器都是从 RAM 运行的,所以实现类似的东西是没有意义的,除非你这样做是为了某些需要它的现有软件的利益。