x86 CPU在物理地址0xFFFFFFF0处开始执行。 BIOS ROM位于地址空间的末尾。 CPU从ROM执行的第一条指令是远跳转,导致重新加载CS段,因此从物理区域0x000F0000 - 0x000FFFFF内执行下一条指令。
是什么原因导致ROM在两个区域都做出响应? PC上有一些特殊的地址解码逻辑吗?我在Bochs源代码中发现了一条评论,该代码指出最后128K的BIOS ROM映射到0xE0000 - 0xFFFFF。但是我找不到更多关于此的信息。很明显,这是PC特有的,因为我有x86嵌入式主板,并且这种镜像不会发生在那里。我只能用近跳。
答案 0 :(得分:15)
在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(因为它是打开的话),CPU和它周围的电路都不能支持所有32(或更多)地址线i80386DX /原始i80386和i80486)或2 40-52 字节(在64位能力的奔腾级CPU上)如果是这种情况,如果忽略物理地址空间中的多个高位,可以说执行有效地从低于理论最大值的地址开始 - 例如16 0x00FFFFF0(i80286 / i80386SX)。
如果您需要解决电路板的问题,请参阅其文档和原理图,以了解ROM如何映射到其上的物理地址空间。
答案 1 :(得分:2)
由于内存别名,ROM对两个区域都做出响应。根据Intel的Pete Dice撰写的Dr. Dobbs article:
对于旧版ROM和BIOS内存范围,英特尔芯片组通常具有内存别名功能,该功能允许访问小于1 MB的内存以路由到大小小于4 GB的DRAM或非易失性存储器或从中进行访问。控制此别名的寄存器通常称为可编程属性映射(PAM)。在固件镜像之前,期间和之后可能需要操纵这些寄存器。内存访问重定向的控制因芯片组的不同而不同。例如,某些芯片组允许对读写进行控制,而其他芯片组仅允许对读取进行控制。
请查看本文,以获取有关设备内存映射以及内存初始化,配置和测试的更多低级详细信息。