Page 1 of 1

OSDev with 64-bit C++

Posted: Sat Oct 24, 2009 5:35 am
by Creature
Hello,

I recently started messing around with 64-bit OSDev. I managed to get into my C/C++ entry point just fine. The only question I have is how does 64-bit relate to calling global/static constructors from the linker script and the compiler-dependencies? In my current OS (32-bit), I have pretty much everything necessary to run C++ (according to our wiki article), including the looping of the static/global constructors. However, now I am in 64-bit, I'm wondering when I should loop the constructors (in 32-bit mode, or 64-bit mode?) and better: are the addresses I grab from the linker script with the EXTERN directive now 64-bits (i.e. must I use 64-bit registers for it now?).

Last but not least: I was wondering if any of the other dependencies, such as the Stack-Smashing Protector and the __dso_handle, are different in 64-bits? Are there any other pitfalls I should watch out for in 64-bit C++?

Thanks in advance,
Creature

Re: OSDev with 64-bit C++

Posted: Sat Oct 24, 2009 12:24 pm
by tantrikwizard
static c++ initialization must be done by you. It's often handled in crt0.c or similar. I'm not sure about gcc, but with M$ VC++ and Watcom, these compilers put all the static initializers in a special code segment. Your crt0 implementation would begin iterating through and calling the function pointers that the compiler/linker placed in the static init code segment. Take a look at your compiler's crt0 or similar for some ideas.

Re: OSDev with 64-bit C++

Posted: Sat Oct 24, 2009 12:41 pm
by Creature
tantrikwizard wrote:static c++ initialization must be done by you. It's often handled in crt0.c or similar. I'm not sure about gcc, but with M$ VC++ and Watcom, these compilers put all the static initializers in a special code segment. Your crt0 implementation would begin iterating through and calling the function pointers that the compiler/linker placed in the static init code segment. Take a look at your compiler's crt0 or similar for some ideas.
Yes, I know how it's done (it uses the ctor section in the linker script), but I was wondering if it's different in 64-bit C++ than it is in 32-bits C++. I got it working just fine in 32-bits, but 64-bits is apparently different (it's apparently not as simple as just using a 64-bit general purpose register and calling the addresses anymore).

Re: OSDev with 64-bit C++

Posted: Sat Oct 24, 2009 12:51 pm
by Cognition
The simple answer to your questions is yes, they should be 64 bit values. As for big pitfalls, the biggest one I'd say is to be aware that arguments are passed much different then they are on a standard x86 machine, it's covered in the x86-64 ABI if you don't have a copy yet. Segmentation changes dramatically as does the TSS segment and IDT table entries to an extent. And virtual 8086 mode is no longer supported if you have code that uses it. I don't know how far along you are but paging structures are a bit more complicated in 64-bit mode as well (not very much more though). If your code is well written and doesn't assume a lot about the size of a pointer then most of it should transfer over quite well.

Re: OSDev with 64-bit C++

Posted: Sat Oct 24, 2009 12:52 pm
by tantrikwizard
Well, the static init doesn't neccessarily have to be performed at the very beginning of the kernel, it just needs to be called at some point before it's dependencies are used. It sounds like the init functions are being called from ASM, can you call them from within a C function instead? It will prob be a bit more portable if it goes that route too.