Page 1 of 1
Bizarre Kernel Issue
Posted: Thu Jul 09, 2009 5:54 pm
by brodeur235
Here is my short kernel code:
Code: Select all
;||=====================================================||
;|| KERNEL ||
;||=====================================================||
[BITS 32]
;||======================================||
;|| K_MAIN ||
;||======================================||
k_main:
; setup segments and stack
mov ax,0x10
mov ds,ax
mov es,ax
mov fs,ax
mov gs,ax
mov ss,ax
mov esp,0x0000D000
;THE FOLLOWING FUNCTION CALL IS THE ISSUE
mov al,0x1B
call k_set_screen_colors
jmp (($-k_main)+KERNEL_OFFSET)
end_k_main:
;||======================================||
;|| END K_MAIN ||
;||======================================||
;||======================================||
;|| K_SCREEN ||
;||======================================||
k_screen:
k_set_screen_colors:
mov ebx,0x00B8001
mov ecx,(80*25)
.kssc_set_next:
mov BYTE [ds:ebx],al
add ebx,0x2
loop .kssc_set_next
ret
k_print:
mov ebx,0x000B8000
imul eax,160
add ebx,eax
.kp_next_char:
lodsb
cmp al,0x00
jz .kp_done
mov BYTE [ds:ebx],al
add ebx,0x2
jmp .kp_next_char
.kp_done:
ret
end_k_screen:
;||======================================||
;|| END K_SCREEN ||
;||======================================||
kl_data:
dbg_msg db "Debug MSG.",0x00
kl_padding:
; pad to kernel size
times (KERNEL_SIZE - ($-k_main)) db 0x00
;||=====================================================||
;|| END KERNEL ||
;||=====================================================||
The part right under ";THE FOLLOWING FUNCTION CALL IS THE ISSUE":
Code: Select all
mov al,0x1B
call k_set_screen_colors
Is VERY wierd. If I do ANYTHING but call the function and that one function alone, I get a "stuck" error from vbox. If I even comment those two lines out, then I get the stuck error. However if this function is the ONLY thing I call in EXACTLY that manner, everything works as expected. Here is what the error page looks like:
EDIT: Here is the VBox log:
http://pastebin.ca/1490214 I don't understand it at all.
What is the problem here?
All help appreciated,
Brodeur235
Re: Bizarre Kernel Issue
Posted: Thu Jul 09, 2009 6:24 pm
by yemista
maybe KERNEL_OFFSET is the problem? What is is being set to? If you want an infinite loop, use
Also, I dont know virtual box, but maybe you should try to use bochs? That error message is hard to debug. It would be more helpful if you could provide us with a register dump before and after the crash. I am suggesting bochs because it puts out a lot of information when it crashes in bochsout.txt. If virtual box does the same, show us some of the output
Re: Bizarre Kernel Issue
Posted: Thu Jul 09, 2009 6:40 pm
by brodeur235
KERNEL_OFFSET is the offset in memory that the kernel was loaded to. The reason I don't use the loop you suggested is because my bootloader is in the same source file, at the beginning of it. And just before the bootloader I ORGed the file to 0x7C00 for the bootloder. So, whenever I want to JMP somewhere in the kernel, I have to say (($-k_main)+KERNEL_OFFSET) where k_main is the beginning of the kernel and KERNEL_OFFSET is the kernel's offset in memory. For clarity's sake, here is the whole source:
Code: Select all
; general sizes (in bytes)
%define SECTOR_SIZE 0x0200
%define KILOBYTE_SIZE 0x0002 * SECTOR_SIZE
%define MEGABYTE_SIZE 0x0200 * KILOBYTE_SIZE
%define GIGABYTE_SIZE 0x0200 * MEGABYTE_SIZE
%define PAGE_SIZE 0x0004 * KILOBYTE_SIZE
; kernel disk info
%define KERNEL_DRIVE 0x0000
%define KERNEL_HEAD 0x0000
%define KERNEL_TRACK 0x0000
%define KERNEL_SECTOR 0x0002
%define KERNEL_SIZE PAGE_SIZE * 2
; kernel memory info
%define KERNEL_OFFSET 0x00000040
; kernel screen module
%define SCREEN_WIDTH 80
%define SCREEN_HEIGHT 25
%define BLACK 0x00
%define BLUE 0x01
%define GREEN 0x02
%define CYAN 0x03
%define RED 0x04
%define MAGENTA 0x05
%define BROWN 0x06
%define LIGHT_GREY 0x07
%define DARK_GREY 0x08
%define LIGHT_BLUE 0x09
%define LIGHT_GREEN 0x0A
%define LIGHT_CYAN 0x0B
%define LIGHT_RED 0x0C
%define LIGHT_MAGENTA 0x0D
%define LIGHT_BROWN 0x0E
%define WHITE 0x0F
;||=====================================================||
;|| BOOT LOADER ||
;||=====================================================||
[BITS 16]
[ORG 0x7C00]
bl_main:
; setup stack
xor ax,ax
mov ss,ax
mov sp,0x8000
; setup data
xor ax,ax
mov ds,ax
; load kernel
call kernel_loader
; load gdt
lgdt [gdt_descriptor]
; enter pmode
mov eax,cr0
or eax,1
mov cr0,eax
; jmp to kernel
jmp 0x8:KERNEL_OFFSET
kernel_loader:
; determine # of sectors to load
; dx:ax / bx = ax remainder dx
mov dx,0x0000
mov ax,KERNEL_SIZE
mov bx,SECTOR_SIZE
div bx
; ensure size is even number of sectors
cmp dx,0x0000
jnz .kl_error
; setup to loop thru sectors
mov cx,ax
mov BYTE [sector_current], KERNEL_SECTOR
mov WORD [offset_current], KERNEL_OFFSET
.lk_copy_sector:
push cx
; copy current sector
; disk loc -> es:bx in mem
mov dh,KERNEL_DRIVE
mov dl,KERNEL_HEAD
mov ch,KERNEL_TRACK
mov cl,[sector_current]
xor bx,bx
mov es,bx
mov bx,[offset_current]
mov ah,0x02
mov al,0x01
int 0x13
; prepare for next sector
add WORD [offset_current],SECTOR_SIZE
inc BYTE [sector_current]
pop cx
loop .lk_copy_sector
; completed
jmp .kl_success
; error section
.kl_error:
jmp $
; success section
.kl_success:
ret
gdt_entries:
; null entry
db 00000000b
db 00000000b
db 00000000b
db 00000000b
db 00000000b
db 00000000b
db 00000000b
db 00000000b
; code segment descriptor: OFFSET = 0x0008
db 11111111b
db 11111111b
db 00000000b
db 00000000b
db 00000000b
db 10011010b
db 11001111b
db 00000000b
; data segment descriptor: OFFSET = 0x0010
db 11111111b
db 11111111b
db 00000000b
db 00000000b
db 00000000b
db 10010010b
db 11001111b
db 00000000b
gdt_descriptor:
; table size (2 bytes)
dw (gdt_descriptor - gdt_entries)
; table offset (4 bytes)
dd gdt_entries
bl_data:
; kernel_load data
sector_current db 0x00 ; KERNEL_SECTOR
offset_current dw 0x0000 ; KERNEL_OFFSET
bl_padding:
;pad to 510 bytes
times (512-2-($-bl_main)) db 0x00
;make disk bootable w/ 2 byte flag
db 0x55
db 0xAA
;||=====================================================||
;|| END BOOT LOADER ||
;||=====================================================||
;||=====================================================||
;|| KERNEL ||
;||=====================================================||
[BITS 32]
;||======================================||
;|| K_MAIN ||
;||======================================||
k_main:
; setup segments and stack
mov ax,0x10
mov ds,ax
mov es,ax
mov fs,ax
mov gs,ax
mov ss,ax
mov esp,0x0000D000
mov al,0x78
call k_set_screen_colors
jmp (($-k_main)+KERNEL_OFFSET)
end_k_main:
;||======================================||
;|| END K_MAIN ||
;||======================================||
;||======================================||
;|| K_SCREEN ||
;||======================================||
k_screen:
k_set_screen_colors:
mov ebx,0x00B8001
mov ecx,(80*25)
.kssc_set_next:
mov BYTE [ds:ebx],al
add ebx,0x2
loop .kssc_set_next
ret
k_print:
mov ebx,0x000B8000
imul eax,160
add ebx,eax
.kp_next_char:
lodsb
cmp al,0x00
jz .kp_done
mov BYTE [ds:ebx],al
add ebx,0x2
jmp .kp_next_char
.kp_done:
ret
end_k_screen:
;||======================================||
;|| END K_SCREEN ||
;||======================================||
kl_data:
dbg_msg db "Debug MSG.",0x00
kl_padding:
; pad to kernel size
times (KERNEL_SIZE - ($-k_main)) db 0x00
;||=====================================================||
;|| END KERNEL ||
;||=====================================================||
Also yemista, I'm staying at a hotel in Boston tonight
. Small world, eh?
Brodeur235
Re: Bizarre Kernel Issue
Posted: Thu Jul 09, 2009 7:48 pm
by yemista
In general, its not wise to define offsets like that. If you ever change something youll have to recalculate it. Let the linker set them for you.
You should be able to do jmp 0x8:kmain rather than jumping to the kernel offset, and loop: jmp loop should work as well. You can also change your org, which might be a good idea. The way you are doing it, since it is all one source file, all your code thinks it starts at 0x7c00, even though you are loading it somewhere else. That could be screwing things up. I suggest you break it down into different source files, and learn about linker scripts. When you make a function call, a physical address is supplied. Since it is all one source file, with [org 0x7c00] at the top, every function takes that as its base, even though you seem to be loading the kernel to 0x40, and that could be screwing things up. try to debug it step by step, and show us the instruction that fails.
Re: Bizarre Kernel Issue
Posted: Thu Jul 09, 2009 7:55 pm
by mathematician
Near jumps are relative, so where you loaded the file is irrelevant. jmp $ will get you into an infinite loop.
On the other hand, far jumps are absolute, so if your kernel was located at 0x8000 say, and your gdt is initialised for the flat memory model, the far jump to the kernel would need to tanslate into jmp 0x08:0x8000.
Re: Bizarre Kernel Issue
Posted: Thu Jul 09, 2009 8:10 pm
by brodeur235
Near jumps are relative, so where you loaded the file is irrelevant. jmp $ will get you into an infinite loop.
As far as I can tell, that did it. I no longer get the vbox error. I have a couple flights to make tommorow and I've got to go to bed, but I'll get back to this thread if it turns out that didn't do it.. Thanks for the advice,
Brodeur235
Re: Bizarre Kernel Issue
Posted: Fri Jul 10, 2009 7:47 am
by Combuster
Code: Select all
jmp 0x8:KERNEL_OFFSET ; execute IVT
Other than that, virtual box logs do provide a crashdump (note the EIP):
Code: Select all
# 00:00:04.916 Guest CPUM (VCPU 0) state: se
# 00:00:04.916 eax=60000010 ebx=00000040 ecx=00000000 edx=00000000 esi=0000c440 edi=0000ffde
# 00:00:04.916 eip=c48305bd esp=0000cff4 ebp=00000000 iopl=0 rf nv up ei pl zr na pe nc
# 00:00:04.916 cs={0008 base=0000000000000000 limit=ffffffff flags=0000c09b} dr0=00000000 dr1=00000000
# 00:00:04.916 ds={0010 base=0000000000000000 limit=ffffffff flags=0000c093} dr2=00000000 dr3=00000000
# 00:00:04.916 es={0010 base=0000000000000000 limit=ffffffff flags=0000c093} dr4=00000000 dr5=00000000
# 00:00:04.916 fs={0010 base=0000000000000000 limit=ffffffff flags=0000c093} dr6=ffff0ff0 dr7=00000400
# 00:00:04.916 gs={0010 base=0000000000000000 limit=ffffffff flags=0000c093} cr0=60000011 cr2=00000000
# 00:00:04.916 ss={0010 base=0000000000000000 limit=ffffffff flags=0000c093} cr3=00000000 cr4=00000000
# 00:00:04.916 gdtr=0000000000007c6e:0018 idtr=0000000000000000:ffff eflags=00010202
# 00:00:04.916 ldtr={0000 base=00000000 limit=00000000 flags=00000082}
# 00:00:04.916 tr ={0000 base=00000000 limit=0000ffff flags=0000008b}
# 00:00:04.916 SysEnter={cs=0000 eip=00000000 esp=00000000}
By the looks of it, it made a jump instruction out of the int 0x10 vector...