protected mode - ist er wirklich drin?



  • Ich habe heute endlich mal wieder seit langem meinen prekernel ohne Fehler kompilieren können. Da das Debuggen so verdammt schwer ist wollte ich mal ein paar Freaks von euch fragen, ob mein Code einen echten GDT setzt und ob der Prozessor wirklich in den PMode kommt (kompiliert mit NASM):

    [BITS 16]   ;16 BITS
    [org 0]
    
    struc GDTSTRUCT
        .limit:     resw    1
        .baseaddr:  resd    1
    endstruc
    
    struc DESCRIPTORSTRUCT
        .segment_size:      resw    1
        .segment_baddr_low: resw    1
        .segment_baddr_high:    resb    1
        .access_flags:      resb    1
        .segment_size_high: resb    1
        .segment_baddr_xhigh    resb    1
    endstruc
    
    struc SELECTORSTRUCT
        .flags_and_index    resw    1
    endstruc
    
    mov ax, 9000h
    mov ds, ax
    mov es, ax
    
    start:
        call cls
        mov     si,     secondstage_ok
        call    putstr
        mov     si,     pmode_init
        call    putstr
    
    pmode_initialize:
        cli
        cld
    
    setgdtr:
        global_table:
            istruc GDTSTRUCT
                at GDTSTRUCT.limit, dw 0x0000
                at GDTSTRUCT.baseaddr,  dd 0x00000000
        iend
    
        lgdt    [global_table]
    
        selector_dummy:
            istruc SELECTORSTRUCT
                at SELECTORSTRUCT.flags_and_index,  dw  0x0000
            iend
    
    lesen:
        mov ah, 0
        int 0x16
        retn
    
    putstr:
        lodsb
        or al, al
        jz short putstrd
        mov ah, 0x0E
        mov bx, 0x0007
        int 0x10
        jmp putstr
    
        putstrd:
        retn
    
    cls:
        ;Bildschrim löschen
        mov ax,0600h
            mov bh,07h
            xor cx,cx
            mov dx,1950h
            int 10h
        call jump200
        retn
    
    jump200:
        mov ah, 0x02
        mov bh, 0x00
        mov dl, 0x00
        mov dh, 0x00
        int 10h
        retn
    
    reset:
        jmp 0xFFFF:0x0000
    
    secondstage_ok db "[Second stage Bootloader successfully loaded...]", 13, 10, 0
    pmode_init db "[Now setting up protected mode...]", 13, 10, 0
    
    times 1024-($-$$) db 0
    


  • Also, folgende Sache vergisst du auf jeden Fall: Das PE-Bit setzen. Das geht so:

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

    Ohne dem geht's auf keinen Fall. Genauer hab ich mir deinen Code aber noch nicht angeschaut, heißt also nicht dass alles richtig ist, dies ist mir jetzt gerade bloß sofort aufgefallen.
    Ach ja: Ich finde keine Stelle wo du den Kernel (oder was das ist) in einen Stillsatnd bringst, so wie du es jetzt machst würde der Code einfach an den Stellen wo die Prozeduren sind fortgeführt, füge zum Testen also eine endlosschleife oder ähnliches hinzu.



  • Ich gehe jetzt folgendermaßen vor:
    1. Einen leeren Global Description Table setzen
    2. PE Bit setzen

    BOCHS meldet folgenden Abbruch:
    3rd (13) exception with no resolution

    Irgendwie habe ich das System noch nicht begriffen. Man erstellt also einen GDT. In den schiebt man dann irgendwie deskriptoren rein, die die einzelnen Segmente beschreiben. Was kommt dann? Und wozu sind Selektoren gut?

    Und meine Endlosschleife will NASM garnicht akzeptieren:
    loop:
    jmp loop

    expression syntax error

    [ Dieser Beitrag wurde am 20.03.2003 um 20:41 Uhr von hackbert editiert. ]



  • Original erstellt von hackbert:
    **Und meine Endlosschleife will NASM garnicht akzeptieren:
    loop:
    jmp loop

    expression syntax error
    **

    *g* loop ist auch ein Assembler-Befehl.



  • shit, habe ich vergessen!



  • Original erstellt von hackbert:
    **Ich gehe jetzt folgendermaßen vor:
    1. Einen leeren Global Description Table setzen
    **

    Leer ist garnicht gut. Jede GDT muss MINDESTENS den ersten Eintrag als dummyeintrag auf 0 haben, ein Code-Segment für den Kernel und ein Daten-Segment für den Kernel (wo dann auch der Stack reinkommt)

    **
    Irgendwie habe ich das System noch nicht begriffen. Man erstellt also einen GDT. In den schiebt man dann irgendwie deskriptoren rein, die die einzelnen Segmente beschreiben. Was kommt dann? Und wozu sind Selektoren gut?
    **

    Dann schieb man erstmal vernünftige Deskriptoren rein 😉 Die Selektoren sind dann die Werte die man in CS, DS, ES, etc. reinschreibt. Davon werden die untersten 2 Bits genommen um den Privileglevel zu bestimmen den der Anfrager haben will und der Rest um den passenden Deskriptor zu suchen.

    Um noch einen Bug aufzuzeigen:

    **```
    pmode_initialize:
    cli
    cld

    setgdtr:
    global_table:
    istruc GDTSTRUCT
    at GDTSTRUCT.limit, dw 0x0000
    at GDTSTRUCT.baseaddr, dd 0x00000000
    iend

    lgdt    [global_table]
    

    Wenn ich das richtig sehe, packst du die Daten über die GDT mitten zwischen den Code. Das wird den Prozessor dazu verleiten, das dort steende versuchen, auszuführen. Pack die Daten lieber ganz am Ende, wo sie nicht ausgeführt werden können.

    Ansonsten empfehle ich http://www.fh-zwickau.de/doc/prmo/pmtutor/text/ da wird das alles ganz gut beschrieben finde ich.



  • Original erstellt von TriPhoenix:
    **
    Leer ist garnicht gut. Jede GDT muss MINDESTENS den ersten Eintrag als dummyeintrag auf 0 haben, ein Code-Segment für den Kernel und ein Daten-Segment für den Kernel (wo dann auch der Stack reinkommt)
    **

    Hat jemand dazu ein Codebeispiel. Das Tutorial habe ich übrigens schon gelesen und finde es etwas unübersichtlich, Codebeispiele wären gut.

    [ Dieser Beitrag wurde am 21.03.2003 um 13:29 Uhr von hackbert editiert. ]



  • Hast du nicht mehr den Code von dem OS das ich damals angefangen hab? Dort wurde auch der PMode eingeschaltet, guck dir das mal an!
    Ansontsne, ein gutes Tutorial ist auch noch dies hier (finde ich): http://my.execpc.com/~geezer/os/pm-de.htm



  • Original erstellt von hackbert:
    **Hat jemand dazu ein Codebeispiel. Das Tutorial habe ich übrigens schon gelesen und finde es etwas unübersichtlich, Codebeispiele wären gut.
    **

    Dann guck mal genau hin 😉 Unter "Einschalten des Protected Mode" versteckt sich ein komplettes Beispiel


Anmelden zum Antworten