运行在x86_64长模式下的BSP能否发送SIPI唤醒AP?
问题1:SDM提到的BSP初始化序列是否适用于长模式
完全适用。长模式是x86保护模式的扩展架构,进入长模式的前提就是已经开启保护模式(你当前EFER寄存器已经置位LME、LMA,CR0置位PE,完全满足SDM中对BSP初始化状态的要求),INIT-SIPI-SIPI的发送逻辑和BSP运行在32位保护模式还是64位长模式无关,流程本身是通用的。
问题2:BSP写入ICR后直接复位的根因分析与调试方案
你遇到的复位是典型的三重故障复位,触发原因是CPU执行movl $0xc4610,(%rax)时触发了未处理的异常,异常处理流程连续出错最终触发CPU自动复位。结合你给出的寄存器信息,优先排查以下几点:
- APIC MMIO地址的页表映射错误
APIC寄存器的MMIO区间是0xfee00000 ~ 0xfee01000,你需要检查长模式下的页表对这段地址的映射配置:
必须配置为恒等映射(虚拟地址等于物理地址)、必须设置正确的内存类型为不可缓存(UC)不能用普通可缓存内存的属性、必须开启可写权限。你给出的64位环境下CR4没有置位PSE,如果你用的是4K分页,确认对应PTE的属性配置正确,这是最高概率的故障点。 - APIC模式配置错误
确认你的代码没有将APIC从xAPIC模式切换到x2APIC模式,x2APIC模式下不再支持0xfee00000的MMIO访问方式,直接读写该地址会触发异常。
调试步骤参考:
- 先在长模式下注册简单的页错误、通用保护错误异常处理函数,在异常处理函数里加死循环,确认写入ICR时触发的异常类型,拿到错误码和故障地址
- 写入ICR之前先尝试读取APIC ID寄存器(地址
0xfee00020),如果读操作也触发异常,100%是MMIO映射的问题 - 对比32位环境下的MTRR配置,确认64位下
0xfee00000段的内存类型和32位一致
内容的提问来源于stack exchange,提问作者Eric Stdlib
相关产品推荐
相关产品推荐

