Autor Thema: Sofortige Tastaturinterrupt nach Aktivieren der Hardwareinterrupts  (Gelesen 9525 mal)

s137

  • Beiträge: 110
    • Profil anzeigen
Gespeichert
Hallo zusammen,

Ich habe mittlerweile ein externes Testprogramm als flache Binary geschrieben und auch entsprechend als Mutlibootmodul geladen. Nur sobald ich mit dem im Tutorial gegebenen Code den Task (also das Multiboot Modul, sprich das externe Tetsprogramm) initialisieren möchte und danach die Hardwareinterrupts aktiviere, bekomme ich sofort nach der Aktivierung, einen Tastaturinterrupt, bei dem ich im Interrupthandler bisher nur eine kleine Infoausgabe definiert habe. Ich habe noch keine Keyboardtreiber und habe auch die Tastatur noch in keinster Weise aktiviert. Wie kann ich dann einen Tastaturinterrupt bekommen?

Vielen Dank schonmal für eure Hilfe
s137

OsDevNewbie

  • Beiträge: 282
    • Profil anzeigen
    • YourOS Kernel
Gespeichert
« Antwort #1 am: 29. November 2014, 17:14 »
Hallo,
Tastaturinterrupts kannst du trotzdem bekommen. Da ist es egal, ob du einen Treiber hast oder nicht. Du kannst aber die Tastaturinterrupts ausschalten, indem du beim PIC das entsprechende Bit löscht.
Weil du einen Tastaturinterrupt bekommst, heisst das wahrscheinlich dass irgendwann mal eine Taste gedrückt wurde.
Ich hoffe ich konnte dir helfen.
Viele Grüsse
OsDevNewbie

Ein Computer ohne Betriebsystem ist nicht mehr wert als ein Haufen Schrott.
Ein Computer ist eine Maschine, die einem Lebewesen das kostbarste klaut, was sie selber nicht hat:
DIE ZEIT DES LEBENS

s137

  • Beiträge: 110
    • Profil anzeigen
Gespeichert
« Antwort #2 am: 29. November 2014, 17:24 »
Oh ok, das mit dem PIC werd ich mal ausprobieren, aber ich habe definitv keine Taste gedrückt... Wenn dann erst nach dem Tastaturinterrupt...

s137

  • Beiträge: 110
    • Profil anzeigen
Gespeichert
« Antwort #3 am: 29. November 2014, 17:47 »
Also gut habe mal mit "outb(0x20, 0x02);" den Tastaturinterrupt maskiert, bekomme jedoch weiterhin einen Tastaturinterrupt, und sonst nichts anderes.

Hier mal mein Interrupthandler:

struct cpu_state* handle_interrupt(struct cpu_state* cpu)
{

  struct cpu_state* new_cpu = cpu;

  if (cpu->intr <= 0x1f) {
        // kprintf("Exception %d, Kernel angehalten!\n", cpu->intr);
           kputs("Exception: ");
           kputn(cpu->intr, 10);
           kputs("\n Fehlercode: ");
           kputn(cpu->error, 16);

           debug(cpu, 1, "EXCEPTION:");

           kputs("\n Kernel angehalten! \n");

        while(1) {
            // Prozessor anhalten
            asm volatile("cli; hlt");
        }
   } else {
        // Hier den Hardwareinterrupt behandeln
        // kputs("Hardwareinterrupt");

        if (cpu->intr >= 0x20 && cpu->intr <= 0x2f) {

           if (cpu->intr == 0x20) {
            new_cpu = schedule(cpu);
            set_tss_entry(1, (unsigned long) (new_cpu + 1));
           }

           if (cpu->intr == 0x21) {
            debug(cpu, 1, "Tastaturinterrupt:");
           }

           if (cpu->intr >= 0x28) {
             outb(0xa0, 0x20); // End of Interrupt: Slave PIC
            }

            outb(0x20, 0x20); // End of Interrupt: Master PIC
        }

        if (cpu->intr == 0x30) {
            new_cpu = syscall(cpu);
        }

   }
return new_cpu;
}


Danke schonmal für den Tipp mit dem PIC^^
« Letzte Änderung: 29. November 2014, 17:49 von s137 »

s137

  • Beiträge: 110
    • Profil anzeigen
Gespeichert
« Antwort #4 am: 29. November 2014, 19:24 »
Edit: Ich hatte den Falschen Befehl für das maskieren benutzt, es muss natürlich "outb(0x21, 0x02)" heißen... Zwar bekomme ich dann keinen Tastaturinterrupt mehr.. Das eigentliche Problem löst das aber nicht.. Denn mein Task wird trotzdem nicht ausgeführt... Es passiert dann einfach nichts... Und irgendwo muss der Tastaturinterrupt ja auch hergekommen sein, oder?
« Letzte Änderung: 29. November 2014, 19:29 von s137 »

kevin

  • Administrator
  • Beiträge: 2 767
    • Profil anzeigen
Gespeichert
« Antwort #5 am: 29. November 2014, 20:12 »
Den Tastaturinterrupt bekommt man typischerweise, weil man im Bootmenü Enter gedrückt hat. Den Makecode verarbeitet zwar GRUB noch, aber den Breakcode kriegt unter Umständen dein OS.

Wie du festgestellt hast, hat das aber mit deinem Problem eher nichts zu tun.
Thou shalt not follow the NULL pointer, for chaos and madness await thee at its end.

s137

  • Beiträge: 110
    • Profil anzeigen
Gespeichert
« Antwort #6 am: 29. November 2014, 21:23 »
Ah ok, danke, das macht sinn :DD

Ich debugge, das ganze später mal noch ein bisschen mehr um rauszufinden an was es liegt..

s137

  • Beiträge: 110
    • Profil anzeigen
Gespeichert
« Antwort #7 am: 30. November 2014, 00:00 »
Also beim Debugging des Tastaturinterrupts nach dem nichts mehr passiert, ist mir der veränderte EFLAGS Wert aufgefallen, welcher nicht 0x202 war, sonder 0x213, es waren also das Carry Flag und das Nested Task Flag gesetzt. Ich wüsste allerdings nicht wo ich in meinem Code einen "Overflow bei vorzeichenloser Berechnung" haben sollte… und den Zweck des "Nested Task Flag" hab ich auch noch nicht ganz verstanden...

Jidder

  • Administrator
  • Beiträge: 1 625
    • Profil anzeigen
Gespeichert
« Antwort #8 am: 30. November 2014, 01:10 »
Die gesetzen Flags in 0x213 sind das Direction Flag (0x200), das Auxilary Carry Flag (0x10) und das Carry Flag (0x1). Das Nested Task Flag ist 0x4000 und hier nicht gesetzt. Dass da Flags von arithmetischen Operationen gesetzt sind, ist ganz normal, denn dein Compiler generiert Code, der mathematische und logische Operationen enthält.
Dieser Text wird unter jedem Beitrag angezeigt.

s137

  • Beiträge: 110
    • Profil anzeigen
Gespeichert
« Antwort #9 am: 30. November 2014, 01:15 »
oh ok, danke :DD

naja ich habs jetzt (durch veränderungen im Userprogramm das als Multiboot Modul geladen wird) geschafft dass sich das Modul initialisert und ausgeführt wird, alerdings tritt direkt nach der Ausführung ein GPF auf mit dem Fehlercode: 2000. Diesen Fehlercode kann ich irgendiwe nicht genau analysieren, da dort ja keins der unteren Bits gesetzt ist.

Kann mir da irgendjemand weiterhelfen?

Jidder

  • Administrator
  • Beiträge: 1 625
    • Profil anzeigen
Gespeichert
« Antwort #10 am: 30. November 2014, 01:19 »
Keine gesetzten unteren Bits heißt, dass es sich um einen Fehler mit Bezug auf die GDT handelt. Es wird also vermutlich versucht 0x400 in ein Segmentregister zu laden. (Meine vermutete Ursache ist wie immer ein beschädigter oder falscher Stack.)
Dieser Text wird unter jedem Beitrag angezeigt.

s137

  • Beiträge: 110
    • Profil anzeigen
Gespeichert
« Antwort #11 am: 30. November 2014, 01:22 »
darf ich fragen wie du von dem Fehlercode 0x2000 auf 0x400 kommst?

Jidder

  • Administrator
  • Beiträge: 1 625
    • Profil anzeigen
Gespeichert
« Antwort #12 am: 30. November 2014, 01:24 »
Hast Recht. Ist Selektor 0x2000. Hab da wohl durch 8 dividiert, weil ich an Indizies gedacht habe.
Dieser Text wird unter jedem Beitrag angezeigt.

s137

  • Beiträge: 110
    • Profil anzeigen
Gespeichert
« Antwort #13 am: 30. November 2014, 01:47 »
Ich glaube ich weiß jetzt, was das Problem war... Ich hatte keine Endlosschleife in meinem externen Programm und sobald das Programm endet gabs die Exception... mein Kernel kann quasi nicht aus einem Task zurück in meine init (die aufrufende Funktion) springen, und dort in die Endlosschleife gehen. Wie kann ich das beheben? Momentan habe ich halt nur Tasks die eine Endlosschleife haben, also halt nie enden.

Jidder

  • Administrator
  • Beiträge: 1 625
    • Profil anzeigen
Gespeichert
« Antwort #14 am: 30. November 2014, 02:04 »
Da musst du einen Exit-Syscall implementieren, den jedes Programm am Ende aufrufen muss.
Dieser Text wird unter jedem Beitrag angezeigt.

s137

  • Beiträge: 110
    • Profil anzeigen
Gespeichert
« Antwort #15 am: 30. November 2014, 02:14 »
ah ok, Danke :DD aber wie genau realisiere ich sowas? muss ich mir vorher die adresse irgendwie merken zu der ich zurückspringen will? oder geht das irgendwie einfacher?
« Letzte Änderung: 30. November 2014, 02:24 von s137 »

OsDevNewbie

  • Beiträge: 282
    • Profil anzeigen
    • YourOS Kernel
Gespeichert
« Antwort #16 am: 30. November 2014, 02:50 »
Das ist eigentlich ein Syscall, der einfach diesen Prozess löscht. Dann machst du noch einen Taskswitch oder wartest auf den nächsten Taskswitch.
Was bringt es dir zurück in den Kernel zu wechseln? Er wird nur noch über Syscall und Interrupts ausgeführt. Deshalb brauchst du auch keine Rücksprungaddresse.
Viele Grüsse
OsDevNewbie

Ein Computer ohne Betriebsystem ist nicht mehr wert als ein Haufen Schrott.
Ein Computer ist eine Maschine, die einem Lebewesen das kostbarste klaut, was sie selber nicht hat:
DIE ZEIT DES LEBENS

s137

  • Beiträge: 110
    • Profil anzeigen
Gespeichert
« Antwort #17 am: 30. November 2014, 13:49 »
Naja dass macht Sinnn.. aber wie lösche ich den Task aus einer verketteten Liste.. Ich weiß ja da nicht an welcher Stelle der Liste mein Task ist... Und ich kann ja aus dee Liste nicht einfach nen Eintrag rausnehmen, oder?

Svenska

  • Beiträge: 1 792
    • Profil anzeigen
Gespeichert
« Antwort #18 am: 30. November 2014, 19:23 »
Eine Liste musst du durchsuchen, um einen bestimmten Task zu finden. Wenn du ihn kennst - und bei einer einfach verketteten Liste musst du auch den Task davor kennen, bei einer doppelt verketteten Liste nicht - dann kannst du auch Einträge aus der Mitte entfernen.

s137

  • Beiträge: 110
    • Profil anzeigen
Gespeichert
« Antwort #19 am: 30. November 2014, 20:24 »
Ok danke, das heißt ich sollte meien Tasks erstmal eine eindeutige ID zuweisen...

 

Einloggen