Page 1 of 1

Kernel prob

Posted: Tue Jan 11, 2005 12:00 am
by onizuka
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() {
}

Re: Kernel prob

Posted: Tue Jan 11, 2005 12:00 am
by onizuka
Here is some more. Dunno if it's linked with the problem but looks weird. The call to morpos_main seems to use a wrong address.

OBJDUMP :
---------------

[mulder@Spooky os]$ objdump -t morpos.temp

morpos.temp: file format elf32-i386

SYMBOL TABLE:
00010000 l d .text 00000000
00000000 l d *ABS* 00000000
00000000 l d .data 00000000
00000000 l d .bss 00000000
00000000 l d .comment 00000000
00000000 l d .note.GNU-stack 00000000
00000000 l d *ABS* 00000000
00000000 l d *ABS* 00000000
00000000 l d *ABS* 00000000
00000000 l df *ABS* 00000000 kern.c
00000000 l df *ABS* 00000000 bochs.c
00010017 g F .text 0000000d morpos_main <----- !!!
00010024 g F .text 0000001c bochs_print
00010000 g F .text 00000017 main

BOCHS DEBUGGER OUTPUT :
---------------------------------------

<bochs:31> u 0x10000 0x100cf
00010000: ( ): push ebp ; 55
00010001: ( ): mov ebp, esp ; 89e5
00010003: ( ): sub esp, 0x8 ; 83ec08
00010006: ( ): and esp, 0xfffffff0 ; 83e4f0
00010009: ( ): mov eax, 0x0 ; b800000000
0001000e: ( ): sub esp, eax ; 29c4
00010010: ( ): call 0x10011 ; e8fcffffff <---- should be a call 0x10017 ??
00010015: ( ): jmp 0x10015 ; ebfe
00010017: ( ): push ebp ; 55
(...)

Re: Kernel prob

Posted: Wed Jan 12, 2005 12:00 am
by theubu
yo!! main doesn't appear to halt the machine is probably tripple faulting?

Re: Kernel prob

Posted: Wed Jan 12, 2005 12:00 am
by [AlAdDiN]
hi,
I did not checked all your code, but i have a little idea :
you linked ur kernel with his command :
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
so i'll assume that ur kernel will be loaded and launched from 1000h, if it is not the case u have to correct it...

now ur boot sector seems to be ok, but it doesn't move itself before loading kernel, i think you kernel is overwriting a part of ur bootcode or somthing

if you don't know how to move ur boot sector at execution time here the code i'm using

Code: Select all

start:
cli
mov    AX,9000h   ;<--- dest offset address
mov    SS,AX
mov    SP,0h
sti
mov es, ax
push ax
xor ax, ax
mov ds, ax
mov ax, 7c00h
mov si, ax
mov di, ax
mov cx, 0100h
rep movsw
mov ax, go
push ax

retf   ;simulate a retf

go:   ; congratulations u have moved ur boot sector

;here write ur normal boorsector code 

I suggest you to move ur kernel to the 1Mb address, this avoid you lot of problems, and let you use the first Mb for other funny things (vm86 for example) ;)


try this and tell me wut do you get

btw : i have a boot code (in two stages) that can load two files (a setup and a kernel), the setup code check configurations, switch to pm, move kernel to 1Mb and run it.
if you want to use it take a look here http://xos.freezee.org/beta (comments are in freanch)

Re: Kernel prob

Posted: Thu Jan 13, 2005 12:00 am
by JAAman
no that cant be the problem since he's loading it ABOVE his boot sector (0x10000 > 0x7C00)

I would certainly not advise loading it to 1MB as it is a lot more complicated

at the location hes at now the only thing he has to worry about is video ram at 0xA0000 which gives him 576k -- if you need to load more than that much in the boot sector something is wrong