PMODE: dpl > CPL - wo liegt der Fehler?



  • Hallo!
    Wenn ich meinen Code ausführe kriege ich bei BOCHS folgenden Fehler:
    00000560063e[CPU ] jump_protected: dpl > CPL
    Wenn ich im Code nachdem ich in den pmode schalte

    db 0eah
    dw pmode
    dw 8

    weglasse befindet sich die CPU im pmode ohne Fehler! Aber ich muss ja dahin springen - jedoch wenn ich das tue wie oben beschrieben bekomme ich eine 3rd exception! Was mich noch sehr verwundert, aus Bochs:
    00000560063i[CPU ] | SEG selector base limit G D
    00000560063i[CPU ] | SEG sltr(index|ti|rpl) base limit G D
    00000560063i[CPU ] | DS:9000( 0000| 0| 0) 00090000 0000ffff 0 0
    00000560063i[CPU ] | ES:9000( 0000| 0| 0) 00090000 0000ffff 0 0
    00000560063i[CPU ] | FS:0000( 0000| 0| 0) 00000000 0000ffff 0 0
    00000560063i[CPU ] | GS:0000( 0000| 0| 0) 00000000 0000ffff 0 0
    00000560063i[CPU ] | SS:4000( 0000| 0| 0) 00040000 0000ffff 0 0
    00000560063i[CPU ] | CS:9000( 0000| 0| 0) 00090000 0000ffff 0 0

    Meine Deskriptoren haben andere bases und andere limits 😕

    Hier der Code:

    [BITS 16]
    [ORG 0]
    
    jmp start
    
    PM db 'Schalten in Pmode',13,10,0
    string db 'Hallo aus dem Pmode',13,10,0
    
    struc GDTSTRUCT
    
    .limit: resw 1 
    .base: resd 1 
    
    endstruc
    
    global_table:
        istruc GDTSTRUCT 
        at GDTSTRUCT.limit, dw 1
        at GDTSTRUCT.base, dd 1
        iend
    
    des_null    dw 0000h            
                dw 0000h            
                db 00h              
                db 00000000b        
                db 00000000b        
                db 0 
    
    des_code    dw 9FFFh      
                dw 1       
                db 1            
                db 10011010b   ;Codesegment lesbar / ausführbar     
                db 11000000b        
                db 0 
    
    des_vram    dw 4000h           
                dw 8000h            
                db 0Bh             
                db 10010010b        
                db 11000000b        
                db 0     
    
    des_data    dw 2000h
                dw 1
                db 1             
                db 10010010b   ;Datensegment lesbar / ausführbar     
                db 11000000b        
                db 0  
    
    des_kernel dw 0200h
               dw 1
               db 1
               db 10010010b 
           db 11000000b
               db 0
    
    message:  
    lodsb
    or al,al
    jz done
    mov ah, 0Eh
    mov bx, 7
    INT 10h
    jmp message
    
    done:
    retn
    
    start:
    mov ax, cs
    mov ds, ax
    mov es, ax
    mov eax, des_null
    mov [global_table+GDTSTRUCT.base], eax
    mov eax, 4 * 8
    mov [global_table+GDTSTRUCT.limit], eax
    
    ;Adresse des Codesegments in den Deskriptor eintragen
    mov ax,cs
    shl eax, 4
    add ax, start
    mov [des_code+2], ax
    xor ax,ax
    mov ax, cs
    mov [des_code+4], ax
    
    ;Adresse des Datensegments in den Deskriptor eintragen
    mov ax,ds
    shl eax, 4
    add ax, start
    mov [des_data+2], ax
    xor ax,ax
    mov ax, ds
    mov [des_data+4], ax
    
    lgdt [global_table]
    mov si, PM
    call message
    cli
    mov eax,cr0
    or eax,1
    xor eax,eax
    mov eax, 0x00000001
    mov cr0,eax
    db 0eah
    dw pmode
    dw 8
    
    pmode:
    
    loop_end:
    jmp loop_end
    

    Ich wäre für sinnvolle Posts sehr dankbar! Bitte nicht wieder sowas wie: "Du kannst doch eh kein OS programmieren - geh lieber raus und spiel Fußball"! Danke

    Kevin



  • Original erstellt von Surkevin:
    **;Adresse des Codesegments in den Deskriptor eintragen
    mov ax,cs
    shl eax, 4
    add ax, start
    mov [des_code+2], ax
    xor ax,ax
    mov ax, cs
    mov [des_code+4], ax
    **

    Wenn ich das richtig sehe, überschreibst du mit mov [des_code+4], ax das Typfeld. Imho müsste es heißen:

    ;Adresse des Codesegments in den Deskriptor eintragen
    mov ax,cs
    shl eax, 4
    add ax, start
    mov [des_code+2], ax
    mov ax, cs
    shr ax, 16
    mov [des_code+4], al
    mov [des_code+7], ah
    


  • Jo, stimmt schon, aber vielleicht wuerde das so:

    mov eax, 0
    mov ax, cs
    shl eax, 04h
    mov [des_code+2], ax
    shr eax, 10h
    mov [des_code+4], al
    mov [des_code+7], ah
    

    noch ein stueckel besser laufen... 😉

    Waere vielleicht besser, wenn Du zur Base der Descriptoren nicht noch das Offset von Start addieren wuerdest, Du hast schliesslich oben in deinem Code "[org 0]" stehen...

    [ Dieser Beitrag wurde am 23.04.2003 um 14:20 Uhr von Nobuo T editiert. ]



  • Hmmmm kommt leider immernoch
    jump_protected: dpl > CPL
    man man man - wieso nur? 😞
    Vielen Dank trotzdem für sinnvolle postings 🙂

    Warum eigentlich mov [des_code+7], ah?

    Kevin

    [ Dieser Beitrag wurde am 23.04.2003 um 15:42 Uhr von Surkevin editiert. ]



  • Original erstellt von Surkevin:
    **Warum eigentlich mov [des_code+7], ah?
    **

    Weil der Segment-Deskriptor so aufgebaut ist, dass die Basis 0..15 an +2 kommt, Basis 16..23 an +4 und 24..31 an +7. Sch... Abwärtskompatibilität 🙂

    PS: Kannst du nochmal den Code in seiner aktuellen Gesamtheit posten? Dann kann ich nämlich mit dem Bochs Debugger mal gucken. (Gut zusammengefasst übrigens auf http://www.cs.bilkent.edu.tr/~korpe/courses/cs342/debugger-bochs.htm )

    [ Dieser Beitrag wurde am 23.04.2003 um 15:46 Uhr von TriPhoenix editiert. ]



  • Jo mach ich gerne - sag ob ich den Bootloader auch noch posten soll! Hier der gesamte Kernelcode:

    [BITS 16]
    [ORG 0]
    
    jmp start
    
    PM db 'Schalten in Pmode',13,10,0
    string db 'Hallo aus dem Pmode',13,10,0
    
    struc GDTSTRUCT
    
    .limit: resw 1 
    .base: resd 1 
    
    endstruc
    
    global_table:
        istruc GDTSTRUCT 
        at GDTSTRUCT.limit, dw 1
        at GDTSTRUCT.base, dd 1
        iend
    
    des_null    dw 0000h            
                dw 0000h            
                db 00h              
                db 00000000b        
                db 00000000b        
                db 0 
    
    des_code    dw 9FFFh       ;Größe 4096 Bytes entspr. 8 Sektoren    
                dw 1       ;die ersten 5 Sektoren belassen und dann in den 6. schreiben     
                db 1            
                db 10011010b   ;Codesegment lesbar / ausführbar     
                db 11000000b        
                db 0 
    
    des_vram    dw 4000h           
                dw 8000h            
                db 0Bh             
                db 10010010b        
                db 11000000b        
                db 0     
    
    des_data    dw 2000h
                dw 1
                db 1             
                db 10010010b   ;Datensegment lesbar / ausführbar     
                db 11000000b        
                db 0  
    
    des_kernel dw 0200h
               dw 1
               db 1
               db 10010010b 
           db 11000000b
               db 0
    
    message:  
    lodsb
    or al,al
    jz done
    mov ah, 0Eh
    mov bx, 7
    INT 10h
    jmp message
    
    done:
    retn
    
    start:
    mov ax, cs
    mov ds, ax
    mov es, ax
    mov eax, des_null
    mov [global_table+GDTSTRUCT.base], eax
    mov eax, 4 * 8
    mov [global_table+GDTSTRUCT.limit], eax
    
    ;Adresse des Codesegments in den Deskriptor eintragen
    mov eax, 0
    mov ax, cs
    shl eax, 04h
    mov [des_code+2], ax
    shr eax, 10h
    mov [des_code+4], al
    mov [des_code+7], ah
    
    ;Adresse des Datensegments in den Deskriptor eintragen
    mov ax,ds
    shl eax, 4
    mov [des_data+2], ax
    xor ax,ax
    shr eax,10h
    mov [des_data+4], al
    mov [des_data+7], ah
    
    lgdt [global_table]
    mov si, PM
    call message
    cli
    mov eax,cr0
    or eax,1
    xor eax,eax
    mov eax, 0x00000001
    mov cr0,eax
    db 0eah
    dw pmode
    dw 8
    
    pmode:
    
    loop_end:
    jmp loop_end
    

    Kevin



  • Original erstellt von Surkevin:
    **Jo mach ich gerne - sag ob ich den Bootloader auch noch posten soll! Hier der gesamte Kernelcode:
    **

    Würde helfen, wenns geht noch ne kompilieranleitung 😉 Alternativ kannst mir natürlich auch das fertige image mailen (foo@triphoenix.de) das tuts auch iums zu debuggen.



  • Ich benutze Nasm(w)
    Mail is unterwegs....
    Code vom Bootloader:

    [BITS 16]
    [ORG 0]
    
    jmp start
    
    Fehler db 'An Error occured',13,10,0
    reset db 'Diskette resetet',13,10,0
    boot_msg db 31,'booting mkos bootsektor 0.0.0',13,10,0
    loading_kernel_msg db 'loading kernel',13,10,0
    loaded db 'Kernel wurde geladen und wird nun ausgeführt',13,10,0
    
    message:
    lodsb
    or al,al
    jz done
    mov ah, 0Eh
    mov bx, 7
    INT 10h
    jmp message
    
    done:
    retn
    
    Resetdisk:
    mov ah, 00h
    mov dl, 0
    INT 13h
    jnc load_kernel
    jc error
    
    hang:
    jmp hang
    
    error:
      mov si, boot_msg
      call message
      jmp hang
      hlt
      ret
    
    load_kernel:
      mov si, reset
      call message
      mov ax, 0x9000
      mov es, ax
      xor bx, bx
      mov ah, 02h
      mov al, 1
      mov ch, 0
      mov cl, 2
      mov dh, 0
      mov dl, 0
      int 0x13
      jc error
      ret
    
    start:
      mov ax, 07C0h       
      mov es, ax
      mov ds, ax
    
      cli
      mov ax, 0x4000
      mov ss, ax
      mov sp, 0xffff
      sti
    
      mov si, boot_msg
      call message
    
      mov si, loading_kernel_msg
      call message
    
      call Resetdisk
      mov si, loaded
      call message
    
      mov ax, 0x9000       
      mov es, ax
      mov ds, ax
      jmp 0x9000:0x0000
    
    times 510-($-$$) db 0
    dw 0xAA55
    

    P.S.: DANKE!!!!! FÜR DEINE MÜHE!

    Antrax



  • Original erstellt von Surkevin:
    **Mail is unterwegs....
    **

    Läuft wohl etwas länger heute 🙂 Verrätst du derweil, wie die Daten auf der Diskette liegen? Einfach Bootsektor und dann der Startup direkt dahinter?



  • sorry hat vergessen zu schicken *g*...schick jetzt los
    erst bootloader und direkt dahinter der "kernel" 🙂



  • Also in meinem Bochs läuft der Kernel durch und steht nachdem er die Messages ausgegeben hat. Wie gefordert.

    Edit die Bochsout.txt zeigt dass dohc irgendwas nicht stimmte. Der Prozessor ist nicht im PMode...

    Aha...dein Kernel wird garnicht erfolgreich geladen...schick nächstes mal die volel Datei, ich hab nur den Loader in der .bin 😉

    [ Dieser Beitrag wurde am 23.04.2003 um 22:36 Uhr von TriPhoenix editiert. ]



  • Hab ich doch - die img Datei sind beide Dateien zusammen 😞



  • Okay, was ich bisher an fehlern finden konnte:

    - Die GDT-Adresse ist nicht in Ordnung, dort ist nämlich nur der Offset im Register drin, nicht Die komplette lineare Adresse. lgdt lädt als Basis 0x00000020 rein, richtiger wäre ja 0x00090020.
    - Beim Patchen der Stellen im Datendeskriptor ist ein xor eax, eax hängen geblieben
    - Du rufst im Protected Mode den Bios Interrupt 10 auf um eine Nachricht auszugeben. BIOS-Calls gehen im Protected Mode nicht mehr



  • Hm neee den INT benutz ich vor dem schalten in den pmode! Hmm wo ist der Fehler im Code? Ich gebe doch mit lgdtr mein struct an wo die Adresse steht an, oder nicht? Darf man xor eax,eax nicht verwenden 😕

    Danke für die Mühe

    Kevin



  • Original erstellt von Surkevin:
    Hm neee den INT benutz ich vor dem schalten in den pmode!

    Sorry, war ein lesefehler 🙂

    Hmm wo ist der Fehler im Code? Ich gebe doch mit lgdtr mein struct an wo die Adresse steht an, oder nicht?

    Nur den Offset innerhalb des Segmentes 9000. Musst halt einfach noch 90000 draufaddieren.

    Darf man xor eax,eax nicht verwenden 😕

    Doch, aber nicht wenn du den wert von eax in der nächsten zeile noch brauchst 🙂



  • hmmm wieso 90000, vertippt?



  • Hmm ich habe jetzt folgende Veränderungen vorgenommen:

    start:
    mov ax, cs
    mov ds, ax
    mov es, ax
    mov eax, des_null
    add eax, 90000h
    mov [global_table+GDTSTRUCT.base], eax
    mov eax, 4 * 8
    mov [global_table+GDTSTRUCT.limit], eax

    und dann das xor ax,ax noch rausgenommen - jetzt ist der Fehler:
    00000560063e[CPU ] jump_protected: gate type 14 unsupported

    hmm komisch 😕

    Kevin



  • Original erstellt von Surkevin:
    hmmm wieso 90000, vertippt?

    90000 weil der code im segment 9000 liegt. Die lineare Adresse dafür ist ja * 16 also 90000. Den Rest gucke ich mir morgen an 🙂



  • hmm oki 😃
    das is bestimmt dezimal also habe ich in meinem code add eax, 90000h durch add eax, 90000 ersetzt...der fehler ist nun
    00000560063e[CPU ] jump_protected: gate type 0 unsupported

    Nochmal vielen Dank

    Kevin



  • TriPhoenix kannst du dir vorstellen warum dieser Fehler kommt?


Anmelden zum Antworten