Lowlevel

Lowlevel => Lowlevel-Coding => Thema gestartet von: Developer30 am 04. August 2013, 12:57

Titel: IRQ1 / Tastatur funktioniert nicht?
Beitrag von: Developer30 am 04. August 2013, 12:57
Hallo  :-)

Ich möchte gerne Tastatureingaben mit dem IRQ1 abfangen. Dazu habe ich die PICs initialisiert und für jeden IRQ eine Funktion in der IDT eingetragen. Die Funktionen sind über den int Befehl auch alle erreichbar (d.h. meine IDT scheint schonmal korrekt zu sein).

Den PIC habe ich folgendermaßen initialisiert:

// Master-PIC initialisieren
outb(0x20, 0x11); // Initialisierungsbefehl fuer den PIC
outb(0x21, 0x20); // Interruptnummer fuer IRQ 0
outb(0x21, 0x04); // An IRQ 2 haengt der Slave
outb(0x21, 0x01); // ICW 4

// Slave-PIC initialisieren
outb(0xa0, 0x11); // Initialisierungsbefehl fuer den PIC
outb(0xa1, 0x28); // Interruptnummer fuer IRQ 8
outb(0xa1, 0x02); // An IRQ 2 haengt der Slave
outb(0xa1, 0x01); // ICW 4

// Interrupts verknüpfen
IDT::SetGate(0x20, _irq0, 0x08, 0x8E);
IDT::SetGate(0x21, _irq1, 0x08, 0x8E);
IDT::SetGate(0x22, _irq2, 0x08, 0x8E);
IDT::SetGate(0x23, _irq3, 0x08, 0x8E);
IDT::SetGate(0x24, _irq4, 0x08, 0x8E);
IDT::SetGate(0x25, _irq5, 0x08, 0x8E);
IDT::SetGate(0x26, _irq6, 0x08, 0x8E);
IDT::SetGate(0x27, _irq7, 0x08, 0x8E);
IDT::SetGate(0x28, _irq8, 0x08, 0x8E);
IDT::SetGate(0x29, _irq9, 0x08, 0x8E);
IDT::SetGate(0x2A, _irq10, 0x08, 0x8E);
IDT::SetGate(0x2B, _irq11, 0x08, 0x8E);
IDT::SetGate(0x2C, _irq12, 0x08, 0x8E);
IDT::SetGate(0x2D, _irq13, 0x08, 0x8E);
IDT::SetGate(0x2E, _irq14, 0x08, 0x8E);
IDT::SetGate(0x2F, _irq15, 0x08, 0x8E);

// Alle IRQs aktivieren (demaskieren)
outb(0x20, 0x0);
outb(0xa0, 0x0);

Anschließend lade ich die IDT und initialisiere dann die Tastatur:
// Tastaturpuffer leeren
while (inb(0x64) & 0x1)
    inb(0x60);

// Warten bis die Tastatur bereit ist, und der Befehlspuffer leer ist
while ((inb(0x64) & 0x2)) {}
outb(0x60, 0xF4);

In meiner _irq1 Prozedur erzeuge ich eine Bildschirmausgabe, sodass ich ja sehen sollte, wenn eine Taste gedrückt wird. Außerdem lade ich mit inb(0x60) den Scancode und setze danach EOI für den IRQ1.

Wenn ich meinen Kernel mit bochs ausführe, dann erscheint zu beginn direkt einmal, dass eine Taste gedrückt wurde, obwohl ich noch gar nichts gedrückt habe. Wenn ich dann weitere Tasten auf der Tastatur drücke passiert nichts. Irgendwann steht dann auch in der bochs Konsole:

00103620000i[KBD  ] internal keyboard buffer full, ignoring scancode.(1e)
00105448000i[KBD  ] internal keyboard buffer full, ignoring scancode.(1f)
00106000000i[KBD  ] internal keyboard buffer full, ignoring scancode.(20)
00106516000i[KBD  ] internal keyboard buffer full, ignoring scancode.(9e)

Es ist mir bald schon peinlich, dass das, woran ich hier scheitere, auf der Tutorialseite mit einem Stern als "einfach" eingestuft wird. Ich hoffe dennoch auf Hilfe und Verständnis für Anfängerfehler.

lg
Developer30
Titel: Re: IRQ1 / Tastatur funktioniert nicht?
Beitrag von: Svenska am 04. August 2013, 13:33
Die Tastatur löst genau einen IRQ aus, wenn eine Taste gedrückt wurde. Danach schweigt sie, bis sie gefragt wurde.

Lies den Scancode in der ISR von der Tastatur, dann kommen auch wieder IRQs.
Titel: Re: IRQ1 / Tastatur funktioniert nicht?
Beitrag von: Developer30 am 04. August 2013, 14:27
Lies den Scancode in der ISR von der Tastatur, dann kommen auch wieder IRQs.

Bezwecke ich das nicht mit inb(0x60)?

In meiner _irq1 Prozedur erzeuge ich eine Bildschirmausgabe, sodass ich ja sehen sollte, wenn eine Taste gedrückt wird. Außerdem lade ich mit inb(0x60) den Scancode und setze danach EOI für den IRQ1.
Titel: Re: IRQ1 / Tastatur funktioniert nicht?
Beitrag von: Jidder am 04. August 2013, 16:19
Sendest du nach der Bearbeitung des Keyboard-Interrupts auch ein EOI an den PIC? http://www.lowlevel.eu/wiki/PIC_Tutorial#ISRs_programmieren
Titel: Re: IRQ1 / Tastatur funktioniert nicht?
Beitrag von: Developer30 am 04. August 2013, 16:50
Ja, ich sende ein EOI.

Ich habe mein kleines Projekt mal hochgeladen. Ich wäre sehr dankbar, wenn ihr eventuell selbst mal einen Blick in mein Code werfen könntet. Ich bin für (sonstige, stilistsiche) Verbesserungsvorschläge gerne offen und hoffe, dass der Fehler so besser gefunden werden kann.

Hier der Downloadlink: http://www.file-upload.net/download-7922666/os.tar.gz.html (http://www.file-upload.net/download-7922666/os.tar.gz.html)

lg
Developer30
Titel: Re: IRQ1 / Tastatur funktioniert nicht?
Beitrag von: Jidder am 04. August 2013, 17:05
Du musst Assembler-Stubs in die IDT eintragen. C-Funktionen (PIC::_irq0, etc...) gehen nicht. Der Grund dafür ist (unter anderem), dass du aus einem Interrupt mit dem Maschinenbefehl IRET zurückkehren musst, aber der C-Code verwendet RET. Wir haben dazu ein Tutorial (http://www.lowlevel.eu/wiki/Teil_5_-_Interrupts), das GAS-Syntax verwendet, und ein etwas geschwätzigeres (http://www.lowlevel.eu/wiki/ISR) mit NASM-Syntax.
Titel: Re: IRQ1 / Tastatur funktioniert nicht?
Beitrag von: Developer30 am 04. August 2013, 17:08
d.h. ich definiere in Assembler Labels, die ich dann über extern in C/C++ eintragen kann und rufe meine eigentliche C/C++ Funktion dann mit call auf? Habe ich das richtig verstanden?
Titel: Re: IRQ1 / Tastatur funktioniert nicht?
Beitrag von: Jidder am 04. August 2013, 17:09
Jep.
Titel: Re: IRQ1 / Tastatur funktioniert nicht?
Beitrag von: Developer30 am 04. August 2013, 18:25
Ok, ich habe das mal so umgesetzt. Es funktioniert, wie zu erwarten war  :-)
Danke :wink: