Page 1 of 2

LD : Entry point not at the beginning of the output file ?

Posted: Wed Apr 05, 2017 7:08 am
by Ankeraout
Hi,

I am currently writing my kernel in C, and compiling it with i686-elf toolchain, and until now I used to create "exhaustive object files list" in my makefile, like this :

Code: Select all

LD := i686-elf-ld
LDFLAGS := -Ttext 0x1000 --oformat binary -e _start
ASM := nasm
ASMFLAGS := -f elf
CC := i686-elf-gcc
CFLAGS := -Wall -Wextra -c -nostdlib -fno-builtin

all: kernel.bin

kernel.bin: bootstrp.o kernel.o gdt.o idt.o pic.o keyboard.o ps2.o disk.o interrupt.o mouse.o string.o screen.o isr.o
	$(LD) $(LDFLAGS) $^ -o $@
	
%.o: %.asm
	$(ASM) $(ASMFLAGS) $< -o $@
	
%.o: %.c
	$(CC) $(CFLAGS) $< -o $@
	
clean:
	rm kernel.bin *.o
It was working very well, despite the fact that I found it really dirty.
So today I decided to replace this list with wildcards, like this :

Code: Select all

LD := i686-elf-ld
LDFLAGS := -Ttext 0x1000 --oformat binary -e _start
ASM := nasm
ASMFLAGS := -f elf
CC := i686-elf-gcc
CFLAGS := -Wall -Wextra -c -nostdlib -fno-builtin
SRC_C := $(wildcard *.c)
SRC_ASM := $(wildcard *.asm)
OBJ := $(SRC_ASM:.asm=.o) $(SRC_C:.c=.o)

all: kernel.bin

kernel.bin: $(OBJ)
	$(LD) $(LDFLAGS) $^ -o $@
	
%.o: %.asm
	$(ASM) $(ASMFLAGS) $< -o $@
	
%.o: %.c
	$(CC) $(CFLAGS) $< -o $@
	
clean:
	rm kernel.bin *.o
The problem I encounter is that when bootstrp.o (which contains _start) is not the first file in the argument list of ld, my kernel does not start because the instructions at 0x1000 are not from bootstrp.o.

Here is the code of bootstrp.asm :

Code: Select all

; Multiboot bootstrap

global _start
extern Kernel_start

_start:
	jmp $ ;for debugging
	push ebx
	call Kernel_start
	
align 4
dd 0x1BADB002
dd 0x00000003
dd -(0x1BADB002 + 0x00000003)
And here is an extract of the disassembly of kernel.bin :

Code: Select all

00001740  EBFE              jmp short 0x1740
00001742  53                push ebx
00001743  E8D1E9FFFF        call dword 0x119
_start is located at 0x1740...

I don't know what I am doing wrong here, can somebody help me ?

Thanks by advance,
Ankeraout.

Re: LD : Entry point not at the beginning of the output file

Posted: Wed Apr 05, 2017 8:34 am
by LtG
Not an expert on the tools, but..

Did you read the barebones tutorial? Specifically http://wiki.osdev.org/Bare_Bones#Linking_the_Kernel?

Re: LD : Entry point not at the beginning of the output file

Posted: Wed Apr 05, 2017 8:46 am
by onlyonemac
I'm guessing the wildcard expansion is sorting the files in alphabetical order, and that that's the order they're being packed into the output file, which could put your entry point further into the file.

Re: LD : Entry point not at the beginning of the output file

Posted: Wed Apr 05, 2017 11:37 am
by dozniak
You need a linker script to put your objects in the right order.

onlyonemac is right about default make sorting of the object file list not matching the order you expect.

Re: LD : Entry point not at the beginning of the output file

Posted: Wed Apr 05, 2017 11:38 am
by zaval
open for yourself linker scripts.
put there something like this

Code: Select all

MEMORY{
	Sdram :	ORIGIN = SDRAM_START, LENGTH = SDRAM_LENGTH
}

PHDRS {
    image PT_LOAD;
}

ENTRY( _start )

SECTIONS{
    .text{
        bootstrp.o ( .text )
        *(.text)
    } >Sdram :image
}

Re: LD : Entry point not at the beginning of the output file

Posted: Wed Apr 05, 2017 2:53 pm
by Ankeraout
zaval wrote:open for yourself linker scripts.
put there something like this

Code: Select all

MEMORY{
	Sdram :	ORIGIN = SDRAM_START, LENGTH = SDRAM_LENGTH
}

PHDRS {
    image PT_LOAD;
}

ENTRY( _start )

SECTIONS{
    .text{
        bootstrp.o ( .text )
        *(.text)
    } >Sdram :image
}
I had to create my own script, but now it works !
Thank you all !

Re: LD : Entry point not at the beginning of the output file

Posted: Wed Apr 05, 2017 10:49 pm
by dchapiesky
Note that if you put a function above _start() in bootstrp.c that _start() will no longer be the first function in the executable...

just mentioning it cause that gave me a couple hours consternation...

Re: LD : Entry point not at the beginning of the output file

Posted: Thu Apr 06, 2017 4:00 am
by dozniak
dchapiesky wrote:Note that if you put a function above _start() in bootstrp.c that _start() will no longer be the first function in the executable...

just mentioning it cause that gave me a couple hours consternation...
IIRC you should be able to arrange layout down to function level, look in LD scripts section for exact syntax.

Re: LD : Entry point not at the beginning of the output file

Posted: Fri Apr 07, 2017 10:52 pm
by dchapiesky
dozniak wrote: IIRC you should be able to arrange layout down to function level, look in LD scripts section for exact syntax.
Yah.. true... Just mentioned because of his script...

Code: Select all

SECTIONS{
    .text{
        bootstrp.o ( .text )
        *(.text)
    } >Sdram :image
}

Re: LD : Entry point not at the beginning of the output file

Posted: Sat Apr 08, 2017 5:35 am
by zaval
^ that was just a quick example. But I can't imagine why one would need to put his/her start function NOT at the top of his/her start file. Why? For the life to not look that easy? xD

Re: LD : Entry point not at the beginning of the output file

Posted: Sat Apr 08, 2017 7:36 am
by dozniak
zaval wrote:^ that was just a quick example. But I can't imagine why one would need to put his/her start function NOT at the top of his/her start file. Why? For the life to not look that easy? xD
There's no direct correspondence between the top of C source and where it ends up in the object file. You may have it at the top of your source. It may end up being the last function in the .o after some other functions.

Re: LD : Entry point not at the beginning of the output file

Posted: Sat Apr 08, 2017 8:38 am
by zaval
right. except the file in question was from an assembly file.

Re: LD : Entry point not at the beginning of the output file

Posted: Mon Apr 10, 2017 5:29 am
by dozniak
zaval wrote:right. except the file in question was from an assembly file.
That doesn't matter too much. You could declare multiple functions in asm file as well.

Re: LD : Entry point not at the beginning of the output file

Posted: Mon Apr 10, 2017 7:17 am
by zaval
dozniak wrote:
zaval wrote: right. except the file in question was from an assembly file.
That doesn't matter too much. You could declare multiple functions in asm file as well.
If you put functions A, B, C in your assembly in that order, they remain in the same order in the output file. Linker won't reorder functions inside input sections. It operates on sections as units. Merging them into output sections. It doesn't change symbol positions inside a section. I don't remember anything about linker scripts where one could shuffle functions inside a section. Nor linker does so. Unless it is some weird link time optimization which I am not aware of.

Re: LD : Entry point not at the beginning of the output file

Posted: Mon Apr 10, 2017 11:00 am
by dozniak
zaval wrote: If you put functions A, B, C in your assembly in that order, they remain in the same order in the output file. Linker won't reorder functions inside input sections. It operates on sections as units. Merging them into output sections. It doesn't change symbol positions inside a section. I don't remember anything about linker scripts where one could shuffle functions inside a section. Nor linker does so. Unless it is some weird link time optimization which I am not aware of.
Thanks, but are you just trying to maintain discussion or want to get at something? I wrote linkers and have an idea how they work, thank you very much.