Page 1 of 1
Bootloader fails calling C function
Posted: Tue Sep 27, 2016 7:16 am
by plevexier
I have a small bootloader in real mode I'm playing with, it boots ok, I validated with bochs debugger, but it fails to call the C kmain function.
Code: Select all
bits 16
global _start
extern kmain
section .text
_start:
cli
mov ax, 07C0h ; Set up 4K stack space after this bootloader
add ax, 288 ; (4096 + 512) / 16 bytes per paragraph
mov ss, ax
mov sp, 4096
mov ax, 07C0h ; Set data segment to where we're loaded
mov ds, ax
sti
call kmain
Here's the kmain code:
Code: Select all
void kmain(void) {
const char* string = "stage1 loaded\0";
volatile char *video = (volatile char*)0xB8000;
while( *string != 0 )
{
*video++ = *string++;
*video++ = 0x07;
}
}
And here's the .ld file:
Code: Select all
ENTRY(_start)
STARTUP(boot.o)
INPUT(kernel.o)
SECTIONS
{
.text :
{
*(.text);
}
}
OUTPUT_FORMAT(binary)
OUTPUT(myos.bin)
I'm building with:
Code: Select all
nasm -f elf -o boot.o boot.asm
i686-elf-gcc -c kernel.c -o kernel.o -std=gnu99 -ffreestanding -O2 -Wall -Wextra
i686-elf-gcc -T kernel.ld -o myos.bin -ffreestanding -O2 -nostdlib -lgcc
And then I do a floppy with
Code: Select all
dd if=/dev/zero of=floppy.img bs=512 count=2880
dd if=myos.bin of=floppy.img
When I debug in bochs, the "call kmain" doesn't point to the right address but I can't figure out why... Am I missing something obvious here?
Thanks for your help.
Re: Bootloader fails calling C function
Posted: Tue Sep 27, 2016 7:32 am
by Octocontrabass
plevexier wrote:Am I missing something obvious here?
Your bootloader runs in 16-bit mode, but your C compiler emits 32-bit code.
Re: Bootloader fails calling C function
Posted: Tue Sep 27, 2016 9:02 am
by plevexier
Octocontrabass wrote:Your bootloader runs in 16-bit mode, but your C compiler emits 32-bit code.
Ahah, that sure could explain it
A -m16 should be enough right? I just quickly tested but it still doesn't work. Gonna investigate more though.
Re: Bootloader fails calling C function
Posted: Tue Sep 27, 2016 9:48 am
by plevexier
Yes I retried with:
Code: Select all
i686-elf-gcc -m16 -c kernel.c -o kernel.o -std=gnu99 -ffreestanding -O2 -Wall -Wextra
I put:
At the top of the C file, but same result, the kmain is not called. I even added:
Code: Select all
void kmain(void) __attribute__((section(".text")));
to the C file, just in case, but still, the kmain code is not at the right address :
Code: Select all
----------------
IN:
# kmain(void)
0x00007c43: call 0x7e00
----------------
IN:
0x00007e00: add %al,(%bx,%si)
0x00007e02: add %al,(%bx,%si)
...
Re: Bootloader fails calling C function
Posted: Tue Sep 27, 2016 10:05 am
by Octocontrabass
The BIOS loads one sector.
How big is one sector? How big is your code?
Re: Bootloader fails calling C function
Posted: Tue Sep 27, 2016 10:56 am
by plevexier
Octocontrabass wrote:The BIOS loads one sector.
How big is one sector? How big is your code?
Yes it's the issue, the boot sector is 512 bytes, not enough for the assembly + the C code... Now I see why most of the kernel out there use multiboot... lol
Thanks for your help.
Re: Bootloader fails calling C function
Posted: Tue Sep 27, 2016 7:34 pm
by FallenAvatar
plevexier wrote:Yes it's the issue, the boot sector is 512 bytes, not enough for the assembly + the C code... Now I see why most of the kernel out there use multiboot... lol
Thanks for your help.
Also, GCC can
NOT output real mode code! This might happen to work, but anything else is likely to break randomly. GCC expects 32-bit PMode, or 64-bit Long Mode, (And both with Flat Segments, CS = DS = ES = SS = 0)
- Monk
Re: Bootloader fails calling C function
Posted: Wed Sep 28, 2016 12:02 am
by alexfru
You may want to try out my
BootProg in combination with
Smaller C.
Re: Bootloader fails calling C function
Posted: Wed Sep 28, 2016 9:24 am
by plevexier
tjmonk15 wrote:
Also, GCC can NOT output real mode code! This might happen to work, but anything else is likely to break randomly. GCC expects 32-bit PMode, or 64-bit Long Mode, (And both with Flat Segments, CS = DS = ES = SS = 0)
- Monk
Yes, it's a good point, my goal was only to start on real mode, get the memory map using int 15h and then switch to PM. I think i'll go the other way around, use multiboot, boot in PM, switch to real mode, get the mem map and then switch back.
Re: Bootloader fails calling C function
Posted: Wed Sep 28, 2016 9:25 am
by plevexier
Re: Bootloader fails calling C function
Posted: Wed Sep 28, 2016 12:06 pm
by Octocontrabass
tjmonk15 wrote:Also, GCC can NOT output real mode code! This might happen to work, but anything else is likely to break randomly. GCC expects 32-bit PMode, or 64-bit Long Mode, (And both with Flat Segments, CS = DS = ES = SS = 0)
GCC can output 32-bit code that expects to be running in 16-bit mode. It will run in real mode as long as the entire program's address space is under 64kB and CS=DS=ES=SS. (It'll also run in 16-bit protected mode, with similar limitations.)
It doesn't work by coincidence, it's a documented feature of GCC. It won't break as long as Linux continues to rely on it.
Re: Bootloader fails calling C function
Posted: Thu Sep 29, 2016 12:44 am
by FusT
If you're going to use multiboot to boot your kernel you don't need to switch back to real mode and do int 15h to get a memory map, you can simply get it form the multiboot structure.
See the
multiboot spec.