Assembler springen im Geschützten Modus mit GDT

Ich bin derzeit rund um das Spiel mit x86-Assember, um zu schärfen, meine low-level-Programmierkenntnisse. Derzeit stehe ich vor einem kleinen problem mit der Adressierung in 32-Bit-Protected-Modus.

Die situation ist folgende:

Ich habe ein Programm geladen 0x7e0 die schaltet die CPU in den Protected-Mode und springt an die entsprechende Bezeichnung im code:

[...]
code to switch CPU in Protected Mode
[...]

jmp ProtectedMode


[...]

bits 32

ProtectedMode:
    .halt:
        hlt
        jmp .halt

Dieser Werke absolut in Ordnung so weit. Die "jmp geschützten Modus" funktioniert auch ohne explizite weit springen, um zu löschen der prefetch-queue - da dieses Programm ist geladen mit offset 0 (org 0 am Anfang) - verursacht das code-segment an den richtigen Speicherort verweist.

Mein Aktuelles problem ist jetzt, dass innerhalb des "geschützten Modus" Etikett, das ich will springen Sie zu einem anderen Programm, das geladen wird, 0x8000 (ich überprüfte diese mit einem Speicher-dump, die laden-Funktion hat funktioniert und das Programm wird korrekt geladen, um 0x8000).

Da die CPU ist nun in den geschützten Modus und nicht RealMode mehr, die Adressierung schema anders ist. Den geschützten Modus verwendet Deskriptor-Selektoren zum nachschlagen einer Basis-Adresse und limit in einer Deskriptor-Tabelle hinzufügen, um den angegebenen offset und rufen Sie die physische Adresse (wie ich verstanden habe). Daher war es notwendig, eine GDT-vor Eintritt in den geschützten Modus.

Mine sucht, wie die folgenden:

%ifndef __GDT_INC_INCLUDED__
%define __GDT_INC_INCLUDED__

;*********************************
;* Global Descriptor Table (GDT) *
;*********************************
NULL_DESC:
    dd 0            ; null descriptor
    dd 0

CODE_DESC:
    dw 0xFFFF       ; limit low
    dw 0            ; base low
    db 0            ; base middle
    db 10011010b    ; access
    db 11001111b    ; granularity
    db 0            ; base high

DATA_DESC:
    dw 0xFFFF       ; data descriptor
    dw 0            ; limit low
    db 0            ; base low
    db 10010010b    ; access
    db 11001111b    ; granularity
    db 0            ; base high

gdtr:
    Limit dw 24         ; length of GDT
    Base dd NULL_DESC   ; base of GDT

%endif ;__GDT_INC_INCLUDED__

geladen wird, um die GDT-register über

lgdt [gdtr]

Was ich nicht verstanden habe, so weit ist, wie ich heute springen, um die körperliche Adresse 0x8000 in den geschützten Modus über die GDT?

Meine ersten Gedanken waren, um wählen Sie die Code-Deskriptor (CODE_DESC), die zeigen sollte, zu 0x7e00 (waren das aktuelle Programm geladen wird) und den offset, die notwendig ist, um auf 0x8000 (512 bytes), die bei der jump-Anweisung:

jmp CODE_DESC:0x200

Aber das funktioniert nicht.

jmp 0x7e0:0x200 

funktioniert auch nicht...

Haben Sie eine Idee, was ich hier vermisst? Vielleicht habe ich nicht verstanden, etwas wesentliches in der 32-Bit-geschützten Modus Adressierung und die Verwendung der GDT.

[BEARBEITEN] Vollständige code:

bits 16
org 0                       ; loaded with offset 0000 (phys addr: 0x7e00)

jmp Start

Start:
    xor ax, ax
    mov ax, cs
    mov ds, ax              ; update data segment

    cli                     ; clear interrupts

    lgdt [gdtr]             ; load GDT from GDTR (see gdt_32.inc)

    call OpenA20Gate        ; open the A20 gate 

    call EnablePMode        ; jumps to ProtectedMode

;******************
;* Opens A20 Gate *
;******************
OpenA20Gate:
    in al, 0x93         ; switch A20 gate via fast A20 port 92

    or al, 2            ; set A20 Gate bit 1
    and al, ~1          ; clear INIT_NOW bit
    out 0x92, al

    ret

;**************************
;* Enables Protected Mode *
;**************************
EnablePMode:
    mov eax, cr0
    or eax, 1
    mov cr0, eax

    jmp ProtectedMode ; this works (jumps to label and halts)
    ;jmp (CODE_DESC-NULL_DESC):ProtectedMode ; => does not work
    ;jmp 08h:ProtectedMode , => does not work

;***************
;* data fields *
;*  &includes  *
;***************
%include "gdt_32.inc"

;******************
;* Protected Mode *
;******************
bits 32

ProtectedMode:
    ;here I want to jump to physical addr 0x8000 (elf64 asm program)

    .halt:
        hlt
        jmp .halt
InformationsquelleAutor Sebastian B. | 2012-02-04
Schreibe einen Kommentar