idt aufsetzen
-
Das __attribute__((packed)) hat leider nichts gebracht.
Der Selektor den ich verwende ich genau der des Codesegments (mit Offset 0 und 4 GiB Größe). Muss man noch ein spezielles Interrupt-Segment in der GDT anlegen???
-
Muss man eventuell explizit den PIC anschalten? Wenn ja: Wie geht das bzw. wo finde ich Infos darüber?
-
hi,
Wieso verwendest du hier
for(int i = 0; i < NUM_IDT_ENTRIES; i++) fill_idt_entry(&entries[i], (_u32)interrupt0, 1, ACS_INT, 0);
1 als Selektor??? Der Selektor bezieht sich auf die GDT. Falls beispielsweise dein Codesegmentdeskriptor den Index (!) 1 in der GDT hat, dann musst du als Selektor 0x08 verwenden. Aufbau eines Selektors findest du im Intel Architecture Software Developer's Manual Volume 3 - System Programming Guide.
Wieso verwendest du im selben Codeabschnitt ein 286-Interrupt-Gate? Du bist wahrscheinlich (wie ich dem anderen Thread entnehme) im 32Bit Protected-Mode, da muss man dann schon ein 386-Interrupt-Gate nehmen (0x0E)!
Nur zur Info: Alles mit 286 is 16Bit. Alles mit 386+ is 32Bit.
-
hackbert schrieb:
Muss man eventuell explizit den PIC anschalten? Wenn ja: Wie geht das bzw. wo finde ich Infos darüber?
Ja man sollte die PIC initialisieren, da sie im real-mode die IRQ (=Interrupt Requests) 0-0x0F auf die Interrupts 0x08-0x17 abgebildet. Das Problem daran ist, dass im Protected-Mode alle Interrupts von 0x00 bis 0x20 (ausschließlich) für den Prozessor reserviert sind, d.h. du musst das IRQ to Interrupt maping der PIC verändern. Auf Bona Fide (http://www.osdever.net/ gibts beispielsweise ein Tutorial (http://www.osdever.net/tutorials/pdf/pic.pdf). Vielleicht auch dieses über irq's.
-
Der Tipp mit dem PIC war super! Jetzt startet der Rechner nicht mehr neu
Nur wird meine ISR net aufgerufen...
-
Muss man neben sti und dem Aktivieren des PICs noch andere Aktionen durchführen um Interrupts zu benutzen?
-
Hi.
Bei deinem ganzen Code habe ich irgendwo den Ueberblick verloren. Um wieder etwas mehr Klarheit in die Sache zu bringen, moechte ich dich bitten, klar zwischen "Software Interrupts" (aufgerufen mit "int") und "Hardware Interrupts" (IRQs, Exceptions) zu unterscheiden.
Um interrupts ueber int aufzurufen, brauchst du naemlich weder am PIC, noch am Interrupt-Flag zu drehen.Wenn du also nichts mit den IRQs machen willst, solltest du den PIC einfach ausgeschaltet und das Interrupt-Flag geloescht lassen. Wenn die IDT stimmt und deine ISR richtig funktioniert, muesste dann alles laufen.
Fuer IRQs nochmal der Hinweis: Das Freischalten des PIC allein reicht nicht - du musst den Basisinterrupt fuer den primaeren PIC auf jeden Fall auf eine Nummer > 20h legen. Dann noch ein sti, und zumindest der PIT-IRQ (0) muesste regelmaessig ausgeloest werden.
-
Also. Ich habe erstmal alle Interruppts mit einer ISR versorgt. Das allerdings nur zu Testzwecken! Ich will später sowohl Software-Interrupts, als auch Interrupts von Hardware und Exceptions bearbeiten. Ich brauchte nur erstmal was zum Testen um zu sehen, ob mein IDT richtig ist. PIC1 und 2 arbeiten nun im kaskadierenden Modus, es wurden also die Interrupts richtig für den PM gemappt.
Hackbert
<edit>ein manuelles Auslösen eines Software-Interrupts führt derzeit zu Problemen: asm volatile("int $0x80");</edit>
Die PICs initialisiere ich vor dem sti so:
#include <pmode.h> #include <pic.h> void _init_pic() { _init_pics_cascade(0x20, 0x28); } #define PIC1 0x20 #define PIC2 0xA0 #define ICW1 0x11 #define ICW4 0x01 /* _init_pics_cascade() * init the PICs and remap them */ void _init_pics_cascade(int pic1, int pic2) { /* send ICW1 */ outb(PIC1, ICW1); outb(PIC2, ICW1); /* send ICW2 */ outb(PIC1 + 1, pic1); /* remap */ outb(PIC2 + 1, pic2); /* pics */ /* send ICW3 */ outb(PIC1 + 1, 4); /* IRQ2 -> connection to slave */ outb(PIC2 + 1, 2); /* send ICW4 */ outb(PIC1 + 1, ICW4); outb(PIC2 + 1, ICW4); /* disable all IRQs */ outb(PIC1 + 1, 0xFF); }
-
bluecode schrieb:
hi,
Wieso verwendest du hier
for(int i = 0; i < NUM_IDT_ENTRIES; i++) fill_idt_entry(&entries[i], (_u32)interrupt0, 1, ACS_INT, 0);
1 als Selektor??? Der Selektor bezieht sich auf die GDT. Falls beispielsweise dein Codesegmentdeskriptor den Index (!) 1 in der GDT hat, dann musst du als Selektor 0x08 verwenden. Aufbau eines Selektors findest du im Intel Architecture Software Developer's Manual Volume 3 - System Programming Guide.
Wieso verwendest du im selben Codeabschnitt ein 286-Interrupt-Gate? Du bist wahrscheinlich (wie ich dem anderen Thread entnehme) im 32Bit Protected-Mode, da muss man dann schon ein 386-Interrupt-Gate nehmen (0x0E)!
Nur zur Info: Alles mit 286 is 16Bit. Alles mit 386+ is 32Bit.Wollts nur noch mal sagen, weil ich nicht glaub, dass du 's gelesen hast...
-
*lol* Respekt, dass du das alles durchgehst - vielleicht hilft's ja, wenn ich dich quote...?
-
bluecode schrieb:
Wollts nur noch mal sagen, weil ich nicht glaub, dass du 's gelesen hast...
Doch, doch. Gelesen habe ich das. Und geändert habe ich es auch. gleicher Effekt: auch mit Selektor 8 ist nichts anzufangen...
<edit>Auch das definieren von ACS_INT_GATE auf:
#define ACS_INT_GATE 0x0E
ändert nichts...</edit>