如何正确使用startup-ipi启动应用程序处理器?

时间:2014-05-30 20:23:00

标签: c linux-kernel x86 intel smp

我的目标是让我自己的内核启动一个应用程序cpu。它使用与linux kernel

相同的机制
  • 发送断言和级别触发的init-IPI
  • 等待...
  • 发送取消断言和级别触发的init-IPI
  • 等待...
  • 发送最多两个带有向量编号(0x40000 >> 12)的启动IPI(应用程序处理器的入口代码位于那里)

目前我只对将其与QEMU合作感兴趣。不幸的是,应用程序cpu跳转到0x40000而不是跳转到0x0,而cs寄存器设置为0x4000。 (我用gdb检查过。)

Intel MultiProcessor Specification(B.4.2)解释说,如果目标处理器在RESET或INIT之后立即停止,我注意到的行为是有效的。但是这不应该也适用于linux内核的代码吗?它在init-IPI之后发送启动IPI。或者我是否误解了规范?

如果0x000VV000寄存器设置为0x0,应用处理器是否可以跳转到cs而不是0xVV00?我真的看不到,linux在哪里做了改变行为的事情。

1 个答案:

答案 0 :(得分:4)

似乎我真的误解了规范:由于应用程序cpu以实模式启动0x000VV000等同于0xVV00:0x0000。只能在16位ip寄存器中表示地址是不可能的。因此,需要代码段的段偏移量。

此外,使用gdb调试实模式代码相当复杂,因为它不考虑段偏移。当需要在当前位置查看蹦床的反汇编代码时,有必要计算物理位置:

x/20i $eip+0xVV000

这使得gdb在0xVV00:$eip打印了接下来的20条指令。