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?
Linking error
- Brynet-Inc
- Member
- Posts: 2426
- Joined: Tue Oct 17, 2006 9:29 pm
- Libera.chat IRC: brynet
- Location: Canada
- Contact:
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/)
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/)
I even changed it to kmain in both files, it still didn't work.
Contents - kernel.c:
Contents - loader.asm:
Contents - linker.ld:
That's it!
Contents - kernel.c:
Code: Select all
void _main (void* mbd, unsigned int magic)
{
}
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
Code: Select all
ENTRY (_loader)
SECTIONS
{
. = 0x00100000;
.text :
{
*(.text)
}
.rodata ALIGN (0x1000) :
{
*(.rodata)
}
.data ALIGN (0x1000) :
{
*(.data)
}
.bss :
{
_sbss = .;
*(COMMON)
*(.bss)
_ebss = .;
}
}
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.
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.
Every good solution is obvious once you've found it.
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.
Code: Select all
$ nm kernel.o