Page 1 of 1

ld scripting question: arranging object files in exectuable

Posted: Tue Aug 09, 2011 12:17 am
by ethereal
Greetings, all!

I've been lurking around these forums for a while now, telling myself that one day I'll get around to trying to write my own toy operating system. I finally started earlier today, but I have encountered a small roadblock.

I'm experimenting with getting multiple source files to work properly. My problem: I have two source files, bootstrap.s and kmain.c. bootstrap.s contains my Multiboot header and program entry point (called bootstrap, imaginatively enough), kmain.c contains my kmain() function and some other assorted random stuff.

My problem: my generated kernel.bin file is >8KB now, with all my experimental code and global data. For some reason, the contents of bootstrap.o are placed after kmain.o (confirmed via a hex dump and search for the Multiboot magic string), and since kmain.o is more than 8KB . . . GRUB can't find the multiboot header.

From the ld documentation, I spotted STARTUP(), which appears to be what I am looking for in this case, but it appears to have no effect, whether it is placed at the top or bottom of the script.

I'm currently using the following linker script: (heavily plagiarized from the Wiki, apologies to the original authors . . .)

Code: Select all

OUTPUT_FORMAT(elf64-x86-64)
ENTRY(bootstrap)
STARTUP(bootstrap.o)
KERNEL_LMA = 0x100000;
KERNEL_VMA = 0x800000;

SECTIONS {
    . = KERNEL_LMA;

    .bootstrap : {
        bootstrap.o (.text)
        . = ALIGN(4096);
    }

    . = KERNEL_VMA;

    .text : AT(ADDR(.text) - KERNEL_VMA) {
        _code = .;
        *(EXCLUDE_FILE(*bootstrap.o) .text)
        *(.rodata*)
        . = ALIGN(4096);
    }

   .data : AT(ADDR(.data) - KERNEL_VMA) {
        _data = .;
        *(.data)
        . = ALIGN(4096);
   }

   .ehframe : AT(ADDR(.ehframe) - KERNEL_VMA) {
       _ehframe = .;
       *(.ehframe)
        . = ALIGN(4096);
   }

   .bss : AT(ADDR(.bss) - KERNEL_VMA) {
       _bss = .;
       *(.bss)
        *(COMMON)
       . = ALIGN(4096);
   }

   _end = .;

   /DISCARD/ : {
        *(.comment)
   }
}
What am I missing? I've searched the forums and OSDev wiki, tried a few Google queries, read the ld info page . . . but I haven't turned up anything useful (yet!). I apologize for asking such an inane question, but I confess that I have no remaining ideas.

My thanks in advance for any advice that can be given.

- ethereal

Re: ld scripting question: arranging object files in exectua

Posted: Tue Aug 09, 2011 1:08 am
by gerryg400
Is bootstrap.o the first file on your LD command line ? And have you defined the segment '.text' in your bootstrap.o ?

Re: ld scripting question: arranging object files in exectua

Posted: Tue Aug 09, 2011 1:10 am
by xenos
Typically, the easiest solution would be to place the multiboot header in its own section, and to place this section at the beginning of your linker script. For an example, have a look at Entry.S and ldscript from my kernel. I have a section named .mb_header which contains only the multiboot header, and which is included first in my linker script.

Another (very elegant) way of placing your multiboot header at the beginning of your kernel is to create it in the linker script. See this thread for an example.

Re: ld scripting question: arranging object files in exectua

Posted: Tue Aug 09, 2011 3:17 pm
by ethereal
Thank you, xenOS! Why didn't I think of moving the multiboot header into another section?

Regarding putting the multiboot header into the linker script: it seems to me that since the header directly affects what flags are in the multiboot information that GRUB2 will fill in, it ought to be in the same place as the code that uses said information. But then again, I am already hypocritical since the information will also be used in kmain() . . . I might just do that.

Thank you, again. I'll look at other people's OS source code next time before asking silly questions. :)

- ethereal

Re: ld scripting question: arranging object files in exectua

Posted: Wed Aug 10, 2011 8:27 am
by xenos
Actually I just changed my code so it uses the "linker script method" for writing the multiboot header :) I like it because it's very elegant and avoids the need for an extra section.