0

My first question here

I'm working on a simple operating system in 32-bit mode (just for fun) but I ran into a problem which is I can't jump to my kernel after switching to (32-bit) protected mode

Here's my bootloader.asm

[  BITS 16 ]
[ ORG 0x7c00 ]

jmp  start_boot

start_boot:

KERNEL_OFFSET equ 0x1000
mov [BOOT_DRIVE] , dl

mov bp , 0x9000
mov sp , bp

mov bx , MSG_REAL_MODE
call print

call load_kernel

mov ax , [0x1000]
mov word [reg16] , ax
call print_hex

call switch_to_pm


jmp $



[ BITS 16 ]

load_kernel :
mov bx , MSG_LOAD_KERNEL
call print

mov bx , KERNEL_OFFSET
mov dh , 15
mov dl , [BOOT_DRIVE]
call disk_load

ret

[ BITS 32 ]


;Including files
%include "bootloader/include/print_pm.asm"
%include "bootloader/include/print_hex_pm.asm"


start_pm:
mov ebx , MSG_PRO_MODE
call print_pm

mov ax , [0x1000]
mov word [reg16] , ax
call print_hex_pm


jmp $

jmp CODE_SEG:0x1000



;Including files

%include "bootloader/include/print.asm"
%include "bootloader/include/print_hex.asm"
%include "bootloader/include/disk.asm"
%include "bootloader/include/gdt.asm"
%include "bootloader/include/switch_to_pm.asm"


;Data 
BOOT_DRIVE db 0
check db "check" , 0
MSG_LOAD_KERNEL db "loading Kernel" , 0
MSG_REAL_MODE db "Boot 16" , 0
MSG_PRO_MODE db "Boot 32 " , 0

;Padding 
times 510- ($ -$$) db 0
dw 0xAA55

instead of

call KERNEL_OFFSET 

I've used

jmp KERNEL_OFFSET:0x0

or

jmp CODE_SEG:KERNEL_OFFSET

but none of these works

BUT IF I just loaded my kernel without switching to protected mode it works

BTW here's my disk.asm included in bootloader.asm

disk_load:
push dx
mov ah , 0x02
mov al , dh
mov ch , 0x00
mov dh , 0x00
mov cl , 0x02

int 0x13

jc .error
pop dx
cmp dh , al
jne .error
ret

.error :
    mov bx , Err
    call print 
    call disk_load


;Data
Err db "Disk error" , 0

EDIT : all what's included switch_to_pm.asm

[ BITS 16 ]

switch_to_pm:
CLI
LGDT [ gdtd ]


MOV EAX , CR0
OR EAX , 0x1
MOV CR0 , EAX
JMP CODE_SEG:init_pm

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
[ BITS 32 ]

init_pm:


MOV AX , DATA_SEG
MOV DS , AX
MOV ES , AX
MOV SS ,AX
MOV FS , AX
MOV GS , AX

MOV EBP , 0x90000
MOV ESP , EBP


CALL start_pm

gdt.asm

;GDT
gdt_start: 

gdt_null: 
dd 0x0          ; null descriptor
dd 0x0 

; Offset 0x8 bytes from start of GDT: Descriptor code therfore is 8

gdt_code:               ; code descriptor
dw 0xFFFF           ; limit low
dw 0x0              ; base low
db 0x0              ; base middle
db 10011010b            ; access
db 11001111b            ; granularity
db 0x0              ; base high

; Offset 16 bytes (0x10) from start of GDT. Descriptor code therfore is 0x10.

 gdt_data:              ; data descriptor
dw 0xFFFF           ; limit low (Same as code)
dw 0x0              ; base low
db 0x0              ; base middle
db 10010010b            ; access
db 11001111b            ; granularity
db 0x0              ; base high

;...Other descriptors begin at offset 0x18. Remember that each descriptor is 8 bytes in     size?
; Add other descriptors for Ring 3 applications, stack, whatever here...

gdt_end:

gdtd: 
dw gdt_end - gdt_start - 1  ; limit (Size of GDT)
dd gdt_start            ; base of GDT

CODE_SEG equ gdt_code - gdt_start
DATA_SEG equ gdt_data - gdt_start

Sorry for My mistakes any way I edited the title added most of what's included and tried Babysteps and I used a debugger and the kernel is loaded so where's the problem

  • Please make all files available, and fix the misleading title. As for the problem, make sure you know where your kernel is loaded in the protected mode memory map. Also, learn to use a debugger. – Jester May 28 '13 at 13:09

3 Answers3

0

Too much code hidden in the %include files to see what's really going on here, Mohamed.

jmp CODE_SEG:KERNEL_OFFSET ought to work, but I would expect it to be part of the switch_to_pm routine.

You appear to be ignoring segment registers which need to be set! I highly recommend http://www.osdev.org - start from "baby steps" and work back up to it...

Frank Kotler
  • 3,079
  • 2
  • 14
  • 9
  • Thanks Mohamed. That helps, but I'm afraid I still don't see the problem. Since you've got `cs` loaded, just `jmp KERNEL_OFFSET` "ought" to work. Reloading `cs` "shouldn't" hurt. Your disk read routine loads sector 2 (and following) to `es:bx`. We don't actually see what `es` is, but I ASSume it's the same as `ds` (you might want to make that explicit - can't hurt - should be zero). I ASSume that your kernel actually resided at sector 2. Sorry I can't help you more... – Frank Kotler May 28 '13 at 20:06
0

The reason we ask for all parts, and not just "most of what's included" is so that we can reproduce exactly what you have, and do that without too much hassle. We are trying to help you after all.

Anyway, because you still haven't provided everything (notably the print routines and the actual kernel) I had to remove some stuff to get it to assemble without error and added my simple kernel consisting of a jmp $. I can tell you it works fine with the jmp CODE_SEG:KERNEL_OFFSET and the jmp KERNEL_OFFSET both.

Jester
  • 56,577
  • 4
  • 81
  • 125
0

Can you paste the bochs debug or something ?In my experience,you may lgdt a wrong gdt.Sometimes the address is wrong,sometimes you gdt is wrong about the limit,check the gdt carefully may help you.