2013-05-27 44 views
0

我的第一個問題在這裏跳轉到裝配切換到保護模式後內核

我正在一個簡單的操作系統在32位模式下(只是爲了好玩),但我跑進這是我能一個問題「T跳到我的內核切換到(32位)保護模式後

這裏是我的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 

,而不是

call KERNEL_OFFSET 

我用

jmp KERNEL_OFFSET:0x0 

or 

jmp CODE_SEG:KERNEL_OFFSET 

但這些作品

但如果我只是加載我的內核而無需切換到保護模式下,它的工作原理

BTW這裏是包含在引導程序我disk.asm。 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 

編輯:所有包含內容 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 

對不起,我錯什麼方法,我編輯了標題中加入最包含的內容 並試圖Babysteps的,我用一個調試器和內核載入所以哪來的問題

+0

請使所有文件可用,並修復誤導標題。至於這個問題,確保你知道內核在保護模式內存映射中的加載位置。另外,學習使用調試器。 – Jester

回答

0

Mohamed在文件%include中隱藏了太多代碼以查看真實情況。

jmp CODE_SEG:KERNEL_OFFSET應該工作,但我希望它是switch_to_pm例程的一部分。

您似乎忽略了需要設置的段寄存器!我強烈建議http://www.osdev.org - 從「嬰兒學步」開始,然後備份到它...

+0

謝謝穆罕默德。這有幫助,但我恐怕仍然沒有看到問題。既然你已經加載了'cs',只是'jmp KERNEL_OFFSET''應該「工作。重新加載'cs'「不應該」受到傷害。您的磁盤讀取例程將扇區2(及其後)加載到'es:bx'。我們實際上並沒有看到'es'是什麼,但我假設它與'ds'相同(你可能想明確表示 - 不能傷害 - 應該爲零)。我假設你的內核實際上駐留在扇區2中。對不起,我不能幫你更多... –

0

我們要求所有部分的原因,並不僅僅是「大多數包含的內容的」是讓我們可以精確再現你有什麼,並沒有太多的麻煩做到這一點。畢竟,我們正試圖幫助你。無論如何,因爲你還沒有提供所有的東西(特別是打印例程和實際的內核),所以我不得不刪除一些東西來使它無錯組裝,並添加了一個由jmp $組成的簡單內核。我可以告訴你,jmp CODE_SEG:KERNEL_OFFSETjmp KERNEL_OFFSET都可以正常工作。

0

你可以粘貼bochs調試什麼的?根據我的經驗,你可能會在lgdt錯誤的gdt.Sometimes地址是錯誤的,有時你的gdt是有錯誤的限制,仔細檢查gdt可能會對你有幫助。