I am trying to develop a kernel in C. My kernel is supposed to display a very simple welcome message. The second stage of my bootloader loads the kernel at 0x8000 and it moves the kernel to 0x100000. My kernel consists of two parts. third_stage.asm
which calls the main function in os.c
. The problem is that I keep getting guru meditation error.
The code for my bootloader(boot) can be found in my previous StackOverflow question.
The code for my second stage:
org 0x7E00
bits 16
;;;;;;;;;;;;;stack;;;;;;;;;;
Setup:
cli
xor ax , ax
mov ds , ax
mov es , ax
mov ax , 0x9000
mov ss , ax
mov sp , 0x0000
sti
;;;;;;;;;;;;;video;;;;;;;;;;;
Set:
mov al , 03h
mov ah , 00h
int 10h
mov ah , 09h
mov al , 'A'
mov bh , 00h
mov bl , 0x0F
mov cx , 01h
int 10h
jmp loadgdt
;;;;;;;;;;;;gdt;;;;;;;;;;;;;;;
gdt_start:
null:
dd 0
dd 0
code:
dw 0FFFFh
dw 0
db 0
db 10011010b
db 11001111b
db 0
data:
dw 0FFFFh
dw 0
db 0
db 10010010b
db 11001111b
db 0
end:
load: dw end - gdt_start -1
dd null
;;;;;;;;;;;;;loadgdt;;;;;;;;;;
loadgdt:
lgdt [load]
;;;;;;;;;;;;A20;;;;;;;;;;;;;;;
A20:
mov ax , 0x2401
int 0x15
jc A20
;;;;;;;;;;;;;floppy;;;;;;;;;;;
Reset:
mov ah , 00h
mov dl , [0x500]
int 13h
jc Reset
Read:
mov ax , 0x800
mov es , ax ; Setup ES=0x800
mov ah , 02h ; Setup AH
mov al , 0fh ; Setup AL
mov ch , 00h
mov cl , 03h
mov dh , 00h
mov dl , [0x500]
xor bx , bx
int 13h
jc Read
Begin:
mov ah , 09h
mov al , 'G'
mov bh , 00h
mov bl , 0x0F
mov cx , 01h
int 10h
;;;;;;;;;;;switching to protected;;;;
protected:
mov ah , 09h
mov al , 'P'
mov bh , 00h
mov bl , 0x0F
mov cx , 01h
int 10h
xor ax, ax
mov ds, ax
cli
mov eax, cr0
or eax , 1
mov cr0 , eax
jmp (code-gdt_start):transfer_control
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
bits 32
transfer_control:
mov ax, (data-gdt_start)
mov ds, ax
mov ss, ax
mov es, ax
mov esp, 90000h
mov [0xB8000], word 0x0F58 ; Print 'X'
CopyImage:
mov eax , dword 0x0f
mov ebx , dword 0x200
mul ebx
mov ebx , 4
div ebx
cld
mov esi , 0x8000
mov edi , 0x100000
mov ecx , eax
rep movsd
jmp 0x100000
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
times 512-($-$$) db 0
Code for third_stage:
bits 32
global _start
extern main
_start:
mov ax , 0x10
mov ds , ax
mov ss, ax
mov es, ax
mov esp, 90000h
mov [0xB8002], word 0x0F58 ; Print 'X'
call main
hlt
Code for os.c:
//reserved - 0x500(drive number), 0x501(keyboard buffer), 0x502(screen X) , 0x503(screen y)
volatile char * buffer = (volatile char*)0x501 ;
volatile char * x = (volatile char*)0x502 ;
volatile char * y = (volatile char*)0x503 ;
void newline() {
if(*y < 24) {
*y++ ;
*x = 0 ;
}
else {
*y = 25 ;
*x = 80 ;
}
}
void clrscr() {
volatile char * display = (volatile char*)0xb8000 ;
for(display = 0xb8000 ; display <= 0xbffff;display++) {
*display = 0 ;
}
}
void println(char output[]) {
char * x = (char*)0x502 ;
char * y = (char*)0x503 ;
int arg = 0 ;
if(*x == 80 && *y == 25) {
clrscr() ;
*x = 0 ;
*y = 0 ;
}
volatile char * display = (volatile char*)0xb8000 + (((*y * 80) + *x) * 2) ;
while(output[arg] != '\0') {
if(*x == 80 && *y == 25) {
clrscr() ;
*x = 0 ;
*y = 0 ;
arg = 0 ;
display = 0xb8000 ;
}
else if(*x == 80) {
*y++ ;
*x = 0 ;
}
*display = output[arg] ;
display++ ;
*display = 0x0f ;
display++ ;
arg++ ;
*x++ ;
}
newline() ;
}
void print(char output[]) {
int arg = 0 ;
if(*x == 80 && *y == 25) {
clrscr() ;
*x = 0 ;
*y = 0 ;
}
volatile char * display = (volatile char*)0xb8000 + (((*y * 80) + *x) * 2) ;
while(output[arg] != '\0') {
if(*x == 80 && *y == 25) {
clrscr() ;
*x = 0 ;
*y = 0 ;
arg = 0 ;
display = 0xb8000 ;
}
else if(*x == 80) {
*y++ ;
*x = 0 ;
}
*display = output[arg] ;
display++ ;
*display = 0x0f ;
display++ ;
arg++ ;
*x++ ;
}
}
void printc(char output) {
char * x = (char*)0x502 ;
char * y = (char*)0x503 ;
if(*x == 80 && *y == 25) {
clrscr() ;
*x = 0 ;
*y = 0 ;
}
else if(*x == 80) {
*y++ ;
*x = 0 ;
}
volatile char * display = (volatile char*)0xb8000 + (((*y * 80) + *x) * 2) ;
*display = output ;
display++ ;
*display = 0x0f ;
display++ ;
*x++ ;
if(*x == 80) {
*y++ ;
*x = 0 ;
}
}
void backspace() {
if(*x == 0 && *y == 0) {
}
else if(*x == 0) {
*x = 79 ;
*y-- ;
volatile char * display = (volatile char*)0xb8000 + (((*y * 80) + *x) * 2) ;
*display = 0 ;
display++ ;
*display = 0 ;
}
else {
*x-- ;
volatile char * display = (volatile char*)0xb8000 + (((*y * 80) + *x) * 2) ;
*display = 0 ;
display++ ;
*display = 0 ;
}
}
char * scanln() {
static char input[512] ;
char scancode[0xd9] ;
char shift_scancode[0xd9] ;
*buffer = 0 ;
int arg = 0 ;
scancode[0x1c] = 'a' ;
scancode[0x32] = 'b' ;
scancode[0x21] = 'c' ;
scancode[0x23] = 'd' ;
scancode[0x24] = 'e' ;
scancode[0x2b] = 'f' ;
scancode[0x34] = 'g' ;
scancode[0x33] = 'h' ;
scancode[0x43] = 'i' ;
scancode[0x3b] = 'j' ;
scancode[0x42] = 'k' ;
scancode[0x4b] = 'l' ;
scancode[0x3a] = 'm' ;
scancode[0x31] = 'n' ;
scancode[0x44] = 'o' ;
scancode[0x4d] = 'p' ;
scancode[0x15] = 'q' ;
scancode[0x2d] = 'r' ;
scancode[0x1b] = 's' ;
scancode[0x2c] = 't' ;
scancode[0x3c] = 'u' ;
scancode[0x2a] = 'v' ;
scancode[0x1d] = 'w' ;
scancode[0x22] = 'x' ;
scancode[0x35] = 'y' ;
scancode[0x1a] = 'z' ;
scancode[0x45] = '0' ;
scancode[0x16] = '1' ;
scancode[0x1e] = '2' ;
scancode[0x26] = '3' ;
scancode[0x25] = '4' ;
scancode[0x2e] = '5' ;
scancode[0x36] = '6' ;
scancode[0x3d] = '7' ;
scancode[0x3e] = '8' ;
scancode[0x46] = '9' ;
scancode[0x0e] = '`' ;
scancode[0x4e] = '-' ;
scancode[0x55] = '=' ;
scancode[0x5d] = '\\' ;
scancode[0x54] = '[' ;
scancode[0x5b] = ']' ;
scancode[0x4c] = ';' ;
scancode[0x52] = '\'' ;
scancode[0x41] = ',' ;
scancode[0x49] = '.' ;
scancode[0x4a] = '/' ;
scancode[0x29] = ' ' ;
shift_scancode[0x1c] = 'A' ;
shift_scancode[0x32] = 'B' ;
shift_scancode[0x21] = 'C' ;
shift_scancode[0x23] = 'D' ;
shift_scancode[0x24] = 'E' ;
shift_scancode[0x2b] = 'F' ;
shift_scancode[0x34] = 'G' ;
shift_scancode[0x33] = 'H' ;
shift_scancode[0x43] = 'I' ;
shift_scancode[0x3b] = 'J' ;
shift_scancode[0x42] = 'K' ;
shift_scancode[0x4b] = 'L' ;
shift_scancode[0x3a] = 'M' ;
shift_scancode[0x31] = 'N' ;
shift_scancode[0x44] = 'O' ;
shift_scancode[0x4d] = 'P' ;
shift_scancode[0x15] = 'Q' ;
shift_scancode[0x2d] = 'R' ;
shift_scancode[0x1b] = 'S' ;
shift_scancode[0x2c] = 'T' ;
shift_scancode[0x3c] = 'U' ;
shift_scancode[0x2a] = 'V' ;
shift_scancode[0x1d] = 'W' ;
shift_scancode[0x22] = 'X' ;
shift_scancode[0x35] = 'Y' ;
shift_scancode[0x1a] = 'Z' ;
shift_scancode[0x45] = ')' ;
shift_scancode[0x16] = '!' ;
shift_scancode[0x1e] = '@' ;
shift_scancode[0x26] = '#' ;
shift_scancode[0x25] = '$' ;
shift_scancode[0x2e] = '%' ;
shift_scancode[0x36] = '^' ;
shift_scancode[0x3d] = '&' ;
shift_scancode[0x3e] = '*' ;
shift_scancode[0x46] = '(' ;
shift_scancode[0x0e] = '~' ;
shift_scancode[0x4e] = '_' ;
shift_scancode[0x55] = '+' ;
shift_scancode[0x5d] = '|' ;
shift_scancode[0x54] = '{' ;
shift_scancode[0x5b] = '}' ;
shift_scancode[0x4c] = ':' ;
shift_scancode[0x52] = '"' ;
shift_scancode[0x41] = '<' ;
shift_scancode[0x49] = '>' ;
shift_scancode[0x4a] = '?' ;
shift_scancode[0x29] = ' ' ;
while(*buffer != 0x5a) {
if(*buffer == 0x12) {
*buffer = 0 ;
if(shift_scancode[(int)*buffer] != 0) {
input[arg] = shift_scancode[(int)*buffer] ;
printc(shift_scancode[(int)*buffer]) ;
*buffer = 0 ;
arg++ ;
}
if(*buffer == 0xf0) {
*buffer = 0 ;
*buffer = 0 ;
}
}
else if(*buffer == 0xf0) {
*buffer = 0 ;
*buffer = 0 ;
}
else if(*buffer == 0x66) {
arg-- ;
if(arg >= 0) {
backspace() ;
}
else {
arg = 0 ;
}
}
else if(scancode[(int)*buffer] != 0) {
input[arg] = scancode[(int)*buffer] ;
printc(scancode[(int)*buffer]) ;
*buffer = 0 ;
arg++ ;
}
}
input[arg] = '\0' ;
*buffer = 0 ;
*buffer = 0 ;
return input ;
}
void main() {
char * x = (char*)0x502 ;
char * y = (char*)0x503 ;
*x = 0 ;
*y = 0 ;
println("------------------------------Welcome to Skull OS------------------------------") ;
println("Boot Successful") ;
}
The commands used to make the os are :
nasm third_stage.asm -f elf -o third_stage.o
gcc -m32 -ffreestanding -c os.c -o os.o
ld -m elf_i386 -o os.bin -Ttext 0x100000 os.o third_stage.o --oformat binary
dd seek=0 if=boot of=os.img
dd seek=1 if=second_stage of=os.img
dd seek=2 if=os.bin of=os.img
dd seek=17 if=/dev/zero of=os.img count=1 bs=512
In the beginning I tried to load my OS at 0x8000 but the execution just stops halfway. My OS is being tested under VirtualBox.