Page 1 of 1

Help with linking

Posted: Wed May 12, 2010 9:11 am
by DrOptix
Hi people!
I have a problem with link scripts because i don't really understand them.

I have this files:

boot.asm

Code: Select all

;Gloabal functions
global loader

;Extern functions
extern kmain

; Start loading our kernel
loader:

   call  kmain                       ; call kernel proper

   cli

hang:
   hlt                                ; halt machine should kernel return
   jmp   hang
 
; Padd with nulls and add boot sector signature
 times 510-($-$$) db 0
   db 0x55
   db 0xAA
kernel.c

Code: Select all

void kmain()
{
   // Print something
   unsigned char *videoram = (unsigned char *) 0xb8000;
   
   videoram[0] = 'D'; 
   videoram[1] = 0x07;
   videoram[2] = 'r';
   videoram[3] = 0x07;
   videoram[4] = '.';
   videoram[5] = 0x07;
   videoram[6] = 'O';
   videoram[7] = 0x07;
}
link.ld

Code: Select all

OUTPUT_FORMAT("binary")
ENTRY(loader)
phys = 0x00010000;
SECTIONS
{
  .text phys : AT(phys) {
    code = .;
    *(.text)
    *(.rodata)
    . = ALIGN(4096);
  }
  .data : AT(phys + (data - code))
  {
    data = .;
    *(.data)
    . = ALIGN(4096);
  }
  .bss : AT(phys + (bss - code))
  {
    bss = .;
    *(.bss)
    . = ALIGN(4096);
  }
  end = .;
}
to build this stuff i use this BAT file:

Code: Select all

i686-elf-gcc.exe -o .\bin\kernel.o -c kernel.c -nostdlib -nostartfiles -nodefaultlibs

nasm boot.asm -f elf -o .\bin\boot.o

i686-elf-ld -Tlink.ld -o .\bin\kernel.o bin\boot.o
So what is wrong? I ask because the linker complains about kmain not being referenced:

Code: Select all

D:\WorkStudio\Learn\OSDev_Setup\CustomMakefile>i686-elf-ld -Tlink.ld -o .\bin\kernel.o bin\boot.o 
bin\boot.o: In function `loader':
boot.asm:(.text+0x1): undefined reference to `kmain'
My current development environment is like this:
OS: Windows 7
Compilers:
C : mingw32-make, i686-elf gcc, ld (got it from here)
ASM: NASM

Any kind of help will pe apreciated! Thanx!
~Dr.Optix

Re: Help with linking

Posted: Wed May 12, 2010 9:39 am
by quok
Well, your linker line is all wrong. -o specifies what to name the output file. You're currently overwriting your kernel.o object file by using it as the output file!

Try this one, it should work: i686-elf-ld -Tlink.ld -o kernel.bin .\bin\boot.o .\bin\kernel.o

I've changed the order of the object files due to how LD links. It is a single pass linker by default, but you can change that by using the options --start-group and --end-group, but that also greatly increases link time.

Also, there's other potential problems with your code. You're not setting up a stack, entering protected mode, or setting any segment registers for a proper C environment. In short, while you should be able to get this code of yours to link, it's not going to work as you may expect. Take a look at our wiki. There's some great tutorials there that should help you get started.