I am a newbie in writing bootloaders. I have written a helloworld bootloader in asm, and I am now trying to write one in C. I have written a helloworld bootloader in C, but I cannot compile it.
This is my code. What am I doing wrong? Why won't it compile?
void print_char(); int main(void){ char *MSG = "Hello World!"; int i; __asm__( "mov %0, %%SI;" : :"g"(MSG) ); for(i=0;i<12;i++){ __asm__( "mov %0, %%AL;" : :"g"(MSG[i]) ); print_char(); } return 0; } void print_char(){ __asm__( "mov $0X0E, %AH;" "mov $0x00, %BH;" "mov $0x04, %BL;" "int $0x10" ); }
Let me assume a lot of things here: you want to run your bootloader on an x86 system, you have the gcc toolchain set up on a *nix box.
There are some points to be taken into account when writing a bootloader:
now if you want gcc to output such a binary, you need to play some tricks with it.
__asm__(".code16gcc\n")
at the top of each C file.gcc outputs compiled objects in ELF. We need a bin that is statically linked at 7c00h. Create a file linker.ld
with following contents
ENTRY(main); SECTIONS { . = 0x7C00; .text : AT(0x7C00) { _text = .; *(.text); _text_end = .; } .data : { _data = .; *(.bss); *(.bss*); *(.data); *(.rodata*); *(COMMON) _data_end = .; } .sig : AT(0x7DFE) { SHORT(0xaa55); } /DISCARD/ : { *(.note*); *(.iplt*); *(.igot*); *(.rel*); *(.comment); /* add any unwanted sections spewed out by your version of gcc and flags here */ } }
write your bootloader code in bootloader.c
and build the bootloader
$ gcc -c -g -Os -march=i686 -ffreestanding -Wall -Werror -I. -o bootloader.o bootloader.c $ ld -static -Tlinker.ld -nostdlib --nmagic -o bootloader.elf bootloader.o $ objcopy -O binary bootloader.elf bootloader.bin
Since you already have built boot loaders with ASM, I guess the rest is obvious to you.
- taken from my blog: http://dc0d32.blogspot.in/2010/06/real-mode-in-c-with-gcc-writing.html
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With