Kernel prob
Posted: Tue Jan 11, 2005 12:00 am
Hi,
I've got a problem in my tiny kernel. If I declare a variable in my main function or if I make a call to a function, Bochs reboots (cf. Bochs output). Here are my files. Could somebody check those (especially stack creation and my ld -Ttext parameter).
Thanks.
Christian Vincenot
COMPIL.SH :
-----------------
#Compile the bootsector
nasm myboot.asm -o bootsect
#Compile the kernel objects
gcc -Wall -ffreestanding -fno-builtin -nodefaultlibs -c -o drivers/bochs.o drivers/bochs.c
gcc -Wall -ffreestanding -fno-builtin -nodefaultlibs -c kern.c -o kern.o
#LD : link & set entry point & relocation @10000h
#First ld is to display unresolved symbols (which isn't done with -i)
ld -e main -Ttext 0x10000 --oformat binary -o morpos.temp kern.o drivers/bochs.o
ld -i -e main -Ttext 0x10000 -o morpos.temp kern.o drivers/bochs.o
#OBJCOPY => remove .note & .comment and convert ELF -> Binary
objcopy -R .note -R .comment -S -O binary morpos.temp morpos
#rm morpos.temp
#Create the bootdisk
dd if=/dev/zero of=kernel bs=512 count=2880
dd if=bootsect of=kernel conv=notrunc
dd if=morpos of=kernel conv=notrunc bs=512 seek=1
MYBOOT.ASM :
--------------------
[ORG 7C00h]
[BITS 16]
;------------------DEFS--------------------------------------;
KSTART equ 2 ; Where's the kernel?
KSIZE equ 4 ; Size of kernel in blocks
KSEG equ 1000h ; Where we'll throw the kernel first
;-----------------CODE---------------------------------------;
;Set up our stack
;mov ax, BIOS_DROP ;
;mov ds, ax ;AX = DS = ES = BIOS_DROP
;mov es, ax ;
;mov ax, 0x8000
;mov ss, ax ; let's set up our stack from 0x8000
;mov sp, 0xf000 ; to 0xf000
;----------CODE AGAIN------------------------------------------;
; Let's start the serious stuff
mov si,takeoff
call bprint ; Greetings !!
;Copy the kernel
mov ax, 0x200 + KSIZE ; service: AH=0x2 (copy), AL=KERNEL_SIZE sectors
push word KSEG ; ES <- KERNEL_SEG (copy destination)
pop es ;
xor bx, bx ; BX <- 0 (dunno if that has to be...)
mov cx, KSTART ; CX <- KERNEL_START (copy source)
xor dx, dx ; DX <- 0
int 13h ; SHOOT !!
jnc done
mov si, error
call bprint ; Mayday !!
call head_stop
jmp $
done:
mov si, success
call bprint
call head_stop
cli ; Disable interrupts
;Enable A20 Gate ; 20 bits address => 24 bits address
mov ax, 0x2401 ; This is the BIOS method. Not the best for compatibility
int 0x15 ; but simpler than the kbd controller one
;Enable A20 Gate (damn 2nd method.... Bochs doesn't support the first one)
in al, 0x92
or al, 0x02
out 0x92, al
;Loading the GDT
xor ax, ax ; ax = ds = 0 (used by lgdt)
mov ds, ax
lgdt [gdtr] ; Load the GDT (segmentation)
;Switching to protected mode
mov eax, cr0
or al, 1 ; Protected mode bit <- 0
mov cr0, eax
;jmp $
jmp SYS_CODE_SEL:clear_pipe
;---------------------- PM--------------------------------------------;
[BITS 32]
;Clear the pipeline of any 16 bits instructions left (with the long jump)
clear_pipe:
mov ax, SYS_DATA_SEL ; Update DATA Segment
mov ds, ax
mov ss, ax ; Set the stack
mov esp, 9000h
mov ebp, esp
k_launch:
;jmp $ ; Uncomment this for testing
jmp SYS_CODE_SEL:10000h ; Give the hand to the kernel
;-----------------VARS---------------------------------------------------;
; Should always be declared after the stack's up !! (I think at least =0)
takeoff db "Chris' Boot Sector taking off...",13,10,0
success db "Bootsector: Kernel copy successful !!",13,10,0
error db "Bootsector: Kernel copy error >O<",13,10,0
;GDT Table Definition for segmentation (Basic Flat Model)
gdtr:
dw gdt_end - gdt - 1 ; GDT limit
dd gdt ; GDT base
gdt:
times 8 db 0 ; NULL Descriptor
SYS_CODE_SEL equ $-gdt
dw 0xFFFF ; limit 15:0
dw 0 ; base 15:0
db 0 ; base 23:16
db 0x9A ; type = present, ring 0, code, non-conforming, readable
db 0xCF ; page granular, 32-bit
db 0 ; base 31:24
SYS_DATA_SEL equ $-gdt
dw 0xFFFF ; limit 15:0
dw 0 ; base 15:0
db 0 ; base 23:16
db 0x92 ; type = present, ring 0, data, expand-up, writable
db 0xCF ; page granular, 32-bit
db 0 ; base 31:24
gdt_end:
;-------------------MISC FUNCS-------------------------------------------;
[BITS 16]
;Very simplified printf in real mode
bprint:
push ax
push bx
.next:
lodsb ; Load ds:si word to al
cmp al, 0 ; if 0x0 => end of string
jz .end
mov ah, 0x0E ; 0x0e BIOS service -> print to screen
mov bx, 0x0004 ; bx -> attribut (red), al -> caractere ascii
int 0x10 ; INT !!
jmp .next
.end:
pop bx
pop ax
ret
; Stop the floppy motor head
head_stop:
push cx
mov cx, 0400h
.callBIOS int 08h ; stop floppy motor
loop .callBIOS
pop cx
ret
;-------------------Boot sector signature-------------------------------;
times 510 - ($ - $$) db 0
dw 0xAA55
KERN.C :
------------
#include "main.h"
#include "drivers/bochs.h"
void main(void) {
morpos_main();
idle_task();
}
void morpos_main() {
}
I've got a problem in my tiny kernel. If I declare a variable in my main function or if I make a call to a function, Bochs reboots (cf. Bochs output). Here are my files. Could somebody check those (especially stack creation and my ld -Ttext parameter).
Thanks.
Christian Vincenot
COMPIL.SH :
-----------------
#Compile the bootsector
nasm myboot.asm -o bootsect
#Compile the kernel objects
gcc -Wall -ffreestanding -fno-builtin -nodefaultlibs -c -o drivers/bochs.o drivers/bochs.c
gcc -Wall -ffreestanding -fno-builtin -nodefaultlibs -c kern.c -o kern.o
#LD : link & set entry point & relocation @10000h
#First ld is to display unresolved symbols (which isn't done with -i)
ld -e main -Ttext 0x10000 --oformat binary -o morpos.temp kern.o drivers/bochs.o
ld -i -e main -Ttext 0x10000 -o morpos.temp kern.o drivers/bochs.o
#OBJCOPY => remove .note & .comment and convert ELF -> Binary
objcopy -R .note -R .comment -S -O binary morpos.temp morpos
#rm morpos.temp
#Create the bootdisk
dd if=/dev/zero of=kernel bs=512 count=2880
dd if=bootsect of=kernel conv=notrunc
dd if=morpos of=kernel conv=notrunc bs=512 seek=1
MYBOOT.ASM :
--------------------
[ORG 7C00h]
[BITS 16]
;------------------DEFS--------------------------------------;
KSTART equ 2 ; Where's the kernel?
KSIZE equ 4 ; Size of kernel in blocks
KSEG equ 1000h ; Where we'll throw the kernel first
;-----------------CODE---------------------------------------;
;Set up our stack
;mov ax, BIOS_DROP ;
;mov ds, ax ;AX = DS = ES = BIOS_DROP
;mov es, ax ;
;mov ax, 0x8000
;mov ss, ax ; let's set up our stack from 0x8000
;mov sp, 0xf000 ; to 0xf000
;----------CODE AGAIN------------------------------------------;
; Let's start the serious stuff
mov si,takeoff
call bprint ; Greetings !!
;Copy the kernel
mov ax, 0x200 + KSIZE ; service: AH=0x2 (copy), AL=KERNEL_SIZE sectors
push word KSEG ; ES <- KERNEL_SEG (copy destination)
pop es ;
xor bx, bx ; BX <- 0 (dunno if that has to be...)
mov cx, KSTART ; CX <- KERNEL_START (copy source)
xor dx, dx ; DX <- 0
int 13h ; SHOOT !!
jnc done
mov si, error
call bprint ; Mayday !!
call head_stop
jmp $
done:
mov si, success
call bprint
call head_stop
cli ; Disable interrupts
;Enable A20 Gate ; 20 bits address => 24 bits address
mov ax, 0x2401 ; This is the BIOS method. Not the best for compatibility
int 0x15 ; but simpler than the kbd controller one
;Enable A20 Gate (damn 2nd method.... Bochs doesn't support the first one)
in al, 0x92
or al, 0x02
out 0x92, al
;Loading the GDT
xor ax, ax ; ax = ds = 0 (used by lgdt)
mov ds, ax
lgdt [gdtr] ; Load the GDT (segmentation)
;Switching to protected mode
mov eax, cr0
or al, 1 ; Protected mode bit <- 0
mov cr0, eax
;jmp $
jmp SYS_CODE_SEL:clear_pipe
;---------------------- PM--------------------------------------------;
[BITS 32]
;Clear the pipeline of any 16 bits instructions left (with the long jump)
clear_pipe:
mov ax, SYS_DATA_SEL ; Update DATA Segment
mov ds, ax
mov ss, ax ; Set the stack
mov esp, 9000h
mov ebp, esp
k_launch:
;jmp $ ; Uncomment this for testing
jmp SYS_CODE_SEL:10000h ; Give the hand to the kernel
;-----------------VARS---------------------------------------------------;
; Should always be declared after the stack's up !! (I think at least =0)
takeoff db "Chris' Boot Sector taking off...",13,10,0
success db "Bootsector: Kernel copy successful !!",13,10,0
error db "Bootsector: Kernel copy error >O<",13,10,0
;GDT Table Definition for segmentation (Basic Flat Model)
gdtr:
dw gdt_end - gdt - 1 ; GDT limit
dd gdt ; GDT base
gdt:
times 8 db 0 ; NULL Descriptor
SYS_CODE_SEL equ $-gdt
dw 0xFFFF ; limit 15:0
dw 0 ; base 15:0
db 0 ; base 23:16
db 0x9A ; type = present, ring 0, code, non-conforming, readable
db 0xCF ; page granular, 32-bit
db 0 ; base 31:24
SYS_DATA_SEL equ $-gdt
dw 0xFFFF ; limit 15:0
dw 0 ; base 15:0
db 0 ; base 23:16
db 0x92 ; type = present, ring 0, data, expand-up, writable
db 0xCF ; page granular, 32-bit
db 0 ; base 31:24
gdt_end:
;-------------------MISC FUNCS-------------------------------------------;
[BITS 16]
;Very simplified printf in real mode
bprint:
push ax
push bx
.next:
lodsb ; Load ds:si word to al
cmp al, 0 ; if 0x0 => end of string
jz .end
mov ah, 0x0E ; 0x0e BIOS service -> print to screen
mov bx, 0x0004 ; bx -> attribut (red), al -> caractere ascii
int 0x10 ; INT !!
jmp .next
.end:
pop bx
pop ax
ret
; Stop the floppy motor head
head_stop:
push cx
mov cx, 0400h
.callBIOS int 08h ; stop floppy motor
loop .callBIOS
pop cx
ret
;-------------------Boot sector signature-------------------------------;
times 510 - ($ - $$) db 0
dw 0xAA55
KERN.C :
------------
#include "main.h"
#include "drivers/bochs.h"
void main(void) {
morpos_main();
idle_task();
}
void morpos_main() {
}