Autor Thema: Frage zu Bochs  (Gelesen 6891 mal)

nooooooooos

  • Beiträge: 734
    • Profil anzeigen
Gespeichert
« am: 03. November 2005, 21:32 »
Hallo, ich bins nochmal.


Wenn ich mein OS auf Bochs laufen lasse, dann kommt im Bochs-Fenster immer die Meldung: "[CPU 0] Look prefix unallowed <opt=0x53 .....". Ich habe eine IDT mit Timer Interrupt eingerichtet. Dann, nach ca. 5 Min erscheint in Bochs (und auch normal im PC) ein komisches Bild. Ich habe keinen Code einfach so zusammenkopiert, also kenne ich den Code ganz genau.

Wie entsteht dieses Bild ???
Was bedeutet diese Bochs-Meldung ???


Vielen Dank
Nooooooooos

Homix

  • Beiträge: 138
    • Profil anzeigen
Gespeichert
« Antwort #1 am: 03. November 2005, 22:12 »
hi,
es könnte soeine Meldung kommen, wenn Bochs auf einen ungültigen befehl stößt oder wenn 16-Bit Code im 32-Bit Mode ausgeführt wird.
eventuell wird bei dir durch den Timer an irgendeine Adresse gesprungen.

mfg,
stefan

nooooooooos

  • Beiträge: 734
    • Profil anzeigen
Gespeichert
« Antwort #2 am: 04. November 2005, 12:18 »
Aha. Und wie entsteht dieses Bild, kann es wirklich sein, dass es in irgendeinem Speicherbereich der Code für dieses Bild ist und der Timer-Interrupt das aufruft ????

Es wäre logisch, denn der Code, der irgendwo ist, könnte ja 16-Bit Code sein.

Aber etwas ist komisch: Ich habe mir mal den Code von Hauke angesehen und da passiert genau das selbe !!!!

Und eben, es kommt nicht jedes Mal das gleiche Bild und auch wenn ich den Code in echt am PC teste, kommt ein Bild.

1.) Was ist das für ein Code der das Bild erzeugt ?
2.) Durch welchen Programmier-Fehler (den mindestens zwei Leute gemacht haben) wird zu diesem Code gesprungen ???



Gruss
Nooooooooooooooooooos

matthieuriolo

  • Beiträge: 226
    • Profil anzeigen
Gespeichert
« Antwort #3 am: 04. November 2005, 14:04 »
Was passiert denn wenn du es mit einem normalen PC testest?


PS. Appenzell? Kennst du vielleicht einen Sais? :P

nooooooooos

  • Beiträge: 734
    • Profil anzeigen
Gespeichert
« Antwort #4 am: 04. November 2005, 21:24 »
Eben, auch bei normalem PC erscheint ein Bild.

nooooooooos

  • Beiträge: 734
    • Profil anzeigen
Gespeichert
« Antwort #5 am: 05. November 2005, 08:13 »
Also eben, es geht sehr lang bis dieses Bild kommt. Die 5 Minuten davor blinck eifach der "Cursor" obwohl ich nichts des gleichen programmiert hab. Wenn ich zum Beispiel bei meinem Timer-Interrupt Handler einen Sprung ans Programmende setze, dann startet der PC nicht neu wie er eigentlich müsste. Darum geh ich davon aus, dass gar nicht mal zum Handler gesprungen wird.

Was habe ich falsch gemacht, damit nicht zu meinem Handler gesprungn wird ??????  :cry:  :x  :?  :o  :(

Hier mein Code:
[BITS 16]
                           ;16 Bit Code erstellen
   jmp      start                  ;GDT überspringen
       %macro makeIDT 3
            dw %1
            dw %2
            db 0
            db %3
            dw 0
   %endmacro
NULL_Desc:
   dd      0
   dd      0
   
CODE_Desc:
   dw      0xFFFF                  ;Segmentgröße Byte 0/1
   dw      0                   ;Segmentbasisadresse Byte 0/1
   db      0                  ;Segmentbasisadresse Byte 2
   db      10011010b   ;Zugriffsberechtigungen
   db      11001111b               ;Zusatz + Segmentgröße Bits 16 - 19
   db      0                  ;Segmentbasisadresse Byte 3

DATA_Desc:
   dw      0xFFFF
   dw      0
   db      0
   db      0x92
   db      0xCF
   db      0    

gdt:
   Limit   dw   0                  ;Größe der GDT (wird später eingetragen)
   Base   dd   0    

       
idts:
            makeIDT IRQ_00, 8, 10001110b
            makeIDT IRQ_00, 8, 10001110b
            makeIDT IRQ_00, 8, 10001110b
            makeIDT IRQ_00, 8, 10001110b
            makeIDT IRQ_00, 8, 10001110b
            makeIDT IRQ_00, 8, 10001110b
            makeIDT IRQ_00, 8, 10001110b
            makeIDT IRQ_00, 8, 10001110b
            makeIDT IRQ_00, 8, 10001110b
            makeIDT IRQ_00, 8, 10001110b
            makeIDT IRQ_00, 8, 10001110b
            makeIDT IRQ_00, 8, 10001110b
            makeIDT IRQ_00, 8, 10001110b
            makeIDT IRQ_00, 8, 10001110b
            makeIDT IRQ_00, 8, 10001110b
            makeIDT IRQ_00, 8, 10001110b
            makeIDT IRQ_00, 8, 10001110b
            makeIDT IRQ_00, 8, 10001110b
            makeIDT IRQ_00, 8, 10001110b
            makeIDT IRQ_00, 8, 10001110b
            makeIDT IRQ_00, 8, 10001110b
            makeIDT IRQ_00, 8, 10001110b
            makeIDT IRQ_00, 8, 10001110b
            makeIDT IRQ_00, 8, 10001110b
            makeIDT IRQ_00, 8, 10001110b
            makeIDT IRQ_00, 8, 10001110b
            makeIDT IRQ_00, 8, 10001110b
            makeIDT IRQ_00, 8, 10001110b
            makeIDT IRQ_00, 8, 10001110b
            makeIDT IRQ_00, 8, 10001110b
            makeIDT IRQ_00, 8, 10001110b
            makeIDT IRQ_00, 8, 10001110b
            makeIDT IRQ_01, 8, 10001110b





idt:
Limiti dw   0        ;Größe der IDT (wird später eingetragen)
Basei dd   0        ;Adresse der IDT (wird später eingetragen)



start:

cli
  ;Interrupts ausschalten

mov eax, cs ;EAX auf derzeitiges Codesegment setzen
mov ds, ax ;DS auf Codesegment setzen

shl eax, 4 ;EAX mit 16 multiplizieren (Lineare Adresse
;des Codesegments errechnen)
mov [CODE_Desc+2], ax ;Lineare Adresse des Codesegmentes als
mov [DATA_Desc+2], ax ;Startadresse des Code- und Datendeskriptors
shr eax, 16 ;eintragen
mov [CODE_Desc+4], al
mov [DATA_Desc+4], al

mov eax, cs ;Startadresse der GDT errechnen
shl eax, 4
add eax, NULL_Desc

mov [Base], eax ;Startadresse der GDT eintragen
mov [Limit], WORD gdt - NULL_Desc -1 ;Größe der GDT errechnen und eintragen

lgdt [gdt] ;GDT laden


   mov    [Limiti], word idt - idts -1
   
   
mov      eax, cs        ;Startadresse der IDT errechnen
   shl      eax, 4
   add      eax, idts
   mov    [Basei], eax
   
   

   



mov eax, cr0 ;In den Protected Mode schalten,
or eax, 1 ;indem Bit 0 des CR0 Registers auf 1
mov cr0, eax ;gesetzt wird

db 0xea ;FAR-JUMP zum Codesegment
dw PMODE
dw 0x8
[BITS 32]                        ;32 Bit Code erstellen

PMODE:
   lidt   [idt]
   mov      WORD [CODE_Desc+2], 0            ;Code Segmentstartaddresse auf 0 setzen
   mov      WORD [DATA_Desc+2], 0            ;Daten Segmentstartadresse auf 0 setzen
   mov      BYTE [CODE_Desc+4], 0            ;Code Segmentstartaddresse auf 0 setzen
   mov      BYTE [DATA_Desc+4], 0            ;Daten Segmentstartadresse auf 0 setzen
   
   mov      eax, 2                  ;Selektor für das Datensegment erstellen
   shl      eax, 3
       
   mov      ds, ax                  ;Daten- Stack- und Extrasegment mit Datensegmentdeskriptor laden
   mov      ss, ax          
   mov      es, ax
   mov      eax, 0                  ;FS und GS mit Null-Deskriptor laden
   mov      fs, ax
   mov      gs, ax
   mov      esp, 0x2FFFFF               ;Stack setzen
jmp      0x8:0x10000 + PMODEy   ;Sprung in das "neue" Codesegment
       
PMODEy:    


                          ; Neuinit der Interrupt-Controller, sowie neu Setzen des Interrupt Mappings
 
  mov al,00010001b                      ; kaskadierte Interrupt-Controller und Flankentriggerung an beider Controller
   out 020h,al          
   out 0a0h,al

                           ; neuer IRQ-Vektor für den ersten Controller einstellen neuer Wert => IRQ0..7 -> INT20h..27h
   mov al,20h          
   out 021h,al

                           ; neuer IRQ-Vektor für den zweiten Controller einstellen neuer Wert => IRQ8..15 -> INT28h..2Fh
   mov al,28h          
   out 0a1h,al

                           ; Kaskadierung beider Controller einstellen
   mov al,00000100b                      ; Kaskadierung über IRQ2
   out 021h,al
   mov al,00000010b                      ; Kaskadierung über IRQ2
   out 0a1h,al

                           ; PIC auf Intel-Umgebung und manuelle Int.- Beendigung einstellen
   mov al,00000001b
   out 021h,al
   out 0a1h,al

sti

PMODE2:    
   jmp      0x8:0x10000 + PMODE2            ;Endlosschleife

IRQ_00:
cli
   pusha
   push gs
   push fs
   push ds
   push es

   pop es
   pop ds
   pop fs
   pop gs
   popa
   iret

   
 
IRQ_01:



Gruss Noooooooooos

nooooooooos

  • Beiträge: 734
    • Profil anzeigen
Gespeichert
« Antwort #6 am: 05. November 2005, 11:23 »
So, mittlerweile hab ichs geschafft, dass das Bild nicht angezeigt wird (keine Ahnung wie). Die Meldung "Lock prefix unallowed ..." erscheint jedoch immer noch. Und meine Handler funktionieren immer noch nicht.

Gruss
Noooooooos

SSJ7Gohan

  • Beiträge: 398
    • Profil anzeigen
Gespeichert
« Antwort #7 am: 05. November 2005, 11:44 »
Versuch mal die IDT erst nach PMODEy zu laden.

nooooooooos

  • Beiträge: 734
    • Profil anzeigen
Gespeichert
« Antwort #8 am: 05. November 2005, 14:04 »
Warum ???


Also ich habs jetzt getan und dabei ist was ganz komisches passiert. Diese Lock Meldung ist jetzt nicht mehr, dafür aber mein altes Problem: Bochs/PC blinckt. Dabei gibt Bochs diese Meldung aus : "3rd (13) Exeption with no resolution" Was hat das zu bedeuten ???? Warum ist dieses Blinck Problem nur, wenn die IDT nach dem PM definiert is ???

Gruss
Nooooooos

SSJ7Gohan

  • Beiträge: 398
    • Profil anzeigen
Gespeichert
« Antwort #9 am: 05. November 2005, 14:10 »
Da du ja die Segmentbasisaddressen nicht auf 0 gesetzt hast, verschieben sich alle Addressen ein bischen. Ich würde dir empfehlen in den PM zu springen, ohne die Basisaddressen zu ändern, und die IDT erst anzulegen, wenn du komplett im PM bist.

nooooooooos

  • Beiträge: 734
    • Profil anzeigen
Gespeichert
« Antwort #10 am: 05. November 2005, 17:32 »
Da ichs nicht so mit Fremdbegriffen habe, frage ich, was Segmentbasisadressen sind und wie man sie auf 0 stellt.

Gruss
Noooooooooooooooos

SSJ7Gohan

  • Beiträge: 398
    • Profil anzeigen
Gespeichert
« Antwort #11 am: 05. November 2005, 18:50 »
  mov      WORD [CODE_Desc+2], 0            ;Code Segmentstartaddresse auf 0 setzen
   mov      WORD [DATA_Desc+2], 0            ;Daten Segmentstartadresse auf 0 setzen
   mov      BYTE [CODE_Desc+4], 0            ;Code Segmentstartaddresse auf 0 setzen
   mov      BYTE [DATA_Desc+4], 0            ;Daten Segmentstartadresse auf 0 setzen

Als du deine GDT erstellst setzt du die Basisaddressen auf das aktuelle Codesegment. Danach setzt du sie wieder auf 0. Das ist aber nicht nötig, man kann direkt mit einem 32 Bit Offset in den PM springen.
Setz die Basisaddressen auf 0 und spring mit jmp dword 0x8:PMODE in den PM statt mit
  db      0xea         ;FAR-JUMP zum Codesegment
   dw      PMODE
   dw      0x8

nooooooooos

  • Beiträge: 734
    • Profil anzeigen
Gespeichert
« Antwort #12 am: 05. November 2005, 19:30 »
Also irgendwie funktioniert es so noch weniger. Aber ich bin mir nicht sicher, ob ich alles verstanden hab. Ich hab beide Codeteile (der,der die Deskriptoren auf das aktuelle Segment gesetzt und der,der im PM die Deskriptoren auf 0 setzt) glöscht. Dabei hab ich den Sprung durch deinen ersetzt. Jetzt schreibt Bochs: "Lock prefix....." UND"3rd exeption..."
Vorher hat Bochs nur entweder das eine ("Lock prefix..." aber eine Meldung nach der anderen in einer List)oder das andere(mit anschliessendem Neustart)geschrieben.

Durch abstecken hab ich herausgefunden, dass der Fehler beim Sprung in den PM liegt.

Hab ich was falsch verstanden, oder wo liegt der Hase begraben ??????

Gruss
Nooooos

SSJ7Gohan

  • Beiträge: 398
    • Profil anzeigen
Gespeichert
« Antwort #13 am: 05. November 2005, 20:06 »
Nein, zeig mal deinen neuen Code.

nooooooooos

  • Beiträge: 734
    • Profil anzeigen
Gespeichert
« Antwort #14 am: 05. November 2005, 21:26 »
Voila

[BITS 16]
                           ;16 Bit Code erstellen
   jmp      start                  ;GDT überspringen
       %macro makeIDT 3
            dw %1
            dw %2
            db 0
            db %3
            dw 0
   %endmacro
NULL_Desc:
   dd      0
   dd      0
   
CODE_Desc:
   dw      0xFFFF                  ;Segmentgröße Byte 0/1
   dw      0                   ;Segmentbasisadresse Byte 0/1
   db      0                  ;Segmentbasisadresse Byte 2
   db      10011010b   ;Zugriffsberechtigungen
   db      11001111b               ;Zusatz + Segmentgröße Bits 16 - 19
   db      0                  ;Segmentbasisadresse Byte 3

DATA_Desc:
   dw      0xFFFF
   dw      0
   db      0
   db      0x92
   db      0xCF
   db      0    

gdt:
   Limit   dw   0                  ;Größe der GDT (wird später eingetragen)
   Base   dd   0    

       
idts:
            makeIDT IRQ_00, 8, 10001110b
            makeIDT IRQ_00, 8, 10001110b
            makeIDT IRQ_00, 8, 10001110b
            makeIDT IRQ_00, 8, 10001110b
            makeIDT IRQ_00, 8, 10001110b
            makeIDT IRQ_00, 8, 10001110b
            makeIDT IRQ_00, 8, 10001110b
            makeIDT IRQ_00, 8, 10001110b
            makeIDT IRQ_00, 8, 10001110b
            makeIDT IRQ_00, 8, 10001110b
            makeIDT IRQ_00, 8, 10001110b
            makeIDT IRQ_00, 8, 10001110b
            makeIDT IRQ_00, 8, 10001110b
            makeIDT IRQ_00, 8, 10001110b
            makeIDT IRQ_00, 8, 10001110b
            makeIDT IRQ_00, 8, 10001110b
            makeIDT IRQ_00, 8, 10001110b
            makeIDT IRQ_00, 8, 10001110b
            makeIDT IRQ_00, 8, 10001110b
            makeIDT IRQ_00, 8, 10001110b
            makeIDT IRQ_00, 8, 10001110b
            makeIDT IRQ_00, 8, 10001110b
            makeIDT IRQ_00, 8, 10001110b
            makeIDT IRQ_00, 8, 10001110b
            makeIDT IRQ_00, 8, 10001110b
            makeIDT IRQ_00, 8, 10001110b
            makeIDT IRQ_00, 8, 10001110b
            makeIDT IRQ_00, 8, 10001110b
            makeIDT IRQ_00, 8, 10001110b
            makeIDT IRQ_00, 8, 10001110b
            makeIDT IRQ_00, 8, 10001110b
            makeIDT IRQ_01, 8, 10001110b
            makeIDT IRQ_01, 8, 10001110b

idt:
Limiti dw   0        ;Größe der IDT (wird später eingetragen)
Basei dd   0        ;Adresse der IDT (wird später eingetragen)


start:

cli
  ;Interrupts ausschalten

mov eax, cs ;EAX auf derzeitiges Codesegment setzen
mov ds, ax ;DS auf Codesegment setzen

shl eax, 4 ;EAX mit 16 multiplizieren (Lineare Adresse
;des Codesegments errechnen)



mov eax, cs ;Startadresse der GDT errechnen
shl eax, 4
add eax, NULL_Desc

mov [Base], eax ;Startadresse der GDT eintragen
mov [Limit], WORD gdt - NULL_Desc -1 ;Größe der GDT errechnen und eintragen

lgdt [gdt] ;GDT laden



   



mov eax, cr0 ;In den Protected Mode schalten,
or eax, 1 ;indem Bit 0 des CR0 Registers auf 1
mov cr0, eax ;gesetzt wird

jmp dword 0x8:PMODE
[BITS 32]                        ;32 Bit Code erstellen

PMODE:


   
   mov      eax, 2                  ;Selektor für das Datensegment erstellen
   shl      eax, 3
       
   mov      ds, ax                  ;Daten- Stack- und Extrasegment mit Datensegmentdeskriptor laden
   mov      ss, ax          
   mov      es, ax
   mov      eax, 0                  ;FS und GS mit Null-Deskriptor laden
   mov      fs, ax
   mov      gs, ax
   mov      esp, 0x2FFFFF               ;Stack setzen
jmp      0x8:0x10000 + PMODEy   ;Sprung in das "neue" Codesegment
       
PMODEy:    
   mov    [Limiti], word idt - idts -1
   
   

   
mov      eax, cs        ;Startadresse der IDT errechnen
   shl      eax, 4
   add      eax, idts
   mov    [Basei], eax
   
   

   

   lidt   [idt]                   ; Neuinit der Interrupt-Controller, sowie neu Setzen des Interrupt Mappings


   

                   ; Neuinit der Interrupt-Controller, sowie neu Setzen des Interrupt Mappings

  mov al,00010001b                      ; kaskadierte Interrupt-Controller und Flankentriggerung an beider Controller
   out 020h,al          
   out 0a0h,al

                           ; neuer IRQ-Vektor für den ersten Controller einstellen neuer Wert => IRQ0..7 -> INT20h..27h
   mov al,20h          
   out 021h,al

                           ; neuer IRQ-Vektor für den zweiten Controller einstellen neuer Wert => IRQ8..15 -> INT28h..2Fh
   mov al,28h          
   out 0a1h,al

                           ; Kaskadierung beider Controller einstellen
   mov al,00000100b                      ; Kaskadierung über IRQ2
   out 021h,al
   mov al,00000010b                      ; Kaskadierung über IRQ2
   out 0a1h,al

                           ; PIC auf Intel-Umgebung und manuelle Int.- Beendigung einstellen
   mov al,00000001b
   out 021h,al
   out 0a1h,al



PMODE2:    
   jmp      0x8:0x10000 + PMODE2            ;Endlosschleife

IRQ_00:
cli
   pusha
   push gs
   push fs
   push ds
   push es
 mov al,20h
       
            out 20h,al
   pop es
   pop ds
   pop fs
   pop gs
   popa
   iret


Gruss
Noooooooos

SSJ7Gohan

  • Beiträge: 398
    • Profil anzeigen
Gespeichert
« Antwort #15 am: 05. November 2005, 22:08 »
Mach mal oben ein org 0x10000 hin und ersetz dann
jmp 0x8:0x10000 + PMODEy
durch
jmp 0x8:PMODEy

Wo stürtzt der PC denn ab? Nach dem Label PMODE?

nooooooooos

  • Beiträge: 734
    • Profil anzeigen
Gespeichert
« Antwort #16 am: 06. November 2005, 07:47 »
So geht es immer noch nicht ganz. Allerdings ist dies Lock Fehlermeldung weg. Jetzt steht "Jump protected gate type 0 unsupported". Danch kommt wieder die Meldung "exeption 3rd....."

Gruss
Noooooooooooos

SSJ7Gohan

  • Beiträge: 398
    • Profil anzeigen
Gespeichert
« Antwort #17 am: 06. November 2005, 14:35 »
An welcher Stelle tritt das Problem denn auf?

nooooooooos

  • Beiträge: 734
    • Profil anzeigen
Gespeichert
« Antwort #18 am: 06. November 2005, 15:18 »
Beim Sprung in den PMODE

Gruss
Nooooooooooos

nooooooooos

  • Beiträge: 734
    • Profil anzeigen
Gespeichert
« Antwort #19 am: 07. November 2005, 12:22 »
Kann es sein, dass es daran liegt, weil ich das A20 Gate nicht aktiviert hab ?????


Grussss
Nooooooooooooooooooos

 

Einloggen