Autor Thema: rudimentärer Tastaturtreiber geht nicht  (Gelesen 3447 mal)

Martin Erhardt

  • Beiträge: 165
    • Profil anzeigen
Gespeichert
« am: 12. July 2012, 12:32 »
Guten Morgen,
Sofort nach dem aktivieren der Tastatur mit "outb(0x60,  0xF4);" wird ein Tastatur IRQ ausgelöst. Danach gehen Interrupts nicht mehr.
Wenn man Interrupts erst nach der Aktivierung anschaltet. Wird nach asm volatile("sti") sofort ein Tastatur IRQ ausgelöst.
Ich glaube eher nicht das es ein Spurious Interrupt ist, weil:
1. Ich den selben Treiber auf tut kernel 5 erfolgreich zum laufen gebracht habe
2. Es unwahrscheinlich ist das immer ein Spurious Interrupt ausgelöst wird
Mein kernel erkennt aber keine Spurious Interrupts
Qemu.log(In der der Inhalt des ISR Registers leider nicht verzeichnet ist):
SMM: enter
EAX=00000001 EBX=17fe12b0 ECX=02000000 EDX=00000cfc
ESI=000f321d EDI=0003802d EBP=17fe10d0 ESP=00006f08
EIP=000f384b EFL=00000002 [-------] CPL=0 II=0 A20=1 SMM=0 HLT=0
ES =0010 00000000 ffffffff 00cf9300 DPL=0 DS   [-WA]
CS =0008 00000000 ffffffff 00cf9b00 DPL=0 CS32 [-RA]
SS =0010 00000000 ffffffff 00cf9300 DPL=0 DS   [-WA]
DS =0010 00000000 ffffffff 00cf9300 DPL=0 DS   [-WA]
FS =0010 00000000 ffffffff 00cf9300 DPL=0 DS   [-WA]
GS =0010 00000000 ffffffff 00cf9300 DPL=0 DS   [-WA]
LDT=0000 00000000 0000ffff 00008200 DPL=0 LDT
TR =0000 00000000 0000ffff 00008b00 DPL=0 TSS32-busy
GDT=     000fd3a8 00000037
IDT=     000fd3e6 00000000
CR0=00000011 CR2=00000000 CR3=00000000 CR4=00000000
DR0=0000000000000000 DR1=0000000000000000 DR2=0000000000000000 DR3=0000000000000000
DR6=00000000ffff0ff0 DR7=0000000000000400
CCS=000f31f0 CCD=00000001 CCO=LOGICB 
EFER=0000000000000000
SMM: after RSM
EAX=00000001 EBX=17fe12b0 ECX=02000000 EDX=00000cfc
ESI=000f321d EDI=0003802d EBP=17fe10d0 ESP=00006f08
EIP=000f384b EFL=00000002 [-------] CPL=0 II=0 A20=1 SMM=0 HLT=0
ES =0010 00000000 ffffffff 00c09300 DPL=0 DS   [-WA]
CS =0008 00000000 ffffffff 00c09b00 DPL=0 CS32 [-RA]
SS =0010 00000000 ffffffff 00c09300 DPL=0 DS   [-WA]
DS =0010 00000000 ffffffff 00c09300 DPL=0 DS   [-WA]
FS =0010 00000000 ffffffff 00c09300 DPL=0 DS   [-WA]
GS =0010 00000000 ffffffff 00c09300 DPL=0 DS   [-WA]
LDT=0000 00000000 0000ffff 00008200 DPL=0 LDT
TR =0000 00000000 0000ffff 00008b00 DPL=0 TSS32-busy
GDT=     000fd3a8 00000037
IDT=     000fd3e6 00000000
CR0=00000011 CR2=00000000 CR3=00000000 CR4=00000000
DR0=0000000000000000 DR1=0000000000000000 DR2=0000000000000000 DR3=0000000000000000
DR6=00000000ffff0ff0 DR7=0000000000000400
CCS=00000000 CCD=00000000 CCO=EFLAGS 
EFER=0000000000000000
     0: v=21 e=0000 i=0 cpl=0 IP=0008:0000000000100357 pc=0000000000100357 SP=0010:0000000000104f80 EAX=00000000000000f4
EAX=000000f4 EBX=00036d04 ECX=000b8000 EDX=00000060
ESI=0005d987 EDI=0005d976 EBP=00104fa8 ESP=00104f80
EIP=00100357 EFL=00000202 [-------] CPL=0 II=0 A20=1 SMM=0 HLT=0
ES =0010 00000000 ffffffff 00cf9300 DPL=0 DS   [-WA]
CS =0008 00000000 ffffffff 00cf9a00 DPL=0 CS32 [-R-]
SS =0010 00000000 ffffffff 00cf9300 DPL=0 DS   [-WA]
DS =0010 00000000 ffffffff 00cf9300 DPL=0 DS   [-WA]
FS =0010 00000000 ffffffff 00cf9300 DPL=0 DS   [-WA]
GS =0010 00000000 ffffffff 00cf9300 DPL=0 DS   [-WA]
LDT=0000 00000000 0000ffff 00008200 DPL=0 LDT
TR =0000 00000000 0000ffff 00008b00 DPL=0 TSS32-busy
GDT=     00105020 00000027
IDT=     00105060 000007ff
CR0=00000011 CR2=00000000 CR3=00000000 CR4=00000000
DR0=0000000000000000 DR1=0000000000000000 DR2=0000000000000000 DR3=0000000000000000
DR6=00000000ffff0ff0 DR7=0000000000000400
CCS=00000008 CCD=00104f70 CCO=SUBL   
EFER=0000000000000000
Im Anhang ist mein OS Quellcode.

MNemo

  • Beiträge: 547
    • Profil anzeigen
Gespeichert
« Antwort #1 am: 12. July 2012, 13:31 »
Ich habe nur asm volatile ("int $0x21"); (in der init.c) auskommentiert und
if(intr != 0x20) vor dem print(INT#) (im irq-handler) eingefügt. Und es funktioniert alles wunder bar.

„Wichtig ist nicht, besser zu sein als alle anderen. Wichtig ist, besser zu sein als du gestern warst!“

kevin

  • Administrator
  • Beiträge: 2 767
    • Profil anzeigen
Gespeichert
« Antwort #2 am: 12. July 2012, 13:39 »
Die Tastatur antwortet auf deinen Aktivierungsbefehl mit einer Bestätigung (0xfa), die du auf dem Datenport auslesen musst. Deswegen gibt es auch den IRQ. Solange du den Puffer nach einem IRQ nicht ausgelesen hast, sendet der Tastaturkontroller auch keinen neuen IRQ mehr, wenn noch mehr dazukommt.
Thou shalt not follow the NULL pointer, for chaos and madness await thee at its end.

Martin Erhardt

  • Beiträge: 165
    • Profil anzeigen
Gespeichert
« Antwort #3 am: 12. July 2012, 13:50 »
@taljeth Ja Ich bekome FA(dec: 250) mit inb(0x60) aber es kommt trotzdem kein IRQ mehr.
@MNemo asm volatile ("int $0x21") habe ich nur gemacht um zu testen ob man noch IRQs softwareseitig auslösen kann
Das vorgeschlagene if verstehe ich nicht:
if(intr != 0x20){
kprintf("Interrupt: %d\n", cpu->intr);
if (cpu->intr >= 0x28) {
            // EOI an Slave-PIC
     outb(0xa0, 0x20);
}else if(cpu->intr==0x21){on_key_event(0x21);}
// EOI an Master-PIC
outb(0x20, 0x20);
}
Trotzdem Danke
« Letzte Änderung: 12. July 2012, 13:53 von Martin Erhardt »

MNemo

  • Beiträge: 547
    • Profil anzeigen
Gespeichert
« Antwort #4 am: 12. July 2012, 13:58 »
Das das int 0x21 nur zum testen da war war mir klar, aber IRQs löst du damit nicht aus. Sondern nur ganz normale Soft-Interrupts die du nicht mal mit 'cli' verhindern könntest.

if(cpu->intr != 0x20)
  kprintf("Interrupt: %d\n", cpu->intr);
Weil der Timer dir sonst, doch ziemlich penetrant, den Bildschirm zu spamt. EOIs müssen natürlich trotzdem gesendet werden.

[Edit]
Getestet habe ich das übrigens mit
make; qemu-system-x86-64 -kernel kernel

mit und ohne -no-kvm beides hat funktioniert
Zitat von: qemu-system-x86-64 --version
QEMU emulator version 1.0 (qemu-kvm-1.0), Copyright (c) 2003-2008 Fabrice Bellard
« Letzte Änderung: 12. July 2012, 14:03 von MNemo »
„Wichtig ist nicht, besser zu sein als alle anderen. Wichtig ist, besser zu sein als du gestern warst!“

Martin Erhardt

  • Beiträge: 165
    • Profil anzeigen
Gespeichert
« Antwort #5 am: 12. July 2012, 14:10 »
Seltsam, bei meine iso geht sowohl in virtual box als auch QEMU nicht.
Oder irgendwasanderes anderes z.b im PIC stimmt nicht. Also im tut kernel 5 funktioniert der Kernel
« Letzte Änderung: 12. July 2012, 14:54 von Martin Erhardt »

kevin

  • Administrator
  • Beiträge: 2 767
    • Profil anzeigen
Gespeichert
« Antwort #6 am: 13. July 2012, 10:14 »
@taljeth Ja Ich bekome FA(dec: 250) mit inb(0x60) aber es kommt trotzdem kein IRQ mehr.
Und das Statusregister sagt, dass der Puffer leer ist?

Hm, wenn man mal beim PIC statt bei der Tastatur ansetzt: Sendest du den EOI?
Thou shalt not follow the NULL pointer, for chaos and madness await thee at its end.

Martin Erhardt

  • Beiträge: 165
    • Profil anzeigen
Gespeichert
« Antwort #7 am: 13. July 2012, 10:38 »
Der Wert des Statusregisters( mit kprintf("StatusRegister:%d", inb(0x64) ); ) gelesen ist nach und vor der Aktivierung 0x1c, also ganz normal.
Trotzdem erfahre ich mit (kprintf("Ausgabepuffer:%d", inb(0x60) ), dass auch nach dem Bestätigungs IRQ noch 0xfa im Puffer ist.
Wenn Ich versuche ihn im Handler gewaltsam mit outb(0x60, 0x00);zu leeren wird immer wieder der Bestätigungs IRQ ausgelöst wird:
Ja ein EOI SOLLTE zumindest gesendet werden wie man hier sieht:
void handle_irq(struct cpu_state* cpu)
{
kprintf("Interrupt: %d\n", cpu->intr);
if (cpu->intr >= 0x28) {
            // EOI an Slave-PIC
            outb(0xa0, 0x20);
}else if(cpu->intr==0x21){on_key_event(0x21);}
// EOI an Master-PIC
outb(0x20, 0x20);
}

Martin Erhardt

  • Beiträge: 165
    • Profil anzeigen
Gespeichert
« Antwort #8 am: 13. July 2012, 14:37 »
Hurra Problem gelöst :-D
Ich habe einen alten Programmier Trick angewandt.
Nehme ein ähnliches Projekt deiner Wahl(tut 5) und ersetze den Quellcode schrittweise bis nur noch deiner da ist und wenn du Glück hast funktionierts.
Danke für die Hilfe!

kevin

  • Administrator
  • Beiträge: 2 767
    • Profil anzeigen
Gespeichert
« Antwort #9 am: 13. July 2012, 15:50 »
Und hast du dabei auch rausgefunden, wo der entscheidende Unterschied lag?
Thou shalt not follow the NULL pointer, for chaos and madness await thee at its end.

Martin Erhardt

  • Beiträge: 165
    • Profil anzeigen
Gespeichert
« Antwort #10 am: 13. July 2012, 17:36 »
Ich weiß es nicht genau aber mein Buildskript startet auch Qemu und es könnte sein,dass im Skript für das tutorial andere Qemu parameter verwendet wurden. Anders kann Ich mir nicht erklären wie es auf MNemo′s Maschine funktionieren kann.

 

Einloggen