Page 1 of 1

compile user program for my os

Posted: Fri Aug 12, 2016 10:31 pm
by szhou42
I am writing a simple elf loader, in order to test it, I compile a program with i686-elf-gcc for my os (to test my elf loader). But it wouldn't compile.

Code: Select all

int main() {
    int a = 0;
    a++;
    return 0;
}

Code: Select all

vagrant@vagrant-ubuntu-trusty-32:~/test$ i686-elf-gcc umain.c
/home/vagrant/opt/cross/lib/gcc/i686-elf/4.8.4/../../../../i686-elf/bin/ld: cannot find crt0.o: No such file or directory
/home/vagrant/opt/cross/lib/gcc/i686-elf/4.8.4/../../../../i686-elf/bin/ld: cannot find -lc
collect2: error: ld returned 1 exit status
Then I tried compiling with the normal gcc on my machine.
This time my elf loader successfully loads the executable and start executing(I guess a normal c program always starts with the C run time code), but it triggers an exception at a jmp instruction

Code: Select all

0x080482c6 in ?? ()
=> 0x80482c6:	jmp    *0x804a008      // *0x804a008 is equal to 0, so exception occurs here
   0x80482cc:	add    %al,(%eax)
   0x80482ce:	add    %al,(%eax)
   0x80482d0:	jmp    *0x804a00c
   0x80482d6:	push   $0x0
   0x80482db:	jmp    0x80482c0
   0x80482e0:	jmp    *0x804a010
   0x80482e6:	push   $0x8
   0x80482eb:	jmp    0x80482c0
   0x80482f0:	xor    %ebp,%ebp
(gdb)
0x00000000 in ?? ()
=> 0x0:	Cannot access memory at address 0x0
(gdb) x/1x 0x804a008
0x804a008:	0x00000000
Now that I can't use the i686-elf-gcc nor the normal gcc to compile programs for my os, what should I do ?
There is a tutorial that teaches how to build a compiler to do that http://wiki.osdev.org/OS_Specific_Toolchain
I guess at the end I will get a compiler that targets my os. but I want to understand, why i686-elf-gcc wouldn't compile it for me?
I am now very confused about these compiler-os relationship stuff, can someone clarify for me ?

Thanks in advance.

Re: compile user program for my os

Posted: Sat Aug 13, 2016 4:49 am
by Roman
You can compile it with i686-elf, but without a runtime. Simply add -nostartfiles and specify the entry point. Maybe you need to use position-independent code or a linker script, but that depends on your OS specifics.

Re: compile user program for my os

Posted: Sat Aug 13, 2016 5:01 am
by Ch4ozz
You have to compile it with

Code: Select all

-nostdinc -fno-builtin
Exactly like your OS should be compiled too.
We dont want some random OS dependent CRT code inside the executable since we build our own OS here and there is of course
no available CRT for it (except you port the library to your OS)

Re: compile user program for my os

Posted: Sat Aug 13, 2016 11:46 am
by szhou42
Ch4ozz wrote:You have to compile it with

Code: Select all

-nostdinc -fno-builtin
Exactly like your OS should be compiled too.
We dont want some random OS dependent CRT code inside the executable since we build our own OS here and there is of course
no available CRT for it (except you port the library to your OS)
Hi Ch4ozz and Roman, thank you !
I now manage to compile the program with this command

Code: Select all

gcc -T link.ld -nostdinc -fno-builtin -nostartfiles umain.c -o test1.bin
but i686-elf-gcc still won't compile

Code: Select all

vagrant@vagrant-ubuntu-trusty-32:~/test$ i686-elf-gcc -T link.ld -nostdinc -fno-builtin -nostartfiles umain.c -o test1.bin
/home/vagrant/opt/cross/lib/gcc/i686-elf/4.8.4/../../../../i686-elf/bin/ld: cannot find -lc
collect2: error: ld returned 1 exit status
vagrant@vagrant-ubuntu-trusty-32:~/test$
Also, when my loader loads the program and finish the main function, it triggers an exception at the "ret" instruction.
I guess this is because the program is compiled without crt, and so ret returns to a random address on stack, which explains the exception, is this correct ?
So now what I am missing is a c library that helps gcc to compile a complete user program with crt ?

Code: Select all

0x00000024 in ?? ()
=> 0x24:	push   %ebp
   0x25:	mov    %esp,%ebp
   0x27:	sub    $0x10,%esp
   0x2a:	movl   $0x0,-0x4(%ebp)
   0x31:	addl   $0x1,-0x4(%ebp)
   0x35:	mov    $0x0,%eax
   0x3a:	leave
   0x3b:	ret

Re: compile user program for my os

Posted: Sat Aug 13, 2016 1:01 pm
by Ch4ozz
Use the i686-elf-ld to link your program and not gcc directly.
Also you have to put the return address of some function which safely ends its own thread onto the stack so threads which are returning from main will terminate themselves.

Re: compile user program for my os

Posted: Sat Aug 13, 2016 2:46 pm
by szhou42
Ch4ozz wrote: Also you have to put the return address of some function which safely ends its own thread onto the stack so threads which are returning from main will terminate themselves.
Isn't this usually done by the crt? If so,when my program can be compiled with a c library, i think this problem will be solved automatically.

Re: compile user program for my os

Posted: Sat Aug 13, 2016 4:03 pm
by Ch4ozz
szhou42 wrote:
Ch4ozz wrote: Also you have to put the return address of some function which safely ends its own thread onto the stack so threads which are returning from main will terminate themselves.
Isn't this usually done by the crt? If so,when my program can be compiled with a c library, i think this problem will be solved automatically.
Hm to be honest I dont know if CRT does this.
But I guess it doesnt because if a program is written in pure asm it can terminate just fine too.