x86 CPU从物理地址0xFFFFFFF0开始执行。 BIOS ROM位于地址空间的末尾。 CPU从ROM执行的第一条指令是远跳转,这导致CS段被重新加载,因此从物理区域0x000F0000-0x000FFFFF内执行下一条指令。
是什么导致ROM在两个区域上都响应? PC上是否有一些特殊的地址解码逻辑?我在Bochs源代码中找到注释,该注释指出BIOS ROM的最后128K映射到0xE0000-0xFFFFF。但是,我找不到有关此的更多信息。显然,这是特定于PC的东西,因为我具有x86嵌入式板,并且这种镜像不会在其中发生。我只能使用近跳。
最佳答案
在PC上,总是涉及一些地址解码逻辑,因为在物理地址空间中有一些“漏洞/窗口”,通过它们可以访问BIOS ROM和I / O设备(例如视频卡)而不是RAM。由于兼容性原因,这是设计使然,因此较旧的程序仍可以在较新的计算机上运行。
至于CPU在复位后开始执行的初始地址,如果您查看文档,将会看到奔腾级CPU以此开头:
EIP = 0xFFF0
CS。选择器= 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 / original),则CPU及其周围的电路都不必支持全部32条(或更多条)地址线。 i80386和i80486)或240-52字节(在具有64位功能的奔腾级CPU上),如果是这种情况,则如果忽略物理地址空间中的许多高位,则可以说执行有效地从一个地址开始低于理论最大值-16,例如0x00FFFFF0(i80286 / i80386SX)。
如果您需要解决电路板的问题,请参阅其文档和原理图,以了解如何将ROM映射到其上的物理地址空间。
关于embedded - BIOS ROM如何映射到PC的地址空间?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/7804724/