Autor Thema: Tastaturtreiber  (Gelesen 18336 mal)

MNemo

  • Beiträge: 547
    • Profil anzeigen
Gespeichert
« Antwort #20 am: 28. March 2012, 18:02 »
.size = IDT_ENTRIES - 1,Hier gehört die Größe in Bytes (minus 1) hin, nicht die Anzahl der Einträge.

@taljeth:
scheinbar ist IDT_ENTRIES = 256
« Letzte Änderung: 28. March 2012, 18:07 von MNemo »
„Wichtig ist nicht, besser zu sein als alle anderen. Wichtig ist, besser zu sein als du gestern warst!“

micha

  • Beiträge: 141
    • Profil anzeigen
Gespeichert
« Antwort #21 am: 28. March 2012, 19:23 »
Richtig!
IDT_ENTRIES ist 256.
Wenn ich bei size IDT_ENTRIES * 8 nehme starte qemu bei jedem int. neu

MNemo

  • Beiträge: 547
    • Profil anzeigen
Gespeichert
« Antwort #22 am: 28. March 2012, 21:13 »
du hast nicht mit IDT_ENTRIES * 8 - 1 probiert, oder? Die minus 1 war schon richtig.
„Wichtig ist nicht, besser zu sein als alle anderen. Wichtig ist, besser zu sein als du gestern warst!“

micha

  • Beiträge: 141
    • Profil anzeigen
Gespeichert
« Antwort #23 am: 29. March 2012, 12:40 »
du hast nicht mit IDT_ENTRIES * 8 - 1 probiert, oder? Die minus 1 war schon richtig.
Na klar hab ich das!!!

micha

  • Beiträge: 141
    • Profil anzeigen
Gespeichert
« Antwort #24 am: 29. March 2012, 16:46 »
Jetzt nochmal damit das klar ist:
 1. Ich nehme .size = IDT_ENTRIES -1
   - wenn IDT_ENTRIES = 256 ist funktioniert es
   - wenn IDT_ENTRIES = irgendwas anderes ist, startet qemu neu
 
 2. Ich nehme .size = IDT_ENTRIES * 8 -1
   - Es funktioniert immer, wenn IDT_ENTRIES größer als die wirkliche Anzahl der interrupts ist
      sonst bleibt qemu schwarz

Trotz dem bleibt ein Interrupt der >= 0x20 ist nicht ohne GPF
« Letzte Änderung: 29. March 2012, 19:27 von micha »

Jidder

  • Administrator
  • Beiträge: 1 625
    • Profil anzeigen
Gespeichert
« Antwort #25 am: 30. March 2012, 13:35 »
Steht vielleicht was interessantes im qemu.log?
Dieser Text wird unter jedem Beitrag angezeigt.

micha

  • Beiträge: 141
    • Profil anzeigen
Gespeichert
« Antwort #26 am: 30. March 2012, 14:02 »
wenn ich IDT_ENTRIES auf 256 gestetzt hab und *8 nehme wird der int erst ohne GPF audgelöst, springt in den handler und dann kommt der GPF.

im qemu.log steht eimal:
     0: v=21 e=0000 i=0 cpl=0 IP=0008:00101835 pc=00101835 SP=0010:00105f70 EAX=000000edund dann:
check_exception old: 0xffffffff new 0xd
     1: v=0d e=0204 i=0 cpl=0 IP=0008:00100d66 pc=00100d66 SP=0010:00105f6a EAX=00000000

kevin

  • Administrator
  • Beiträge: 2 767
    • Profil anzeigen
Gespeichert
« Antwort #27 am: 30. March 2012, 14:34 »
Der nächste Schritt ist dann zu schauen, welcher Code an 0x100d66 steht, der löst den GPF aus. Relativ wahrscheinlich ist, dass es der Rücksprung vom Interrupthandler ist, der schiefgeht.
Thou shalt not follow the NULL pointer, for chaos and madness await thee at its end.

micha

  • Beiträge: 141
    • Profil anzeigen
Gespeichert
« Antwort #28 am: 30. March 2012, 15:35 »
genau der ist es! :-)
und was ist daran jetzt falsch, das ein GPF ausgelöst wird :?

kevin

  • Administrator
  • Beiträge: 2 767
    • Profil anzeigen
Gespeichert
« Antwort #29 am: 30. March 2012, 15:42 »
Schau dir die Werte auf dem Stack an. In der Regel hast du dort zu viel liegen, weil du vergessen hast, was abzuräumen. Es kann auch mal passieren, dass zu wenig drauf liegt, wenn du mit dem Stackpointer irgendwo durcheinandergekommen bist. Oder selten, der Stackpointer ist richtig und nur der Inhalt stimmt nicht mehr.
Thou shalt not follow the NULL pointer, for chaos and madness await thee at its end.

Jidder

  • Administrator
  • Beiträge: 1 625
    • Profil anzeigen
Gespeichert
« Antwort #30 am: 30. March 2012, 16:01 »
Der Stackpointer sieht verdächtig aus. Er sollte eigentlich ein Vielfaches von 4 sein. Vielleicht hast du irgendwo ein word gepusht oder gepoppt.
Dieser Text wird unter jedem Beitrag angezeigt.

micha

  • Beiträge: 141
    • Profil anzeigen
Gespeichert
« Antwort #31 am: 30. March 2012, 17:22 »
Ja, ESP ist nicht durch 4 teilbar. Ich hab nachgeschaut, ich hab immer versucht das `rechnen' mit dem Stackpointer zu vermeiden und bevor die komplette cpu gepopt wird nicht add $4, %esp sondern pop %eax verwendet. (%esp wegnehmen)
Beim wegnehmen der interruptnummer und dem Errorcode geht es ja nicht anders, da ist aber auch nichts (add $8, %esp).
Also ich hab' nicht mit irgendwelchen zahlen, die nicht durch 4 teibar sind, den Stackpointer verändert.
Wie könnten andere solche fehler entstehen?

Jidder

  • Administrator
  • Beiträge: 1 625
    • Profil anzeigen
Gespeichert
« Antwort #32 am: 30. March 2012, 17:29 »
Das kann zum Beispiel passieren, wenn push oder pop mit 16-bit Operanden verwendest. Also pushw/popw oder explizit ein 16-bit Register als Parameter übergeben. Allerdings ist das seltsam, dass der Stack trotzdem nicht ausgeglichen ist, außer du pusht etwas und nimmst es dann mit add/mov (oder anders) vom Stack, oder legst etwas mit sub/mov auf den Stack und poppst es.
« Letzte Änderung: 30. March 2012, 17:31 von Jidder »
Dieser Text wird unter jedem Beitrag angezeigt.

micha

  • Beiträge: 141
    • Profil anzeigen
Gespeichert
« Antwort #33 am: 30. March 2012, 17:37 »
Eigentlich habe ich kein pushw/popw verwendet...

Jidder

  • Administrator
  • Beiträge: 1 625
    • Profil anzeigen
Gespeichert
« Antwort #34 am: 30. March 2012, 19:09 »
Ich denke dann bleibt dir nichts anderes übrig, als mit dem Debugger da ranzugehen. Du könntest zum Beispiel einen Breakpoint an den Anfang des Interrupthandlers setzen und ab da schrittweise durchgehen.

Dazu musst du GDB und den QEMU Monitor nehmen. Single-Stepping in Assembler kannst du in GDB mit stepi machen. Die Register kannst du dir im QEMU-Monitor mit info registers anzeigen lassen.

Ein paar Links:
http://www.lowlevel.eu/wiki/Debugging#bochs_.2F_QEMU
http://sourceware.org/gdb/current/onlinedocs/gdb/Continuing-and-Stepping.html#Continuing-and-Stepping
http://qemu-buch.de/de/index.php/QEMU-KVM-Buch/_Anhang/_QEMU-Monitor

Alternative wäre den kompletten Code irgendwo hochzuladen. Dann kann ich mir (oder wer anders) sich das mal angucken, und ich muss nicht mehr rumraten.
« Letzte Änderung: 30. March 2012, 19:11 von Jidder »
Dieser Text wird unter jedem Beitrag angezeigt.

micha

  • Beiträge: 141
    • Profil anzeigen
Gespeichert
« Antwort #35 am: 31. March 2012, 15:26 »
Nun mit dem Debugger komme ich noch nicht wirklich zurecht.
Also ich mache bisjetzt folgendes:
gdb [dann kommt hier das file]
Bla.. BLa ...Bla
(gdb) target remote :1234

Zitat
[dann kommt hier das file]
soll ich da mein iso-image angeben?


und gleichzeitig:
qemu -S -cdrom image.iso
Und wie komme ich zu dem Qemu-Monitor?

Kann mir jemand den Debugger erklären? :?

Jidder

  • Administrator
  • Beiträge: 1 625
    • Profil anzeigen
Gespeichert
« Antwort #36 am: 31. March 2012, 16:05 »
Das Wichtige steht alles im Wiki-Artikel. GDB kriegt die Kernel-Binary als Parameter, und qemu musst du mit -s -S aufrufen. Du musst in gdb einen Breakpoint auf das Label mit dem Interrupthandler setzen mittels break intr_common_handler oder wie auch immer du das genannt hast. Dann startest du die Ausführung mit cont (oder c). Beim Interrupthandler angekommen, nutzt du stepi (oder si) um Schrittweise weiter zu gehen (oder du setzt halt mehr Breakpoints). Wenn du vorher einmal display/i $pc eingibst, zeigt dir GDB sogar immer den nächsten Assemblerbefehl an. In die Qemu-Konsole kommst du wenn du in Qemu Strg-Alt-2 drückst. Die Dokumentationen dazu hab ich ja bereits verlinkt.
« Letzte Änderung: 31. March 2012, 16:07 von Jidder »
Dieser Text wird unter jedem Beitrag angezeigt.

micha

  • Beiträge: 141
    • Profil anzeigen
Gespeichert
« Antwort #37 am: 01. April 2012, 11:12 »
Ich kann jetzt mit dem Debugger arbeiten, ich komme auch an den Qemu-Monitor, doch dann ist meine Emulation verschwunden und die Register und der ganze andere kram passt auch nicht auf das kleine 80x25 "kästchen".
Also hab ich breakpoints (ohne Debugger) mit asm("int $3"); gesetzt und mir im qemu-log die Register angesehen:
Vor dem interruptaufruf war ESP ok. Nachher irgendwie falsch (kein vielfaches von vier). Aber mein Handler sieht nur so aus:
.extern keyboard_irq_handler

...

.global int_handler0x21
int_handler0x21:
    call keyboard_irq_handler
    iret

...
...

und wers wissen will..
void keyboard_irq_handler(void){
    printf("Taste gedrueckt!\n");
}

Ich mach nichts mit dem Stack.
könnte möglicherweise der Timerinterrupt dazwischen funken und der Stack verrutscht?

MNemo

  • Beiträge: 547
    • Profil anzeigen
Gespeichert
« Antwort #38 am: 01. April 2012, 11:42 »
Das dir eine C-Funktion ESP verschiebt ist eher unwahrscheinlich. Ich weiß nicht genau wo bei dir vorher und nachher ist. Also direkt nach dem int_handler0x21 label und direkt vor dem iret müssen ESP, (und alle anderen Register auch) gleich sein. Es sieht so aus also würde es hier nicht an esp liegen (darum kümmert sich gcc) sondern an den anderen Registern die in keyboard_irq_handler verändert werden.

Edit: Eigentlich sollten die Fehler wegen falschen Register-Werten erst später auftreten und nicht schon beim iret. Wenn dein printf groben Unfug baut wäre es auch denkbar des es die Rücksprungadresse für den iret manipuliert. (mit var_args hättest du da zumindest die entsprechenden Pointer zu in der Hand)
« Letzte Änderung: 01. April 2012, 11:49 von MNemo »
„Wichtig ist nicht, besser zu sein als alle anderen. Wichtig ist, besser zu sein als du gestern warst!“

micha

  • Beiträge: 141
    • Profil anzeigen
Gespeichert
« Antwort #39 am: 01. April 2012, 14:02 »
Mein Printf (sprintf) habe ich ja selber implementiert, aber komplett in C. und ich glabe nicht, dass da was schief läuft. die cpu wird doch in einer C-Funktion gesichert.

 

Einloggen