Autor Thema: General Protection Fault  (Gelesen 2617 mal)

Roadrunner

  • Beiträge: 33
    • Profil anzeigen
Gespeichert
« am: 14. September 2012, 16:58 »
Ich habe vor kurzem ein neues OS begonnen, bei dem ich die ISRs in Assembler implementieren wollte. Das hat auch soweit gut funktioniert, allerdings kehrt der Handler nie zurück, wenn ich zum Testen der IDT im Kernel z. B. den Interrupt 55 auslöse, der noch nicht eingetragen ist. Der Handler wird auch tatsächlich aufgerufen, allerdings funktioniert der Befehl "iret" nicht. Hier der Code:

isr_0D:
    pop dword [int_ec] ;Den Error-Code vom Stack nehmen
    iret

Habe ich hier irgend was übersehen? Ich weiß echt nicht mehr weiter...
Exception 0x1A: Insufficient user-IQ

micha

  • Beiträge: 141
    • Profil anzeigen
Gespeichert
« Antwort #1 am: 14. September 2012, 17:11 »
bevor du mit iret aus deinen interrupthandler springst, musst du ein EOI (end of interrupt) an den PIC senden.

Jidder

  • Administrator
  • Beiträge: 1 625
    • Profil anzeigen
Gespeichert
« Antwort #2 am: 14. September 2012, 17:37 »
bevor du mit iret aus deinen interrupthandler springst, musst du ein EOI (end of interrupt) an den PIC senden.
Nur bei IRQs, nicht bei Softwareinterrupts.

Meine Vermutung ist, dass der Stack nicht richtig eingerichtet ist. Kannst du prüfen, ob der Stackpointer einen sinnvollen Wert hat?
Dieser Text wird unter jedem Beitrag angezeigt.

Roadrunner

  • Beiträge: 33
    • Profil anzeigen
Gespeichert
« Antwort #3 am: 15. September 2012, 13:28 »
Ja. Hier die ersten Einträge des Stacks (esp hat den Wert 0xFFFFD0; das kommt hin, da esp am Anfang auf 1 MiB gesetzt wurde):

0xAAA ;Letzter Wert (oben)
0x007
0x246
0x008
0x0BE
0x1BA ;Erster Wert (unten)
Exception 0x1A: Insufficient user-IQ

Jidder

  • Administrator
  • Beiträge: 1 625
    • Profil anzeigen
Gespeichert
« Antwort #4 am: 15. September 2012, 13:36 »
Ja. Hier die ersten Einträge des Stacks (esp hat den Wert 0xFFFFD0; das kommt hin, da esp am Anfang auf 1 MiB gesetzt wurde):
0xffffd0 ist nicht in der Nähe von 1MB, sondern 16MB. Den Stack auf 1 MB (0x100000) zu setzen ist außerdem nicht korrekt, weil das im BIOS liegt. Das ist ein ROM, das in den physischen Adressraum gemappt wurde, und ist nicht beschreibbar. Das heißt wenn ein Interrupt auftritt, werden keine Werte auf den Stack geschrieben, und das IRET liest ungültige Werte vom Stack. Das würde den GPF erklären, wenn du den Stack tatsächlich an der Adresse 1 MB hast. Es gibt zwar die Möglichkeit, dass es auch unbeschreibbaren Speicher in der Nähe von 16 MB gibt, aber das sollte nicht der Fall sein. Du kannst trotzdem mal versuchen den Stack woanders hinzulegen, z.B. so wie in diesem Tutorial in einem eigens dafür reservierten Bereich im Kernel.

Zitat
0xAAA ;Letzter Wert (oben)
0x007
0x246
0x008
0x0BE
0x1BA ;Erster Wert (unten)
Das sind 12-Bit Werte. Du solltest 32-Bit Werte ausgeben lassen. (Oder Bytes)
« Letzte Änderung: 15. September 2012, 14:19 von Jidder »
Dieser Text wird unter jedem Beitrag angezeigt.

Roadrunner

  • Beiträge: 33
    • Profil anzeigen
Gespeichert
« Antwort #5 am: 15. September 2012, 13:42 »
Ich probier gleich mal, den Stack woanders hin zu legen. Was die Ausgabewerte betrifft: Meine Funktion zur Ausgabe von Zahlen gibt keine führenden Nullen aus. Die Werte hier waren alle nicht länger als 3 Stellen, also hab ich sie schnell mal ergänzt, damit es auch ordentlich aussieht. Die Funktion könnte aber auch Werte wie 0x78787878 ausgeben - sie benutzt als Parameter einen 32-Bit-Wert.
Exception 0x1A: Insufficient user-IQ

 

Einloggen