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

第二阶段代码的一部分:

    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

Here:

gdt_ptr:
    dw gdt_end - gdt_data - 1
    dd gdt_start

Why is the GDT size from gdt_data to gdt_end and yet the start is at gdt_start?

Also, how about the real-mode segment in which the GDT is contained? How do you "include" it in the value of gdt_start?

Here:

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

    jmp 0x8:stage3

BITS 32
stage3:

You want stage3 in a segment whose base is 0 according to the relevant GDT entry. Is that the case? IOW, is the value of stage3 equal to the physical address of the code at this label?

于 2012-08-07T12:46:23.473 回答