2013-10-11 56 views
0

我試圖創建64位非常簡單的操作系統。我試圖首先進入保護模式,但在這一點上我失敗了。爲什麼切換到受保護狀態會重新啓動機器?

當我進行32位遠程跳轉時,機器重新啓動。

我的代碼與地址0x100處的另一個彙編程序一起加載到內存中。

該代碼與nasm編譯,我使用qemu -fda運行該程序。

這裏是我到目前爲止的代碼:

[BITS 16] 

jmp _start 

_start: 
    cli 

    lgdt [GDT64] 

    ; Switch to protected mode 
    mov eax, cr0 
    or al, 1b 
    mov cr0, eax 

    ; Desactivate pagination 
    mov eax, cr0 
    and eax, 01111111111111111111111111111111b 
    mov cr0, eax 

    jmp (CODE_SELECTOR-GDT64):pm_start 

[BITS 32] 

pm_start: 
    jmp $ 

GDT64: 
    NULL_SELECTOR: 
     dw GDT_LENGTH ; limit of GDT 
     dw GDT64  ; linear address of GDT 
     dd 0x0 

    CODE_SELECTOR:   ; 32-bit code selector (ring 0) 
     dw 0x0FFFF 
     db 0x0, 0x0, 0x0 
     db 10011010b 
     db 11001111b 
     db 0x0 

    DATA_SELECTOR:   ; flat data selector (ring 0) 
     dw 0x0FFFF 
     db 0x0, 0x0, 0x0 
     db 10010010b 
     db 10001111b 
     db 0x0 

    LONG_SELECTOR: ; 64-bit code selector (ring 0) 
     dw 0x0FFFF 
     db 0x0, 0x0, 0x0 
     db 10011010b  ; 
     db 10101111b 
     db 0x0 

    GDT_LENGTH: 

如果我跳遠之前做一個jmp $,它的工作原理,程序正確地停止,但是當跳遠完成後,它會重新啓動機。

我忘了設置類似某個細分受衆羣之類的東西嗎?

回答

2

正如您的評論所述,您需要GDT的線性地址。您似乎沒有指定任何ORG指令,因此彙編程序將使用基地址0,並且在運行時不會與地址匹配。

此外,不知道如何在0x100加載代碼,引導扇區通常加載在0x7c00

解決方案可以像在文件頂部指定ORG 0x7c00一樣簡單。

+0

上帝,我已經嘗試過,但我忘記重置段寄存器,現在,它運作良好。謝謝。 –

相關問題