warum komm ich im Bootsektor nicht in Pmode?



  • Hallo!
    Ich will direkt mit meinem Bootsektor in Pmode schalten - ich verwende den selben Code wie ich sonst auch zum schalten verwende, nur muss ich eben die Adressen verändern, sind die irgendwie falsch?

    start:
      mov ax, 0x07c0      
      mov es, ax
      mov ds, ax
    
      cli
      mov ax, 0x4000
      mov ss, ax
      mov sp, 0xffff
      sti
    mov eax, des_null
    add eax, 0x07c00
    mov [global_table+GDTSTRUCT.base], eax
    xor eax,eax
    mov ax, 40h
    mov [global_table+GDTSTRUCT.limit], ax
    

    Danke

    Kevin



  • Achja, die Fehlermeldung is laut Bochs
    00000541862e[CPU ] load_seg_reg: LDT invalid
    00000541862p[CPU ] >>PANIC<< exception(): 3rd (13) exception with no resolution



  • Hi.

    IMHO sagt dieses Stueck code ueberhaupt nichts aus - Da koennte ich nur mit wilden Vermutungen um mich werfen.
    Poste mal die ganze Datei des Bootstraps.



  • Okay, here it is:

    [BITS 16]
    [ORG 0]
    
    jmp start
    
    Fehler db 'An Error occured',13,10,0
    reset db 'Diskette resetet',13,10,0
    del db 'Kernel wurde geladen und wird nun ausgeführt',13,10,0
    string db 'Reached the 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 00000000b        
                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  
    
    message:
    lodsb
    or al,al
    jz done
    mov ah, 0Eh
    mov bx, 7
    INT 10h
    jmp message
    
    done:
    retn
    
    hang:
    jmp hang
    
    error:
      mov si, Fehler
      call message
      jmp hang
      hlt
      ret
    
    start:
      mov ax, 0x07c0      
      mov es, ax
      mov ds, ax
    
      cli
      mov ax, 0x4000
      mov ss, ax
      mov sp, 0xffff
      sti
    mov eax, des_null
    add eax, 0x07c00
    mov [global_table+GDTSTRUCT.base], eax
    xor eax,eax
    mov ax, 40h
    mov [global_table+GDTSTRUCT.limit], ax
    
    ;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
    shr eax,10h
    mov [des_data+4], al
    mov [des_data+7], ah
    
    lgdt [global_table]
    cli
    
    mov eax,cr0
    or eax,1
    xor eax,eax
    mov eax, 0x00000001
    mov cr0,eax
    
    db 0eah
    dw pmode
    dw 8
    
    pmode:
    mov ax, 24
    mov ds,ax
    
    mov ax, 16
    mov es, ax
    
    mov si, string
    xor di,di
    mov di,(80*2)*24+(80-17)*2
    
    xor ecx,ecx
    mov ecx, 17
    
    showtext:
    mov al, [si]
    stosb
    inc si
    inc di
    loop showtext
    
    loop_end:
    jmp loop_end
    
    times 510-($-$$) db 0   
    dw 0xAA55
    


  • Oje... net falsch verstehen, aber das ist ja ein ganz schoenes Durcheinander. 🙄

    Nagut, soweit ich das gesehen hab, liegts hauptsaechlich daran, dass Du dich mit der Einsprungsaddresse bei dem Jump zum PMode vertan hast...
    Einfach 7C00 auf das Offset der Addresse addieren und es muesste laufen.

    db 0eah
    dw pmode+0x7C00 ;<== Hier!
    dw 8
    

    Der 2. grobe Fehler, den ich jetzt noch loswerden muss ist, dass die Groesse der GDT falsch eingetragen wird. Die ist tatsaechlich nur halb so gross! (4 descriptoren macht 4*8=20 und nicht 40)

    mov ax,0x0020
    mov [global_table+GDTSTRUCT.limit], ax
    

    Ansonsten sind da noch mehrere Unfeinheiten drin...
    Sollte Interesse bestehen kann ich mich darueber auch noch mal in aller Ausfuehrlichkeit auslassen 😉



  • Deine erste Bemängelung ist der Fehler, vielen Dank!

    Aber wenn du wilslt kannst du sagen was noch so falsch ist 🙂



  • Ok, handelt sich groesstenteils um Kleinigkeiten, sollte aber dennoch so in einem halbwegs ernstgemeinten OS-Versuch nicht vorkommen...

    sp sollte gerade Werte enthalten.

    original: mov sp, 0xffff
    besser: mov sp,0xfffe
    

    Ist nicht unbedingt falsch, aber es waere guenstiger, die Variablen gleich
    mit sinnvollen Werten zu initialisieren, als dann spaeter bekannte
    fixe Werte erst zusammenrechnen und in den Speicher schreiben zu lassen...

    Also - dieses Stueck code hier rausschmeissen:

    mov eax, des_null
    add eax, 0x07c00
    mov [global_table+GDTSTRUCT.base], eax
    xor eax,eax
    mov ax, 40h
    mov [global_table+GDTSTRUCT.limit], ax
    

    und dafuer bei den Variablen folgende Werte einsetzen:

    global_table:
        istruc GDTSTRUCT 
        at GDTSTRUCT.limit, dw 0x0020
        at GDTSTRUCT.base, dd 0x00007C00+des_null
        iend
    

    Das gleiche gilt uebrigens fuer den Datensegment descriptor...
    Von dem kennst Du die BaseAddr auch schon vor der Laufzeit. (Du weist ds schliesslich selbst zu Beginn des Programms einen fixen Wert zu)

    Zu dem code oben 2 Anmerkungen:
    Es ist nicht sinnvoll, erst eax via xor zu loeschen um in der naechsten Zeile ax mit einem fixen Wert zu fuellen, nur um selbigen dann ueber ax in den Speicher zu schreiben.
    fuer sowas haette auch einfach

    mov word [global_table+GDTSRUCT.limit],0x0020
    

    gelangt.

    mov eax,cr0
    or eax,1
    xor eax,eax
    mov eax, 0x00000001
    mov cr0,eax
    

    Das ist nicht sinnvoll! Ich glaube das hatten wir aber schonmal 😃

    xor di,di
    mov di,(80*2)*24+(80-17)*2
    
    xor ecx,ecx
    mov ecx, 17
    

    Du musst einen Register vor dem Befuellen mit fixen Werten nicht nochmal extra loeschen. =>xor-Anweisungen weg.

    So, ich glaub das war alles :p 🙂

    [ Dieser Beitrag wurde am 08.05.2003 um 17:40 Uhr von Nobuo T editiert. ]


Anmelden zum Antworten