Page 1 of 1
Linking error
Posted: Sun Jan 28, 2007 9:28 am
by manutd
I've been following the instructions on
thispage, with one change: I used the NASM version instead of the gas version. It all built fine, but when I try to link, ld gives this error:
ld -T linker.ld loader.o kernel.o
loader.o: In function 'loader':
%path_to_project%/loader.asm:(.text+0x14): undefined reference to 'main'
Any ideas? What am I doing wrong?
Posted: Sun Jan 28, 2007 11:06 am
by Brynet-Inc
There is a good chance is has to do with adding an underscore into the loader.asm file.. _main instead of main.
I think GCC on some targets likes to append an underscore to function names.
It'd be more helpful if you posted the contents of those files.
(BTW - use the new wiki..
http://www.osdev.org/wiki/)
Posted: Mon Jan 29, 2007 6:26 am
by manutd
I even changed it to kmain in both files, it still didn't work.
Contents - kernel.c:
Code: Select all
void _main (void* mbd, unsigned int magic)
{
}
Contents - loader.asm:
Code: Select all
global _loader ; making entry point visible to linker
extern _main ; _main is defined elsewhere
; setting up the Multiboot header - see GRUB docs for details
MODULEALIGN equ 1<<0 ; align loaded modules on page boundaries
MEMINFO equ 1<<1 ; provide memory map
FLAGS equ MODULEALIGN | MEMINFO ; this is the Multiboot 'flag' field
MAGIC equ 0x1BADB002 ; 'magic number' lets bootloader find the header
CHECKSUM equ -(MAGIC + FLAGS) ; checksum required
section .text
align 4
MultiBootHeader:
dd MAGIC
dd FLAGS
dd CHECKSUM
; reserve initial kernel stack space
STACKSIZE equ 0x4000 ; that's 16k.
_loader:
mov esp, stack+STACKSIZE ; set up the stack
push eax ; pass Multiboot magic number
push ebx ; pass Multiboot info structure
call _main ; call kernel proper
hlt ; halt machine should kernel return
section .bss
align 32
stack:
resb STACKSIZE ; reserve 16k stack on a quadword boundary
Contents - linker.ld:
Code: Select all
ENTRY (_loader)
SECTIONS
{
. = 0x00100000;
.text :
{
*(.text)
}
.rodata ALIGN (0x1000) :
{
*(.rodata)
}
.data ALIGN (0x1000) :
{
*(.data)
}
.bss :
{
_sbss = .;
*(COMMON)
*(.bss)
_ebss = .;
}
}
That's it!
Posted: Mon Jan 29, 2007 6:47 am
by Solar
The point Brynet-Inc had been trying to make is that, depending on configuration, GCC might or might not add underscores to symbols. Your _main from kernel.c might have become __main in the compiling.
Try objdump -D on your object files to find out which part of your toolchain (GCC / NASM) is doing what, then set -fleading-underscore or -fno-leading-underscore accordingly to make your GCC and NASM follow the same convention.
Posted: Tue Jan 30, 2007 6:28 am
by manutd
Neither option works, and it also doesn't work when I rename _main to kmain.
Posted: Tue Jan 30, 2007 9:02 am
by Otter
Have you tried objdump to find the mistake ? I would suggest to use nm:
You'll get a list of symbols including all underscores and so on. Search your main or kmain and you'll see to what gcc changes its name.
Posted: Tue Jan 30, 2007 6:17 pm
by manutd
Thank you so much, gcc was appending an extra _, making it __main. Problem solved!