multi-core initialization -- 16/32 bit issues
Posted: Mon Jun 27, 2016 5:41 pm
Hi
I have implemented multi-core initialization and managed to get my APs (application processors) into their real mode boot code. I did this by:
a) copying the AP boot code down below 1Mb (to address 0x1000)
b) then going through the whole SIPI initialization steps
My APs all get to their real mode boot code just fine -- i.e. they are running the code I copied down to below 1Mb.
Now comes the part that has me stumped -- how to get my APs out of real mode and into protected mode (I know how to get out of real mode and into protected mode in general but not in this instance -- read on).
I am using Grub2 as my boot loader, so I far as I understand things I cannot include any 16 bit code in the OS binary (when I do include 16 bit code Grub 2 refuses to load my OS code).
So my AP real mode boot code looks like this (I have questions about the ??? parts).
.code16
startAP:
lgdt ????
movl %cr0, %eax
orl 0x1, %eax
movl %eax, %cr0
ljmp 0x8, ???
I have included this code in my 32-bit OS binary using .incbin -- so I compiled it as a 16-bit raw binary and then I include it as raw bytes using .incbin.
Usually you would put some labels in for the ??? parts, and the linker would relocate, and it would work just great. But I can't do that since my code is not linked -- it is loaded via .incbin -- effectively as data.
So I did the following:
a) copied this code below 1Mb (to address 0x1000)
b) put a descriptor table at 0x2000,
c) put the address of my protected mode code at 0x3000.
My two questions are then:
a) how do I load the gdt with 0x2000 -- the location of my AP gdt? I want to simply do something like
lgdt $0x2000
But that didn't work (using gcc as my assembler).
b) How do I far jump to the address in location 0x300?.
It feels like I might be going about this the wrong way, but I haven't programmed in assembler since my days hacking around on PDP-11 device drivers!
thanks
graham
I have implemented multi-core initialization and managed to get my APs (application processors) into their real mode boot code. I did this by:
a) copying the AP boot code down below 1Mb (to address 0x1000)
b) then going through the whole SIPI initialization steps
My APs all get to their real mode boot code just fine -- i.e. they are running the code I copied down to below 1Mb.
Now comes the part that has me stumped -- how to get my APs out of real mode and into protected mode (I know how to get out of real mode and into protected mode in general but not in this instance -- read on).
I am using Grub2 as my boot loader, so I far as I understand things I cannot include any 16 bit code in the OS binary (when I do include 16 bit code Grub 2 refuses to load my OS code).
So my AP real mode boot code looks like this (I have questions about the ??? parts).
.code16
startAP:
lgdt ????
movl %cr0, %eax
orl 0x1, %eax
movl %eax, %cr0
ljmp 0x8, ???
I have included this code in my 32-bit OS binary using .incbin -- so I compiled it as a 16-bit raw binary and then I include it as raw bytes using .incbin.
Usually you would put some labels in for the ??? parts, and the linker would relocate, and it would work just great. But I can't do that since my code is not linked -- it is loaded via .incbin -- effectively as data.
So I did the following:
a) copied this code below 1Mb (to address 0x1000)
b) put a descriptor table at 0x2000,
c) put the address of my protected mode code at 0x3000.
My two questions are then:
a) how do I load the gdt with 0x2000 -- the location of my AP gdt? I want to simply do something like
lgdt $0x2000
But that didn't work (using gcc as my assembler).
b) How do I far jump to the address in location 0x300?.
It feels like I might be going about this the wrong way, but I haven't programmed in assembler since my days hacking around on PDP-11 device drivers!
thanks
graham