Autor Thema: Problem mit Paging  (Gelesen 3079 mal)

ST-225

  • Beiträge: 43
    • Profil anzeigen
Gespeichert
« am: 15. June 2006, 14:18 »
So, nachdem ich eure (wirklich gelungenen) Lowlevel-Tuts alle gelesen hab möchte ich nun auch mit meinem eigenem OS beginnen. Ich habe mich entschlossen, gleich alles im PMode zu proggen und paging sowie softwaretasking zu benutzen. Mit dem Bootloader bin ich jetzt fertig und habe jetzt mit dem kernel begonnen. In diesem wird zuerst der PMode und daraufhin Paging aktiviert. Mit dem Paging bin ich für den Anfang mal Analog zum Tutorial aus dem lowlevel magazin #8 vorgegangen, jedoch gibt mein test-pc nie "PAGING" (Videotextspeichertest) aus. Hier der Code:
[BITS 16]
mov ax, 0x1000
mov ds, ax
mov es, axcli
call enableA20
lgdt [gdtr]
mov eax, cr0
or al, 1
mov cr0, eax
jmp codesel:PMode

[BITS 32]
PMode:
mov ax, datasel
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax
mov ss, ax
mov esp, 0x90000


Paging:
.init
mov eax, 0
mov ecx, 4096*3
mov edi, 0x8000
rep stosd
.writepagedir
mov DWORD[0x8000+0],(0x9000 | 000000000111b)
mov DWORD[0x8000+3072],(0xA000 | 000000000111b)
.map0
xor ebx,ebx
xor edx,edx
.Loop1:
mov eax,edx
or eax,000000000111b
mov [0x9000+ebx],eax
add ebx,4
add edx,4096
cmp edx,4096*1024
jne .Loop1
.map768
mov DWORD[0xA000],(0xB8000 | 000000000111b)
.activate
mov eax, 0x8000
mov cr3, eax
mov eax, cr0
or eax,10000000000000000000000000000000b
mov cr0, eax


PMODETEST:
    mov BYTE[0xC0000000],'P'
    mov BYTE[0xC0000002],'A'
    mov BYTE[0xC0000004],'G'
    mov BYTE[0xC0000006],'I'
    mov BYTE[0xC0000008],'N'
    mov BYTE[0xC000000A],'G'
    retn

enableA20:
    .stage1
    in al, 0x64
    test al, 00000010b
    jnz .stage1
    .stage2
    mov al, 0xD0
    out 0x64, al
    .stage3
    in al, 0x64
    test al, 00000001b
    jz .stage3
    .stage4:
    in al, 0x64
    test al, 00000010b
    jnz .stage4
    .stage5
    mov al, 0xD1
    out 0x64, al
    .stage6
    in al, 0x64
    test al, 00000010b
    jnz .stage6
    .stage7
    pop eax
    out 0x60, al
    retn


gdtr:  ; Desktiptortabelle
    dw gdt_end-gdt-1   ; Limit
    dd gdt   ; Basisadresse
gdt:
    dd 0,0   ; Null-Deskriptor
codesel equ $-gdt
    dw 0xFFFF; Segmentgröße 0..15
    dw 0x0000; Segmentadresse 0..15
    db 0x00  ; Segmentadresse 16..23
    db 0x9A  ; Zugriffsberechtigung und Typ
    db 0xCF  ; Zusatzinformationen und Segmentgr??e 16...19
    db 0x00  ; Segmentadresse 24..31
datasel equ $-gdt
    dw 0xFFFF; Segmentgröße 0..15
    dw 0x0000; Segmentadresse 0..15
    db 0x00  ; Segmentadresse 16..23
    db 0x92  ; Zugriffsberechtigung und Typ
    db 0xCF  ; Zusatzinformationen und Segmentgr??e 16...19
    db 0x00  ; Segmentadresse 24..31
gdt_end


Ich hoffe es kann mir jemand helfen !
Vielen Dank schonmal im Vorraus !

scales of justice

  • Beiträge: 228
    • Profil anzeigen
Gespeichert
« Antwort #1 am: 15. June 2006, 17:18 »
mov ax, 0x1000
mov ds, ax
mov es, axcli


das cli muss in die nächste Zeile,
und ich denke da sollte auch noch sti drüber

das wird aber wohl nur ein kopierfehler sein...

Jidder

  • Administrator
  • Beiträge: 1 625
    • Profil anzeigen
Gespeichert
« Antwort #2 am: 15. June 2006, 18:28 »
Ja, das Problem ist, dass der Protected Mode Code davon ausgeht, dass er an die Basis 0 geladen wird. In Wirklichkeit ist er anscheinend bei 0x1000:0x0000 also 0x10000 linear. Damit geht der Sprünge in den Protected Mode daneben.

jmp codesel:PMode
muss also
jmp dword codesel:PMode
heissen.

Außerdem gehört die routine enableA20 in den [bit 16] Teil.

Die ganze Sache mit den unterschiedlichen Basen im Real und Protected Mode könnte sich lösen lassen, wenn du org 0x10000 an den Anfang schreibst, was allerdings unsauber ist. Die bessere Möglichkeit wäre, noch im Bootloader in den Protected Mode zu schalten und im Kernel nur 32 Bit Code zu nehmen.
Dieser Text wird unter jedem Beitrag angezeigt.

ST-225

  • Beiträge: 43
    • Profil anzeigen
Gespeichert
« Antwort #3 am: 15. June 2006, 20:33 »
@scales of justice: Ja, war natürlich ein Kopierfehler, weil ich ein paar comments weggelassen hab  :wink:

@PortChicken: Danke für deine Ratschläge, hat aber trotzdem nicht gefunzt. Ich werde jetzt einen Bootloader mit PMode-Switch proggen. Dazu aber jetzt eine Frage: Wie mache ich das mit der load-Funktion, im PMode kann ich ja keine Hardware-Interrupts mehr verwenden. Oder kann ich das einfach vor dem Switch machen, aber dann stimmen ja die Speicheradressen nicht mehr  :?

Jidder

  • Administrator
  • Beiträge: 1 625
    • Profil anzeigen
Gespeichert
« Antwort #4 am: 15. June 2006, 21:15 »
Nein, ich denke nicht, dass es dann ein Problem gibt. Der Bootloader müsste grob so aussehen:

org 0x7c00

[bits 16]

xor ax, ax
mov ds, ax

; lade kernel an die adresse 0x1000:0x0000
mov ax, 0x1000
mov es, ax
mov bx, 0
call load_kernel

; gdt laden
lgdt [gdt_ptr]

; protected mode einschalten
mov eax, cr0
inc eax
mov cr0, eax

mov ax, datasel
mov ds, ax
; es, fs, gs, ss und esp auch mit known-good-werten laden

jmp codesel:0x10000

gdt db ... ; deine gdt


und der kernel so:

[bits 32]
org 0x10000

; a20, paging, etc. initialisieren
Dieser Text wird unter jedem Beitrag angezeigt.

ST-225

  • Beiträge: 43
    • Profil anzeigen
Gespeichert
« Antwort #5 am: 15. June 2006, 21:37 »
great thx. Fang' ich gleich morgen früh damit an  :idea:  :D

 

Einloggen