我的目标是让我自己的内核启动一个应用程序cpu。它使用与linux kernel相同的机制。 :
- 发送断言和电平触发的 init-IPI
- 等等...
- 发送取消断言和电平触发的 init-IPI
- 等等...
- 发送最多两个启动 IPI, vector 编号为
(0x40000 >> 12)
(应用处理器的入口代码位于此处)
目前我只是想让它与 QEMU 一起工作。不幸的是,应用程序 CPU 没有跳转到 0x40000
,而是跳转到 0x0
,并将 cs
寄存器设置为 0x4000
。 (我用 gdb 检查过)。
Intel MultiProcessor Specification (B.4.2) 解释了如果目标处理器在 RESET 或 INIT 之后立即停止,我注意到的行为是有效的。但这不应该也适用于linux内核的代码吗?它在 init-IPI 之后发送startup-IPI。或者我误解了规范?
如何才能使应用处理器跳转到 0x000VV000
而不是 0x0
,并将 cs
寄存器设置为 0xVV00
?我真的看不出 linux 在哪里做了一些改变行为的事情。
最佳答案
看来我真的误解了规范:由于应用程序cpu是以实模式启动的,0x000VV000
相当于0xVV00:0x0000
。仅用 16 位 ip 寄存器来表示地址是不可能的。因此需要代码段的段偏移量。
此外,使用 gdb 调试实模式代码相当复杂,因为它不考虑段偏移量。当需要查看当前位置蹦床的反汇编代码时,需要计算物理位置:
x/20i $eip+0xVV000
这使得 gdb 在 0xVV00:$eip
打印接下来的 20 条指令。
关于c - 如何正确使用startup-ipi来启动应用处理器?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23962839/