Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
I have implemented the MP spec 1.4 and have all my AP's running the trampoline. I put it at physical 0x00000000 and have everything started there.
The AP's enter there in 16bit realmode, and i setup a temp gdt (idmapped) and set AP in pmode.
Now everything should be ready for doing the last bit. That last bit of course need calling a 32bit function that is part of the linked kernel.. Here is my problem.. I cannot link this 16bit code together with the 32bit code.. So i wonder, maby i should solve this totally different.. I just cannot see a nice way to do this yet...
Basically whats needed further is loading the TSS for each AP, then loading the IDT and GDT (shared between all cpus) and then calling the dispatcher to jump to AP idle thread..
What you can do, is create some position-independent (or with hardcoded addresses) code in assembly, so that it has no relocations that could mess up linking. By adding a symbol for the start and end, you can copy the binary blob at runtime to the desired location before bootstrapping the APs with it.
Of course you could mess a whole lot with linker scripts...
"Certainly avoid yourself. He is a newbie and might not realize it. You'll hate his code deeply a few years down the road." - Sortie
[ My OS ] [ VDisk/SFS ]
I was thinking about doing special/nasty stuff with ld script, variables etc.
I ended actually up with jumping the AP to 0x100000 from the trampoline (same as kernel start asm stub). Did a bit toggle stuff there so that after BSP has booted the AP's will go trough all the same pagedir setup etc, and then jump to a special C function that detects cpu number, loads apropriate tss, and then kicks of the interrupt dispatch routine.. Now i only need to expand my gdt with some more tss'es and then i can remove the HLT before ltr and the iret Hopefully everything will work just nice
I have a small piece of ("position independent") 16-bit assembly that I copy to a (dynamically allocated) page below 0x00100000. Then I set a few variables inside this page (a GDTR, address of page allocated for the AP CPU's stack, address for the AP CPU to jump to once it's in protected mode, etc). When the AP CPU starts it loads the GDT, enables protected mode, sets it's SS:ESP, and does a "jmp far" to wherever it's told.
Probably the only tricky part is realising that when the AP CPUs starts, CS points to the trampoline code; so the trampoline code can use CS to access the variables that are stored in the same page. For an example "o32 lgdt [cs:TRAMPOLINE_GDTR - TRAMPOLINE_START]".
Cheers,
Brendan
For all things; perfection is, and will always remain, impossible to achieve in practice. However; by striving for perfection we create things that are as perfect as practically possible. Let the pursuit of perfection be our guide.