PC上的BIOS ROM是如何映射到地址空间中的?

18

x86 CPU从物理地址0xFFFFFFF0开始执行。在地址空间的末尾,BIOS ROM位于那里。CPU从ROM执行的第一条指令是远跳转(far jump),它会导致CS段重新加载,因此下一条指令将从物理区域0x000F0000-0x000FFFFF内执行。

是什么导致ROM在这两个区域上响应?PC上有一些特殊的地址解码逻辑吗?我在Bochs源代码中发现了注释,说明BIOS ROM的最后128K映射到0xE0000-0xFFFFF。然而,我找不到更多关于此的信息。显然,这是一些PC特定的东西,因为我有一个x86嵌入式板,这种镜像并没有发生。我只能使用近跳转。


1
你看过 http://wiki.osdev.org/System_Initialization_%28x86%29 吗? - user786653
2个回答

21
在PC上,总会涉及一些地址解码逻辑,因为在物理地址空间中有一些“洞口/窗口”,可以通过这些洞口/窗口访问BIOS ROM和I/O设备(例如视频卡),而不是RAM。出于兼容性的原因,这是设计好的,以便旧程序仍然可以在新电脑上运行。
至于CPU在复位后从哪个地址开始执行,如果您查看文档,您将看到Pentium级别的CPU从以下位置开始:
EIP=0xFFF0
CS.Selector=0xF000
CS.Base=0xFFFF0000
如果按照正常实模式寻址方案,则物理地址应为 CS.Selector*16+IP ,或者,使用这些值替换后为 0xFFFF0。然而,CPU实际上是用 CS.Base+(E)IP来计算地址(在实模式和16/32位保护模式下,但不在虚拟8086或64位保护模式下),因此CPU从内存中请求的第一个地址将是 0xFFFFFFF0。您无法使用远跳转到ROM中的高地址代码,可能是因为加载到 CS 后,CS.Base 将重置为 16 * CS.Selector 的新值。因此,跳转到 0xF000:0xFFF0 将传输控制到 0xFFFF0 而不是 0xFFFFFFF0,除非该ROM也映射到内存中的低位置并且其中的代码适用于在 CS(.Selector)=0xF000 下运行,否则它将无法运行。

此外,如果PC的最大限制为16MB(在i80286和i80386SX上)或4GB(在i80386DX/原始i80386和i80486上)或240-52字节(在64位Pentium级别的CPU上),那么既不需要CPU也不需要其周围的电路支持所有32个(或更多)地址线,如果物理地址空间中的许多高位被忽略,执行可以说有效地从低于理论最大值的地址开始-例如0x00FFFFF0(i80286/i80386SX)。

如果您需要解决主板问题,请查阅其文档和原理图以了解ROM是如何映射到物理地址空间上的。


谢谢。我特别关注断言“除非ROM也映射到低位置”。那么对于PC/AT兼容架构,ROM总是映射在这两个位置吗? - manison
3
CPU要求前16个最大字节的指令,而兼容性要求剩余的ROM BIOS代码可在1MB以下的位置使用(至少是其中一部分)。因此,如果这些第一条指令存储在同一个ROM中,则必须将其映射到2个不同的位置。但是,如果特定PC品牌中的第一条指令是跳转到ROM中的某个位置(例如0xF000:0xFFF0),则硬件实现可能会在从最大-16读取内存时简单地响应该远跳转指令的字节序列,而无需提供第二个映射。 - Alexey Frunze
看起来Z80的设计更好,CPU在启动时从地址0开始,中断向量放置在启动地址之后。 - Amir Saniyan

5

由于内存别名,ROM可以同时响应两个区域。根据英特尔的Pete Dice撰写的Dr. Dobbs文章

对于传统选项ROM和BIOS内存范围,英特尔芯片组通常具有内存别名功能,允许将访问1 MB以下的内存路由到或从位于4 GB以下的DRAM或非易失性存储器中。控制此别名的寄存器通常被称为可编程属性映射(PAM)。在固件阴影之前、期间和之后,可能需要操作这些寄存器。控制内存访问重定向的方式因芯片组而异。例如,某些芯片组允许控制读写,而其他芯片组仅允许控制读取。

请参阅该文章,了解有关设备内存映射和内存初始化、配置和测试的更多底层详细信息。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接