Page 1 of 1

Problem linking kernel.o and loader.o

Posted: Sun Jan 18, 2009 12:47 pm
by abachler
Im using GCC and getting an error linking, I am using the barebones code verbatum, I searched and every post says its because I need to set up a cross compiler, but I already have a cross compiler set up...

loader.o: In function 'loader':
loader.s: (.text+0x14): undefined reference to 'kmain'

Code: Select all

nasm -f elf -o loader.o loader.s  
gcc -o kernel.o -c kernel.cpp -Wall -Wextra -Werror -nostdlib -nostartfiles -nodefaultlibs  
ld -T linker.ld -o kernel.bin kernel.o loader.o

Re: Problem linking kernel.o and loader.o

Posted: Sun Jan 18, 2009 12:54 pm
by Hangin10
Either add an underscore before kmain in the assembly file, or add -fno-leading-underscore to the flags to GCC.

Re: Problem linking kernel.o and loader.o

Posted: Sun Jan 18, 2009 1:13 pm
by abachler
I tried -

Code: Select all

extern _kmain
call _kmain
same result

Code: Select all

extern __kmain
call __kmain
same result

Code: Select all

gcc -fno-leading-underscore -o kernel.o -c kernel.c -Wall -Wextra -Werror -nostdlib -nostartfiles -nodefaultlibs
with both of the above and plain kmain, same result

Re: Problem linking kernel.o and loader.o

Posted: Sun Jan 18, 2009 1:30 pm
by Creature
Can you show us your code? Try putting loader.o before kernel.o by the way (if your OS uses GRUB), because the file with the multi-boot header should be one of the first files to be linked.

Re: Problem linking kernel.o and loader.o

Posted: Sun Jan 18, 2009 1:31 pm
by piranha
If you tell it (gcc) to use no leading underscores, then maybe not using a leading underscore in the call would work, hmm?

Edit: Nvmd, didnt read the footnote at the bottom of your post...

-JL

Re: Problem linking kernel.o and loader.o

Posted: Sun Jan 18, 2009 3:39 pm
by Combuster
Have you checked that you actually use the crosscompiler and not your system's stock gcc?
(try calling i586-elf-gcc and i586-elf-ld)

Re: Problem linking kernel.o and loader.o

Posted: Sun Jan 18, 2009 3:40 pm
by abachler
Creature wrote:Can you show us your code? Try putting loader.o before kernel.o by the way (if your OS uses GRUB), because the file with the multi-boot header should be one of the first files to be linked.
I copied and pasted the code in http://wiki.osdev.org/Bare_bones

updating cygwin now, as soon as it finishes Ill double check that its using the right gcc, I suspect that may be the problem as i586-elf-gcc doesnt exist in my install of gcc

well, even after updating cygwin I dont have that file, or the i686 equivelant, all I have is i686-pc-cygwin-gcc, which gives me the saem error as before.

whoever thought the hardest part of writing an OS would be setting up the toolchain...

turns out, a friend on another site suggested runnign nm kernel.o, and it turns out the compiler is mangling the name fo the function to __Z5kmainv, so after changing the references to that it linked just fine.

Re: Problem linking kernel.o and loader.o

Posted: Tue Jan 20, 2009 7:40 am
by Hyperdrive
abachler wrote:turns out, a friend on another site suggested runnign nm kernel.o, and it turns out the compiler is mangling the name fo the function to __Z5kmainv, so after changing the references to that it linked just fine.
Seems you're putting your file through g++, which does name mangling.

Try adding

Code: Select all

extern "C"
in front of your function. So it will look like this:

Code: Select all

extern "C"
void kmain( void* mbd, unsigned int magic )
{ ....
That turns off the name mangling for kmain.

Regards,
Thilo

Re: Problem linking kernel.o and loader.o

Posted: Thu Feb 12, 2009 7:42 am
by sirprize
Hi Thilo,

I just ran into this exact problem. Thanks for your post, I wasn't aware of the fact that g++ does name mangling. With extern "C" decalaration it works well.

Regards,
Michael

Re: Problem linking kernel.o and loader.o

Posted: Fri Feb 13, 2009 3:17 pm
by xlq
All C++ compilers do name mangling. It's how it solves operator overloading and scoping issues.

Re: Problem linking kernel.o and loader.o

Posted: Sat Feb 14, 2009 6:10 am
by unplygOS
I found that if I have

Code: Select all

 extern kmain
call kmain
in boot.s
and

Code: Select all

void kmain( void* mbd, unsigned int magic )
in kernel.c
and follow the rest of the tutorial. Of course you could always add an underscore to kmain. It worked for me.

Re: Problem linking kernel.o and loader.o

Posted: Sat Feb 14, 2009 6:38 am
by xlq
unplygOS wrote:I found that if I have

Code: Select all

 extern kmain
call kmain
in boot.s
and

Code: Select all

void kmain( void* mbd, unsigned int magic )
in kernel.c
and follow the rest of the tutorial. Of course you could always add an underscore to kmain. It worked for me.
Yes, but was your kernel C or C++? There's a big difference.

With the underscore, I'd prefer to get the compiler to output the proper symbol names, (-fno-leading-underscore) rather than putting the underscores in your assembly code.