Page 1 of 1

calling functions written in c from your bootloader?

Posted: Wed Feb 11, 2015 9:27 pm
by markq
Hello,

I am trying to call c functions from my bootloader. Suppose I am in 32-bit protected mode in my bootloader and I want to call some c functions for easier data manipulation such as parsing kernel elf header and loading it in to memory. How would I link my bootloader with my c functions? Suppose my loader is called bootloader.asm and c function file is call function.c.

I tried linking them but it didn't work cause it added some stuff at the end of the binary...

x86_64-elf-gcc -c function.c
nasm -f bootloader.asm -o bootloader.o
ld -melf_i386 -Ttext 0x7c00 function.o bootloader.o -o bootloader.bin --oformat binary

Re: calling functions written in c from your bootloader?

Posted: Wed Feb 11, 2015 9:59 pm
by SoulofDeity
markq wrote:Hello,

I am trying to call c functions from my bootloader. Suppose I am in 32-bit protected mode in my bootloader and I want to call some c functions for easier data manipulation such as parsing kernel elf header and loading it in to memory. How would I link my bootloader with my c functions? Suppose my loader is called bootloader.asm and c function file is call function.c.

I tried linking them but it didn't work cause it added some stuff at the end of the binary...

x86_64-elf-gcc -c function.c
nasm -f bootloader.asm -o bootloader.o
ld -melf_i386 -Ttext 0x7c00 function.o bootloader.o -o bootloader.bin --oformat binary
Well, assuming you've initialized the stack, you just have to use the right calling convention.

Re: calling functions written in c from your bootloader?

Posted: Wed Feb 11, 2015 10:00 pm
by deleted
Hello there! Welcome to the OSDeving forums.

I'm not sure what programming experience your coming from, but you need to know a few things.

First: understand how a compiler, kernel, and linker work together. (http://wiki.osdev.org/How_kernel,_compi ... k_together)

Next let's take a look at what your doing, but first please please please create a makefile!

Ok, so we need to make some object files, this can be done by using what I belive is the -c flag. So, in order to save our object file, we need to use the -o flag.

Code: Select all

CROSS-NAME-gcc -c -o kernel.c kernel.o
Now we need to assemble your assembly code, using Nasm. The flags should be pretty self explanatory:

Code: Select all

nasm -felf -o start.o start.asm
Now we have two object files, to linking! I suggest you use Brandon's linking script, and options (Google OSDEVER.net tutorial kernel). You can then link the objects like this

Code: Select all

CROSS-NAME-ld -Tlink.ld -o kernel.bin start.o kernel.c
As for using functions in and out of different languages, use the extern keyword in C, and specify the global keyword in ASM in order to access the ASM function.

EG:

Code: Select all

global push_ebx
push_ebx:
    push_ebx


In C:

extern void push_ebx();
Please excuse poorly written code. Now, if you are using a cross compiler, you should be able to call that function.

Enjoy!

PS: I suggest you read up on C and ASM crossing ;)

Re: calling functions written in c from your bootloader?

Posted: Wed Feb 11, 2015 10:13 pm
by markq
wxwsk8er wrote:Hello there! Welcome to the OSDeving forums.

I'm not sure what programming experience your coming from, but you need to know a few things.

First: understand how a compiler, kernel, and linker work together. (http://wiki.osdev.org/How_kernel,_compi ... k_together)

Next let's take a look at what your doing, but first please please please create a makefile!

Ok, so we need to make some object files, this can be done by using what I belive is the -c flag. So, in order to save our object file, we need to use the -o flag.

Code: Select all

CROSS-NAME-gcc -c -o kernel.c kernel.o
Now we need to assemble your assembly code, using Nasm. The flags should be pretty self explanatory:

Code: Select all

nasm -felf -o start.o start.asm
Now we have two object files, to linking! I suggest you use Brandon's linking script, and options (Google OSDEVER.net tutorial kernel). You can then link the objects like this

Code: Select all

CROSS-NAME-ld -Tlink.ld -o kernel.bin start.o kernel.c
As for using functions in and out of different languages, use the extern keyword in C, and specify the global keyword in ASM in order to access the ASM function.

EG:

Code: Select all

global push_ebx
push_ebx:
    push_ebx


In C:

extern void push_ebx();
Please excuse poorly written code. Now, if you are using a cross compiler, you should be able to call that function.

Enjoy!

PS: I suggest you read up on C and ASM crossing ;)

Hi,

I can understand what you did above. But I want to call c functions from my bootloader. The thing is when I link my bootloader with my c function using ld it adds some stuff at the end to the new binary which removes the magic number aa 55 from the end of the file. This causes bios unable to recognize the new binary as a bootloader. So I was wonder how I would resolve this issue.

Re: calling functions written in c from your bootloader?

Posted: Wed Feb 11, 2015 10:27 pm
by SoulofDeity
markq wrote:Hi,

I can understand what you did above. But I want to call c functions from my bootloader. The thing is when I link my bootloader with my c function using ld it adds some stuff at the end to the new binary which for some reason removes the magic number aa 55 from the end of the file. This causes bios unable to recognize the new binary as a bootloader. So I was wonder how I would resolve this issue.
You can either:

1) Use a 2nd stage chainloader to load the entire thing into memory

2) Try stripping the debugging symbols, removing unused sections, disable linking against libraries, and disable section alignment and:
2a) Edit your linker script to truncate the file to 510 bytes and add 0x55aa to the end of the file or...
2b) Pipe your binary file through through 'dd' to dump exactly 510 bytes and 'cat' 0x55aa to the end of it.

Re: calling functions written in c from your bootloader?

Posted: Thu Feb 12, 2015 12:26 am
by Roman
You shouldn't use C for boot sectors and shouldn't parse ELF from it. Load a second stage and read about calling conventions.

Re: calling functions written in c from your bootloader?

Posted: Thu Feb 12, 2015 1:25 am
by markq
Roman wrote:You shouldn't use C for boot sectors and shouldn't parse ELF from it. Load a second stage and read about calling conventions.
Should the second stage bootloader be written in c or asm? I would imagine that if I write it in C I would stil need inline assembly to access bios functions, switch between modes and setting up stuff like gdt, ldt, A20, Long mode and etc. For some reason some people claim the second stage bootloader for linux is in C, if so, is it a good idea or not?

Re: calling functions written in c from your bootloader?

Posted: Thu Feb 12, 2015 1:33 am
by SoulofDeity
markq wrote:
Roman wrote:You shouldn't use C for boot sectors and shouldn't parse ELF from it. Load a second stage and read about calling conventions.
Should the second stage bootloader be written in c or asm? I would imagine that if I write it in C I would stil need inline assembly to access bios functions, switch between modes and setting up stuff like gdt, ldt, A20, Long mode and etc. For some reason some people claim the second stage bootloader for linux is in C, if so, is it a good idea or not?
If you're rolling your own bootloader, then none of your stages should be written in C. That doesn't come until after you've enabled the A20 gate, setup the GDT/IDT, and entered protected mode. At this point, taking into account the MBR, you've used up well over half of your 510 bytes. With C, the remaining space would be used up in a flash. You have no choice but to store your code separate and load it off disk.

If you really want to use C that bad, just follow the Bare Bones tutorial. You can always write your own bootloader later if it bothers you.

Re: calling functions written in c from your bootloader?

Posted: Thu Feb 12, 2015 1:59 am
by Combuster
markq wrote:32-bit protected mode
markq wrote:x86_64-elf-gcc
Really?