Bootloader fails calling C function

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
plevexier
Posts: 8
Joined: Wed Sep 21, 2016 6:32 am
Libera.chat IRC: plevexier
Contact:

Bootloader fails calling C function

Post 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.
Octocontrabass
Member
Member
Posts: 5587
Joined: Mon Mar 25, 2013 7:01 pm

Re: Bootloader fails calling C function

Post 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.
plevexier
Posts: 8
Joined: Wed Sep 21, 2016 6:32 am
Libera.chat IRC: plevexier
Contact:

Re: Bootloader fails calling C function

Post 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.
plevexier
Posts: 8
Joined: Wed Sep 21, 2016 6:32 am
Libera.chat IRC: plevexier
Contact:

Re: Bootloader fails calling C function

Post 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:

Code: Select all

asm(".code16gcc\n");
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)
...
Octocontrabass
Member
Member
Posts: 5587
Joined: Mon Mar 25, 2013 7:01 pm

Re: Bootloader fails calling C function

Post by Octocontrabass »

The BIOS loads one sector.

How big is one sector? How big is your code?
plevexier
Posts: 8
Joined: Wed Sep 21, 2016 6:32 am
Libera.chat IRC: plevexier
Contact:

Re: Bootloader fails calling C function

Post 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.
FallenAvatar
Member
Member
Posts: 283
Joined: Mon Jan 03, 2011 6:58 pm

Re: Bootloader fails calling C function

Post 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
alexfru
Member
Member
Posts: 1112
Joined: Tue Mar 04, 2014 5:27 am

Re: Bootloader fails calling C function

Post by alexfru »

You may want to try out my BootProg in combination with Smaller C.
plevexier
Posts: 8
Joined: Wed Sep 21, 2016 6:32 am
Libera.chat IRC: plevexier
Contact:

Re: Bootloader fails calling C function

Post 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.
plevexier
Posts: 8
Joined: Wed Sep 21, 2016 6:32 am
Libera.chat IRC: plevexier
Contact:

Re: Bootloader fails calling C function

Post by plevexier »

alexfru wrote:You may want to try out my BootProg in combination with Smaller C.
Nice resources thanks.
Octocontrabass
Member
Member
Posts: 5587
Joined: Mon Mar 25, 2013 7:01 pm

Re: Bootloader fails calling C function

Post 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.
FusT
Member
Member
Posts: 91
Joined: Wed Sep 19, 2012 3:43 am
Location: The Netherlands

Re: Bootloader fails calling C function

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