问题 BIOS ROM如何映射到PC上的地址空间?


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

什么原因导致ROM在两个区域都做出响应? PC上有一些特殊的地址解码逻辑吗?我在Bochs源代码中发现了一条评论,该代码指出最后128K的BIOS ROM映射到0xE0000 - 0xFFFFF。但是我找不到更多关于此的信息。很明显,这是PC特有的,因为我有x86嵌入式主板,并且这种镜像不会发生在那里。我只能用近跳。


9294
2017-10-18 08:57


起源

你看过了吗? wiki.osdev.org/System_Initialization_%28x86%29 ? - user786653


答案:


在PC上总是涉及一些地址解码逻辑,因为在物理地址空间中存在一些“孔/窗口”,通过它们可以访问BIOS ROM和I / O设备(例如视频卡)而不是RAM。这是出于设计原因,出于兼容性原因,旧程序仍然可以在较新的计算机上运行。

至于CPU在重置后开始执行的初始地址,如果查看文档,您会看到奔腾级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 /原始版本上),CPU和它周围的电路都不能支持所有32(或更多)地址线。 i80386和i80486)或240-52 字节(在64位能力的奔腾级CPU上)如果是这种情况,如果忽略物理地址空间中的多个高位,则可以说执行有效地从低于理论最大值的地址开始 - 16,例如0x00FFFFF0(i80286 / i80386SX)。

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


15
2017-10-18 10:55



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