I used to create an ELF file with the main code written in C and compiled with gcc
gcc -nostdlib -nostartfiles -nodefaultlibs -fno-builtin -O0 -c
kernel.c
Then another assemble code [init.s] with a well known entry point (first instruction at the very first byte)
[bits 32]
[global start]
[global kbhit]
[global getscan]
[extern main]
start: call main ; jump to main() in kernel.c
hang: hlt ; halt the cpu
jmp hang
kbhit:
in al,0x64
and al,1
ret
getscan:
in al,0x60
ret
with some "firmware" functions to be used by the C program [kbhit(), getscan(),...] as we don't have access to BIOS in protected mode
Assemble with nasm, also in ELF:
nasm -f elf init.s
Then link both together and store the resulting file in sectors after the MBR in your USB (you MBR should read it from USB, put it in memory, go to protected mode and jumt to the first byte of "kernel.bin")
ld -T kernel.ld -o kernel.bin init.o kernel.o
The order of the object files (.o) is important, put init.o the first one
kernel.ld:
OUTPUT_FORMAT("binary")
ENTRY(start)
SECTIONS
{
.text 0x100000 : {
*(.text)
}
.data : {
*(.data)
}
.bss :
{
*(.bss)
}
}
Hope this help