loading a c object file in real mode

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
richi18007
Member
Member
Posts: 35
Joined: Mon Mar 07, 2011 1:41 pm

loading a c object file in real mode

Post by richi18007 »

I tried every single thing .
I went through this link

http://dc0d32.blogspot.in/2010/06/real- ... iting.html . To create a bootloader in C . The code works just fine . But when I try to load this bootloader code itself with my custom loader , the loading function is mentioned below .( by the linker script given in the link already, I get nothing , plain nothing man ). I just modified the addresses in the link to make the starting address of the linked C code as 0x2000 , so that it works, but it doesn't ](*,) . I just cannot load anything which was initially written in C through the my bootloader , no matter what format they are in and how I link them. But i can load everything in assembly with the help of my bootloader. Also , I want to make the jump to C world in real mode only . So , no Pmode yet.

Can anybody please give me some link. Some sequence of commands to load a C file at memory location (0x2000) as a flat binary. So that , it would just run . I am writing the relevant code

Code: Select all

repeat_read:	
	;Code to load the second sector on the disk into memory location 0x2000:0x0000
	mov bx, 0x2000	; Segment location to read into (remember can't load direct to segment register)
	mov es, bx
	mov bx, 0	; Offset to read into
	mov ah, 02	; BIOS read sector function
	mov al, 01	; read one sector
	mov ch,	0	; Track to read
	mov cl,	02	; Sector to read
	mov dh,	0	; Head to read
	mov dl,	00	; Drive to read
	int 0x13	; Make the BIOS call (int 13h contains mainly BIOS drive functions)
	;Set up the data segment 
	jnc repeat_read_success 
	mov si , error_message 
	call print_string 
	ret 
repeat_read_success:
	mov si , kernel_loading_success 
	call print_string
	;Set the data segment 
	mov ax , 0x2000
	mov ds , ax 
	jmp 0x2000:0x0  ; Load at address 0x20000
If I do something like this ya know

Code: Select all

nasm -f bin -o main.bin main.asm (main.asm , just a dummy code which can print a string)
dd if=boot.bin of=floppy.img seek=1 count=1 bs=512 conv=notrunc (just load this binary at the second sector)
This works fine with my bootloader(written at the first sector of the floppy disk image). But when I load a properly assembled and linked C code at sector 2. It stops working. Nothing is printed after the jump instruction in the end . This is my link script as of yet

Code: Select all

SECTIONS
{    
    . = 0x20000;    
    .text : AT(0x20000)
    {
        _text = .;
        *(.text);
        _text_end = .;
    }
    .data :
    {
        _data = .;
        *(.bss);
        *(.bss*);
        *(.data);
        *(.rodata*);
        *(COMMON)
        _data_end = .;
    }    
/*
    .sig : AT(0x2)    
    {        
        SHORT(0xaa55);
    }
*/    
    /DISCARD/ :
    {
        *(.note*);
        *(.iplt*);
        *(.igot*);
        *(.rel*);
        *(.comment);
        /* add any unwanted sections spewed out by your version of gcc and flags here */    
    }
}

I hope that the link script is correct. Please , tell me where i am correct. I cannot find the solution out. Woke up till late night , but still nothing makes sense.
User avatar
turdus
Member
Member
Posts: 496
Joined: Tue Feb 08, 2011 1:58 pm

Re: loading a c object file in real mode

Post by turdus »

Let's assume that your C compiler produce correct real mode code. After loading, you have to parse it's header (either elf or pe) to find the relative address of the main function. Next add the location of your loader in memory, and jump to that. It's not trivial in real mode, because the same address can be represented with several segment:offset pairs, but you have to set up correctly as the C code expects. Workaround: start your main with setting up the segment registers and stack, so runtime values will match linker's.

Compiling raw binary with C is not recommended, because C is a high level language (well, higher than assembler), that reuires text, data and bss sections, which are not stored in raw format. Compiler would merily use them, so you'll have to set up the environment in your bootloader (or in first instructions of your main) correctly for C call convention.

Another solution: write your C loader in pmode (recommended), and set up pmode in your bootloader, so that you can jump to main without problem. If you want to access bios from C, you should implement a small bios_int(num,&regsstruct) function that switches back to real mode, calls the apprirate isr and returns in pmode. See minix's or bsd's similar function for a reference implementation.
User avatar
eino
Member
Member
Posts: 49
Joined: Fri Sep 16, 2011 10:00 am
Location: Finland

Re: loading a c object file in real mode

Post by eino »

http://www.skyfree.org/linux/references/ELF_Format.pdf will give you valuable info about the elf header and how to find the entry point.
I'm Eino Tuominen from Finland, a web software dev learning low level stuff and reading / trying out kernel dev
Post Reply