My goal is to let my own kernel start an application cpu. It uses the same mechanism as the linux kernel:
(0x40000 >> 12)
(the entry code for the application processor lies there)Currently I'm just interested in making it work with QEMU. Unfortunately, instead of jumping to 0x40000
, the application cpu jumps to 0x0
with the cs
register set to 0x4000
. (I checked with gdb).
The Intel MultiProcessor Specification (B.4.2) explains that the behavior that I noticed is valid if the target processor is halted immediately after RESET or INIT. But shouldn't this also apply to the code of the linux kernel? It sends the startup-IPI after the init-IPI. Or do I misunderstand the specification?
What can I do to have the application processor jump to 0x000VV000
and not to 0x0
with the cs
register set to 0xVV00
? I really can't see, where linux does something that changes the behavior.
It seems that I really misunderstood the specification: Since the application cpu is started in real mode 0x000VV000
is equivalent to 0xVV00:0x0000
. It is not possible to represent the address just in the 16 bit ip
register. Therefore a segment offset for the code segment is required.
Additionally, debugging real mode code with gdb is comparable complicated because it does not respect the segment offset. When required to see the disassembled code of the trampoline at the current position, it is necessary to calculate the physical location:
x/20i $eip+0xVV000
This makes gdb print the next 20 instructions at 0xVV00:$eip
.