compile user program for my os

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
szhou42
Member
Member
Posts: 67
Joined: Thu Apr 28, 2016 12:40 pm
Contact:

compile user program for my os

Post 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.
User avatar
Roman
Member
Member
Posts: 568
Joined: Thu Mar 27, 2014 3:57 am
Location: Moscow, Russia
Contact:

Re: compile user program for my os

Post 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.
"If you don't fail at least 90 percent of the time, you're not aiming high enough."
- Alan Kay
User avatar
Ch4ozz
Member
Member
Posts: 170
Joined: Mon Jul 18, 2016 2:46 pm
Libera.chat IRC: esi

Re: compile user program for my os

Post 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)
szhou42
Member
Member
Posts: 67
Joined: Thu Apr 28, 2016 12:40 pm
Contact:

Re: compile user program for my os

Post 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
User avatar
Ch4ozz
Member
Member
Posts: 170
Joined: Mon Jul 18, 2016 2:46 pm
Libera.chat IRC: esi

Re: compile user program for my os

Post 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.
szhou42
Member
Member
Posts: 67
Joined: Thu Apr 28, 2016 12:40 pm
Contact:

Re: compile user program for my os

Post 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.
User avatar
Ch4ozz
Member
Member
Posts: 170
Joined: Mon Jul 18, 2016 2:46 pm
Libera.chat IRC: esi

Re: compile user program for my os

Post 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.
Post Reply