1

問題があります。最近は GDT、A20、プロテクト モードで遊んでいます。私はGDT用のこの簡単なコードを持っています:

gdt_start:
gdt_null:
    dd 00000000h
    dd 00000000h

gdt_code:
    dw 0xFFFF
    dw 0
    db 0
    db 10011010b
    db 11001111b
    db 00000000b

gdt_data:
    dw 0xFFFF       
    dw 0                
    db 0                
    db 10010010b            
    db 11001111b            
    db 0

gdt_end:
gdt_ptr:
    dw gdt_end - gdt_data - 1
    dd gdt_start

install_gdt:
    cli;
    pusha
    lgdt [gdt_ptr]
    sti
    popa

    ret

ご覧のとおり、とてもシンプルです。これが私のA20の有効化です:

ena20:
    mov al, 0xDD
    out 0x64, al
    ret

および第 2 段階のコードの一部:

    call install_gdt
    call ena20

    cli
    mov eax, cr0
    or eax, 1
    mov cr0, eax

    jmp 0x8:stage3
;-------------------------------------------
;STAGE3
;-------------------------------------------
BITS 32
stage3:
    ;mov ax, 0x10
    ;mov ds, ax
    ;mov ss, ax
    ;mov es, ax
    ;mov esp, 90000h

    ;mov edi, 0xB8000
    ;mov byte [edi], 'A'

    jmp $

一歩一歩進んでみました。GDT をレジスタに正常にロードし、A20 を有効にして保護モードに移行できます。しかし、しようとするとjmp 0x8:stage3、VirtualBoxからエラーが発生します:

A critical error has occurred while running the virtual machine and
the machine execution has been stopped.

(仮想マシンの状態は現在「Guru Meditation」です) どこに問題があるか知っている人はいますか? 機能させるにはどうすればよいですか?助けてください。

4

1 に答える 1

1

ここ:

gdt_ptr:
    dw gdt_end - gdt_data - 1
    dd gdt_start

GDT のサイズが からgdt_datagdt_endあるのに、開始点が であるのはなぜgdt_startですか?

また、GDT が含まれるリアルモード セグメントはどうでしょうか。の値にどのように「含める」のgdt_startですか?

ここ:

    mov eax, cr0
    or eax, 1
    mov cr0, eax

    jmp 0x8:stage3

BITS 32
stage3:

stage3関連する GDT エントリに従って、基数が 0 のセグメントが必要です。そうですか?IOW の値は、stage3このラベルのコードの物理アドレスと同じですか?

于 2012-08-07T12:46:23.473 に答える