Calling Global Constructors: Difference between revisions

m
Add warnings against using the wrong link order
[unchecked revision][unchecked revision]
(Add 32-bit information)
m (Add warnings against using the wrong link order)
Line 17:
i585-elf-ld crt0.o crti.o crtbegin.o foo.o bar.o crtend.o crtn.o
 
The idea is that the these files toggether form _init and _fini functions during the linking. This is done by storing the _init function in the .init section, and the _fini function in the .fini section. Each file then contributes a bit to these sections and the linker makes glues together the fragments in the code specified on the command line. crti.o provides the function header, crtbegin.o and crtend.o provide the body, and crtn.o provide the footer (return statement). It is important to understand that the link order matters and strange things may happen if the objects is not exactly linked in this order.
 
== Using global constructors from C ==
Line 65:
rm -f mykernel.bin $(INTERNAL_OBJS)
</source>
 
It is important to remember that the objects must be linked in this exact order, or you will experience strange bugs.
 
Your kernel will then have an _init and a _fini function linked in, which can be called from your boot.o (or what your kernel entry point object is called) before passing control to kmain (or what your kernel main routine is called). Please note that the kernel may not be initialized, at all, at this point in time and you can only do trivial things from your global constructors. In addition, _fini may not ever get called because your operating system will remain running, and when it is time to shut down, there is little worth doing that a processor reset won't do. It may be worth setting up a kmain_early function that initializes the heap, the log, and other core kernel features. Then your boot.o can call kmain_early, then call _init, and then finally pass control to the real kmain. This is analogous to how things work in user-space, where crt0.o calls _initialize_c_library (or what you call it), then _init, and finally exit(main(argc, argv)).
Anonymous user