Hi,
I started writing a small kernel code that prints a character when it is loaded by my bootloader wriiten in assembly. Everything worked fine till i was printing a character. But when i tried putting function calls in my c code the computer reboots, no idea why!!. I'm using tftpboot to load the binary.
Following are my code with the disassembled c code
bootloader.asm
bits 16
org 7c00h
cli
xor ax,ax
mov ds,ax
mov es,ax
lgdt [gdt_desc]
mov si,7e00h ; if your kernel has been placed at offset 200h, like you did
mov di,1000h ; the address where the kernel should be
mov cx,512 ; whatever the size of the kernel is
rep movsb
mov eax,cr0
or al,1
mov cr0,eax
jmp 08h:clear_pipe
bits 32
clear_pipe:
mov ax,10h
mov ds,eax
mov es,eax
mov ss,eax
mov esp,90000h
jmp 08h:00001000h
;mov byte [ds:0B8000h], 'P' ; Move the ASCII-code of 'P' into first video memory
;mov byte [ds:0B8001h], 1Bh ; Assign a color code
jmp $
gdt dd 0ffffh,0cf9a00h,0ffffh,0cf9200h
gdt_desc dw 23
dd gdt-8
main.c
#define WHITE_TXT 0x07 // white on black text
int k_clear_screen();
int k_printf(char *message, unsigned int line);
int main() // like main in a normal C program
{
//for(;;);
k_clear_screen();
k_printf("Hi!\nHow's this for a starter OS?", 0);
for(;;);
}
int k_clear_screen() // clear the entire text screen
{
for(;;);
char *vidmem = (char *) 0xb8000;
unsigned int i=0;
while(i < (80*25*2))
{
vidmem[i]=' ';
i++;
vidmem[i]=WHITE_TXT;
i++;
}
for(;;);
return 0;
}
int k_printf(char *message, unsigned int line) // the message and then the line #
{
char *vidmem = (char *) 0xb8000;
unsigned int i=0;
i=(line*80*2);
while(*message!=0)
{
if(*message=='\n') // check for a new line
{
line++;
i=(line*80*2);
*message++;
} else {
vidmem[i]=*message;
*message++;
i++;
vidmem[i]=WHITE_TXT;
i++;
}
}
return 0;
}
compilation steps
nasm -f bin bootloader.asm -o bootloader.bin
gcc -ffreestanding -c main.c -o main.o
ld -i -e _main -Ttext 0x1000 -o kernel.o main.o
objcopy -R .note -R .comment -S -O binary kernel.o kernel.bin
dd if=bootsect.bin of=os1.img bs=512 count=1
dd if=kernel.bin of=os1.img bs=512 seek=1
disassembled main.o
00001000 <main>:
1000: 55 push %ebp
1001: 89 e5 mov %esp,%ebp
1003: 83 ec 08 sub $0x8,%esp
1006: 83 e4 f0 and $0xfffffff0,%esp
1009: b8 00 00 00 00 mov $0x0,%eax
100e: 83 c0 0f add $0xf,%eax
1011: 83 c0 0f add $0xf,%eax
1014: c1 e8 04 shr $0x4,%eax
1017: c1 e0 04 shl $0x4,%eax
101a: 29 c4 sub %eax,%esp
101c: c7 45 fc 00 80 0b 00 movl $0xb8000,0xfffffffc(%ebp)
1023: 8b 45 fc mov 0xfffffffc(%ebp),%eax
1026: c6 00 41 movb $0x41,(%eax)
1029: 8b 45 fc mov 0xfffffffc(%ebp),%eax
102c: 40 inc %eax
102d: c6 00 07 movb $0x7,(%eax)
1030: e8 fc ff ff ff call 1031 <main+0x31> this is the jump to clear screen(should this be 1049 instead of 1031)
1035: 83 ec 08 sub $0x8,%esp
1038: 6a 00 push $0x0
103a: 68 00 00 00 00 push $0x0
103f: e8 fc ff ff ff call 1040 <main+0x40>
1044: 83 c4 10 add $0x10,%esp
1047: eb fe jmp 1047 <main+0x47>
00001049 <k_clear_screen>:
1049: 55 push %ebp
104a: 89 e5 mov %esp,%ebp
104c: 83 ec 08 sub $0x8,%esp
104f: eb fe jmp 104f <k_clear_screen+0x6>
Thanks
Alok