Lowlevel
Lowlevel => Lowlevel-Coding => Thema gestartet von: fabuloes am 05. May 2011, 20:58
-
N'Abend
Ich bin gerade dabei meine IDT für die IRQs einzurichten, also mit Software-Interrupts funktioniert alles super soweit.
Jetzt habe ich den PIC initialisiert, die IRQs alle unmaskiert und enablet , usw. aber wenn ich jetzt zum Test mal alle Einträge in der IDT auf eine Test-ISR (also mit Sicherung der Segmentregister, usw.) setze, erhalte ich sofort nach dem Start eine Exception 0x08 mit dem Errorcode e=0000...
Hat irgendjemand eine Ahnung was ich falsch machen könnte?
Gruß
-
An sich würde ich darauf tippen, dass du entweder a) den PIC nicht geremappt hast, dass also IRQ 0 zu einem Interrupt 8 führt (der dann wie eine Exception aussieht), oder b) die IDT initialisiert, geladen und das IF gesetzt hast, bevor du den PIC geremappt hast, sodass sich ein IRQ 0 als Interrupt 8 durchmogelt, bevor der PIC nach deinen Wünschen initialisiert ist. Zumindest mit letzterem hatte ich auch schon Probleme, wenngleich das eher Race Conditions waren (hin und wieder kam an der Stelle zwischen IDT- und PIC-Initialisierung eben zufällig ein IRQ 0 an).
-
Okay, also die Exception 0x08 wird gefangen, der PIC ist aber richtig geremappt. Beim Aufruf der ISR für die Exception hängts dann beim pop des Datenselektors %ds, weiß jemand woran das liegen kann? (alle Datensegemtnselektoren zeigen auf den 2ten Eintrag in der GDT, aber nur bei %ds funktioniert irgendwas nicht :S)
-
Wenn das pop %ds nach pop %es (und %fs und %gs) kommt, dann hast du möglicherweise ein Element zu wenig auf dem Stack. Das kann auch bedeuten, dass der Wert in ESP um 4 daneben liegt. Wenn das pop %ds der erste Befehl ist, der die Segmentregister lädt, ist es wahrscheinlicher, dass der Wert in ESP komplett falsch ist.
Ohne Code kann ich da erstmal nicht mehr zu sagen.
-
Also der Code sieht immo so aus:
irq_handler: # Wird von jeder Exception ausgegeben
pusha
push %ds
push %gs
push %es
push %fs
call isr
pop %fs
pop %es
pop %gs
pop %ds # Hier hängts
popa
iret
Und die dazugehörige ISR:
isr:
enter $0, $0
# Einen String zum Test ausgeben (msg = "Hallo Interrupt!")
pushl $msg
call put_str # Gibt den String aus
addl $4, %esp
leave
ret