Page 1 of 1

Going from C Bare Bones to C++ Bare Bones

Posted: Tue Oct 26, 2010 3:27 pm
by opengeek
I have some questions about the process.

When you finish the C Bare Bones kernel (http://wiki.osdev.org/Bare_bones) you have 3 files:

linker.ld -> which is the script that tells linker how to link different object code sections

loader.s -> written in gas (in my case) which passes the control from bootloader to kernel main function initializin kernel stack and other things.

kernel.c -> kernel main function

Then I'm following the C++ Bare Bones Kernel Tutorial (http://wiki.osdev.org/C%2B%2B_Bare_Bones)

I need to override my linker.ld from de C with the C++ (without forgeting the ENRTY (loader) ) one that defines extra rules to link constructor and destructor sections of the ELF and GNU soft linking. Untill here everything is fine.

Then the wiki talks about constructors and destructors and that in C++ you must call a constructor before you use an object and the destructor when you don't need the object any more, and after that you give some sample code.
I have some questions about de C/C++ code, i write it inline:

extern start_ctors, end_ctors, start_dtors, end_dtors;
//my compiler says me that all variables declared in extern have no type

void loader(void)
{
//- call all the static constructors in the list.
//I do not understand where and why this list exists if we need an object I will construt it when we need it
for(unsigned long *constructor(&start_ctors); constructor < &end_ctors; ++constructor)
((void (*) (void)) (*constructor)) ();

//- call kernel proper
main();
//I supose here we have to pass the struct mb_header *header, unsigned magic parameters, but I need the *header //and magic but I don't no from where I get them, I need to use a multiboot.h file or something?

//- call all the static destructors in the list.
//I do not understand where and why this list exists if I don't need an object I will destroy it.
for(unsigned long *destructor(&start_dtors); destructor < &end_dtors; ++destructor)
((void (*) (void)) (*destructor)) ();
}

Thank you for solving my n00b doubts.

Re: Going from C Bare Bones to C++ Bare Bones

Posted: Tue Oct 26, 2010 5:09 pm
by KotuxGuy
Try putting your code in code tags(look under "Post a reply"). That makes it easier for us to see your code.
Also, try adding a few crucial spaces between your source code lines. That would help, too.

Re: Going from C Bare Bones to C++ Bare Bones

Posted: Tue Oct 26, 2010 5:44 pm
by HitmanYesman
You can't extern variables without defining their type first. So for example you could do:

Code: Select all

extern unsigned int start_ctors, end_ctors, start_dtors, end_dtors;
Well, as for objects. I think you need to read up more on C++. But here's how it is simply. The linker combines all the constructors into one section and all the deconstructors in a different section. You have to call these sections. But you must also define their place in the linker script, since you are using a custom one.

And if you followed the Bare Bones tutorial right, it boots off of GrUB to a loader.s file passing the parameters with it by pushing them onto the stack. Then, the kmain function takes the parameters.

Re: Going from C Bare Bones to C++ Bare Bones

Posted: Wed Oct 27, 2010 2:13 am
by qw
HitmanYesman wrote:The linker combines all the constructors into one section and all the deconstructors in a different section. You have to call these sections. But you must also define their place in the linker script, since you are using a custom one.
Actually, GCC puts pointers to the constructors in one section called ".ctors" and pointers to the destructors in one section called ".dtors".

So you could treat "start_ctors" and "start_dtors" as arrays of pointers to functions:

Code: Select all

extern void (*start_ctors[])(void);
But beware, some linker scripts put a null value or the number of pointers in start_ctors[0].

In a hosted environment, the constructors in the array are called by a function named "__main". I believe it is in crt0.o or perhaps in libgcc.a, I'm not sure.

Re: Going from C Bare Bones to C++ Bare Bones

Posted: Wed Oct 27, 2010 4:21 am
by gravaera
Hi:
Hobbes wrote:But beware, some linker scripts put a null value or the number of pointers in start_ctors[0].
DJGPP does that: no modern enough version of GCC should. It's easy enough to write a compiler abstraction layer anyway.

--All the best,
gravaera.

Re: Going from C Bare Bones to C++ Bare Bones

Posted: Wed Oct 27, 2010 5:12 am
by Solar
In a hosted environment (i.e., userspace programming), global / static objects are constructed before main() is entered.

This - as well as other housekeeping things, like setting up a stack, putting argc and argv on that stack etc. - is done by the "C runtime environment" (crt0.o on Unix machines), a small piece of code that is added to all executables by the compiler automatically. (The real entry point into a userspace executable is signified by the symbol _start, not main(). That's the entry function of crt0.o.)

In a freestanding environment (i.e., kernel programming), you don't have a crt0.o, and anyways you are using a custom linker script (among other reasons, so you can define which function is called as entry, and to avoid complaints about crt0.o missing - because a cross-compiler doesn't have one by default).

Thus, it falls upon you to do those things usually done by the runtime. Sooner or later you will write your version of crt0.o, but that will be for userspace applications, since the kernel init phase is different.

It actually gets less confusing if you do it in Assembler, IMHO. Having the stack set up, global / static objects constructed and the parameters (magic number, Multiboot data structure pointer) on the stack already before you enter C++ source.

Re: Going from C Bare Bones to C++ Bare Bones

Posted: Wed Oct 27, 2010 6:04 am
by qw
gravaera wrote:DJGPP does that: no modern enough version of GCC should. It's easy enough to write a compiler abstraction layer anyway.
So does MinGW.

Re: Going from C Bare Bones to C++ Bare Bones

Posted: Wed Oct 27, 2010 6:07 am
by Combuster
And who is in control of the linker script? :wink:

Edit: 5000 posts! :D

Re: Going from C Bare Bones to C++ Bare Bones

Posted: Wed Oct 27, 2010 1:58 pm
by qw
Combuster wrote:And who is in control of the linker script? :wink:
The forces of darkness. Who else?
Combuster wrote:Edit: 5000 posts! :D
Wow! Congratulations!