Page 1 of 1

LD not linking stuff in the correct order

Posted: Wed Oct 08, 2008 1:03 pm
by CodeCat
I made a few adaptions to the linker script in the barebones tutorial, so that the multiboot header is now a section of its own. However, when I build the kernel image, objdump reports that the .mbheader section is located after .text in the file even though the linker script says otherwise. It's not a problem now (kernel boots fine) but the multiboot spec says the header should be in the first 8 kB, so what if the text section grows beyond 8 kB? Is this a problem (and if so how do I fix it) or am I just being daft and not understanding the ELF format properly?

Linker script:

Code: Select all

ENTRY (_start)

SECTIONS{
    . = 0x00100000;
	
	.mbheader : {
		*(.mbheader)
	}
	
    .text : {
		*(.text.head)
        *(.text)
    }
	
    .rodata ALIGN (0x1000) : {
        *(.rodata)
    }
	
    .data ALIGN (0x1000) : {
        *(.data)
    }
	
    .bss : {
        sbss = .;
        *(.bss)
		*(COMMON)
        ebss = .;
    }
}
objdump -x output:

Code: Select all

build/kernel.bin:     file format elf32-i386
build/kernel.bin
architecture: i386, flags 0x00000112:
EXEC_P, HAS_SYMS, D_PAGED
start address 0x0010000c

Program Header:
    LOAD off    0x0000100c vaddr 0x0010000c paddr 0x0010000c align 2**12
         filesz 0x0000002c memsz 0x00004034 flags rwx

Sections:
Idx Name          Size      VMA       LMA       File off  Algn
  0 .mbheader     0000000c  00100000  00100000  00001038  2**2
                  CONTENTS, READONLY
  1 .text         0000002c  0010000c  0010000c  0000100c  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, CODE
  2 .bss          00004000  00100040  00100040  00001038  2**5
                  ALLOC
  3 .comment      00000012  00000000  00000000  00001044  2**0
                  CONTENTS, READONLY
SYMBOL TABLE:
00100000 l    d  .mbheader      00000000 .mbheader
0010000c l    d  .text  00000000 .text
00100040 l    d  .bss   00000000 .bss
00000000 l    d  .comment       00000000 .comment
00000001 l       *ABS*  00000000 ALIGN
00000002 l       *ABS*  00000000 MEMINFO
00000003 l       *ABS*  00000000 FLAGS
1badb002 l       *ABS*  00000000 MAGIC
e4524ffb l       *ABS*  00000000 CHECKSUM
00004000 l       *ABS*  00000000 STACKSIZE
00000000 l    df *ABS*  00000000 main.cpp
00100040 g       .bss   00000000 sbss
00100040 g     O .bss   00004000 stack
0010000c g       .text  00000000 _start
00104040 g       .bss   00000000 ebss
0010001c g     F .text  0000001c kmain

Re: LD not linking stuff in the correct order

Posted: Wed Oct 08, 2008 4:10 pm
by Combuster
objdump reports that the .mbheader section is located after .text
00100000 .mbheader
0010000c .text
Right.....

Maybe try turning your screen the right side up and not look at the size #-o

Re: LD not linking stuff in the correct order

Posted: Wed Oct 08, 2008 5:58 pm
by mystran
I would actually put the .mbheader inside the final .text segment, just the first thing there.. but maybe that's just me..

Re: LD not linking stuff in the correct order

Posted: Wed Oct 08, 2008 6:43 pm
by CodeCat
I was referring to the file offsets actually (1038 and 100c). Those are what GRUB looks for, not the load addresses.
An OS image must contain an additional header called Multiboot header, besides the headers of the format used by the OS image. The Multiboot header must be contained completely within the first 8192 bytes of the OS image, and must be longword (32-bit) aligned.
I interpret that to mean the first 8k of the file, not the first 8k of the loaded kernel. After all, why would GRUB go through all the trouble of mapping ELF sections before it even knows whether the kernel is properly bootable or not?

Putting it in .text does work, but why doesn't it work otherwise?