Autor Thema: [Anfänger] Tastatur Implementierungs Tipps / Hilfestellung  (Gelesen 4488 mal)

moritz3101

  • Beiträge: 4
    • Profil anzeigen
Gespeichert
Hey,

bin neu hier und stelle mich erstmal kurz vor, ich heiße Moritz bin 18 Jahre und komme aus der Nähe von Frankfurt.
Seit ich 13 bin hab ich was mit Programmierung am Hut (mehr oder weniger) und seit etwas mehr als einem Monat studier ich Informatik an der TU Darmstadt. Da ich sowieso mehr so der Hardware als der Software Mensch bin kam ich gestern drauf ob man sich nicht während der Unizeit sein eigens kleines Os zusammenbasteln kann.

Daher habe ich das Tutorial hier entdeckt und mich einmal drangesetzt. Soweit klappt auch alles ganz gut. Bin jetzt mit Tutorial 5 fertig und GDT und IDT
funktionieren einwandfrei. Bevor ich nun mit Multitasking weiter mache wollte ich mir einen Tastaturtreiber schreiben (steht ja dabei das man das jetzt schon kann). Hab mir also mal das Kapitel zu KBC angeschaut und blicke nicht ganz durch ... :(

Also wenn ich das richtig verstanden habe brauche ich die Ports 0x60 und 0x64  zum empfangen und senden.
inb und outb machen was sie sollen (Y)

jetzt steht im Beispielcode aber diese Zeile:
// IRQ-Handler fuer Tastatur-IRQ(1) registrieren
    register_intr_handler(IRQ_BASE + 1, &irq_handler);

Und mir ist nicht ganz klar wie ich diese umsetzen soll... also IRQ_BASE is ein int und wahrscheinlich 32 wenn ich das richtig interpretiere.
ab 32 fangen die Hardware Interupts an und IRQ_BASE + 1 sollte der von der Tastatur sein also 33. Soweit richtig oder ?
Dann die Referenz auf irq_handler ist ja einfach die Funktion die unten drunter erklärt ist.
Was macht jetzt aber register_intr_handler ?
Also soweit ich das verstehe müsste die Funktion ja den intr_stub 33 mit der Funktion irq_handler verknüpfen oder ?
Also muss sozusagen in dem Handler der in Tutorial 5 erstellt wurde für 0x21 die Funktion irq handler gesetzt werden oder sehe ich das falsch?

Wenn mir jemand meinen Gedankengang vielleicht korrigieren kann wäre das sehr cool :)

MfG
Moritz

Jidder

  • Administrator
  • Beiträge: 1 625
    • Profil anzeigen
Gespeichert
« Antwort #1 am: 10. November 2014, 00:47 »
Hi und willkommen an Board!

Und mir ist nicht ganz klar wie ich diese umsetzen soll... also IRQ_BASE is ein int und wahrscheinlich 32 wenn ich das richtig interpretiere.
ab 32 fangen die Hardware Interupts an und IRQ_BASE + 1 sollte der von der Tastatur sein also 33. Soweit richtig oder ?
Dann die Referenz auf irq_handler ist ja einfach die Funktion die unten drunter erklärt ist.
Kann ich alles bestätigen.

Was macht jetzt aber register_intr_handler ?
Also soweit ich das verstehe müsste die Funktion ja den intr_stub 33 mit der Funktion irq_handler verknüpfen oder ?
Also muss sozusagen in dem Handler der in Tutorial 5 erstellt wurde für 0x21 die Funktion irq handler gesetzt werden oder sehe ich das falsch?
So ist es. register_intr_handler kann beispielsweise den übergebenen Zeiger irq_handler in ein Array1) an Index 0x21 eintragen. Der Interrupt-Handler (handle_interrupt) könnte dann bei einem Interrupt in dieses Array schauen (an Index cpu->intr), und wenn dort etwas eingetragen ist, diesen Zeiger aufrufen. Die Syntax für sowas ist nicht ganz einfach, aber wenn du nach "array of function pointers" oder so googelst, solltest du da etwas bekommen. Ansonsten einfach hier nachfragen.

Die Signatur von register_intr_handler sollte sowas wie void register_intr_handler(int int_no, void (*handler)(uint8_t)) sein.

1)Das Array müsste dann theoretisch 256 Elemente groß sein, weil es 256 Interrupts gibt, aber du kannst dir ja auch mal überlegen, welche Interrupts überhaupt alles registeriert werden müssen, und ob es nicht auch mit weniger geht. register_intr_handler und der Interrupt-Handler müssten dann entsprechend cleverer sein.
« Letzte Änderung: 10. November 2014, 00:51 von Jidder »
Dieser Text wird unter jedem Beitrag angezeigt.

Svenska

  • Beiträge: 1 792
    • Profil anzeigen
Gespeichert
« Antwort #2 am: 10. November 2014, 01:24 »
Was macht jetzt aber register_intr_handler ?
Also soweit ich das verstehe müsste die Funktion ja den intr_stub 33 mit der Funktion irq_handler verknüpfen oder ?
Also muss sozusagen in dem Handler der in Tutorial 5 erstellt wurde für 0x21 die Funktion irq handler gesetzt werden oder sehe ich das falsch?
Die Funktion register_intr_handler() verklebt in deinem OS den Interrupt 33 mit einer bestimmten Funktion. Für den Anfang reicht es, wenn du einfach den Funktionsaufruf in dein handle_interrupt() einträgst, aber später möchtest du eher eine dynamische Lösung, wie z.B. das von Jidder beschriebene Array, haben.

Achso, und Herzlich Willkommen auch von mir!

kevin

  • Administrator
  • Beiträge: 2 767
    • Profil anzeigen
Gespeichert
« Antwort #3 am: 10. November 2014, 09:55 »
Hallo Moritz, willkommen im Forum! :)

Jidder und Svenska haben dir ja schon bestätigt, dass du auf dem richtigen Weg bist, das brauche ich also nicht zu wiederholen. Ich möchte nur noch kurz anmerken, dass es natürlich deine eigene Entscheidung ist, ob es eine Funktion wie register_intr_handler() überhaupt gibt und wie sie funktioniert. Du musst nur dafür sorgen, dass der Tastatur-IRQ-Handler irgendwie aufgerufen wird, und das kann je nachdem, was du vorhast, durchaus auch statisch sein.
Thou shalt not follow the NULL pointer, for chaos and madness await thee at its end.

moritz3101

  • Beiträge: 4
    • Profil anzeigen
Gespeichert
« Antwort #4 am: 10. November 2014, 14:52 »
okay danke :)

hilf doch manchmal sich ins Bett zuhauen und drüber nachzudenken :D

@Kevin
also ich weiß nicht ob ich mir das vielleicht falsch vorstelle, aber ich bin immer für Flexibilität von daher finde ich das ganze dynamisch schon ein wenig schöner, klar ist das ein bisschen mehr Code aufwand aber im späteren hat man dann immer noch die Möglichkeit was anderes zu registrieren.

Bis jetzt bekomm ich bei der Ausgabe nur %c
liegt wahrscheinlich daran das noch kein c in meiner Kernelprint Funktion implementiert ist :D :D :D

kevin

  • Administrator
  • Beiträge: 2 767
    • Profil anzeigen
Gespeichert
« Antwort #5 am: 10. November 2014, 15:04 »
Dem widerspreche ich nicht, týndur hat auch ein Array (von Listen, die mehrere Handler haben können, wenn ich mich nicht täusche).

Mein eigentliches Ziel war nur, sicherzustellen, dass du nicht denkst, was die Tutorials beschreiben, ist immer der einzige Weg. In der Regel sind es einfach nur Beispiele für einen gangbaren Weg. Die Tutorials selber sagen das eigentlich auch, aber manche denken immer, man müsste sich sklavisch daran halten - nur wird dann das eigene OS nicht besonders individuell.

Bei dir habe ich eigentlich ein gutes Gefühl, dass du das sowieso so verstanden hast, aber es mal anzumerken kann ja nicht schaden. ;)
Thou shalt not follow the NULL pointer, for chaos and madness await thee at its end.

moritz3101

  • Beiträge: 4
    • Profil anzeigen
Gespeichert
« Antwort #6 am: 10. November 2014, 17:20 »
Okay alles klar  :-D

ich wollte es nur so hinstellen weil ich eigentlich mehr der Befürworter des flexibelen bin  :-)

Deswegen auch nochmal eine Frage :D

also die Probleme hab ich jetzt erstmal beseitigt :D der Fehler mit der Ausgabe lag echt daran das ich einfach den Fall %c vergessen hatte  :| naja jetzt geht es ja  :-D
so wenn ich jetzt eine Taste drücke wird ein Interrupt ausgelöst und ein Zeichen, wenn ich die Taste länger gedrückt halte mehr Zeichen und wenn ich loslasse auch ein Zeichen, wird gesendet :)
Soweit ist das ganze klar :)
Dafür wird der über inb(0x60) empfangene Sendcode über das sc_to_ky Array in ein Keycode verwandelt.
So jetzt hab ich ja aber viele verschiedene Tastaturlayouts, das heißt ich muss ja eigentlich sc_to_ky Variabel definieren, dass man auch Englische Tastaturen usw verwenden kann oder ?
Bin mir darüber noch nicht so ganz im klaren deswegen die vielleicht etwas blöde Fragen

kevin

  • Administrator
  • Beiträge: 2 767
    • Profil anzeigen
Gespeichert
« Antwort #7 am: 10. November 2014, 18:24 »
Keycodes sind in der Regel noch nicht abhängig von der Tastaturbelegung, sondern erst die Umwandlung in ASCII. Das ändert aber natürlich nichts daran, dass du an irgendeiner Stelle unterschiedliche Arrays für jede Belegung brauchst.
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 #8 am: 10. November 2014, 23:44 »
Also beispielsweise ein Array für die Umwandlung Scancode -> Keycode und für jedes Tastaturlayout jeweils ein Array für die Umwandlung von Keycode -> Zeichen.

Oder direkt jeweils ein Array Scancode -> Zeichen für jedes Tastaturlayout.

Was bei dem Artikel KBC zu beachten ist, ist dass das letzte kprintf("%c", keycode); fälschlicherweise suggeriert, dass der Keycode tatsächlich schon das Zeichen ist. In týndur, wo der Code herkommt, ist das nur eine abstrakte Zahl, die anschließend erst noch in ein dem Tastaturlayout entsprechendes Zeichen gewandelt werden muss. Ein "%c" zur Ausgabe von keycode würde also nur Murks ausgeben.
« Letzte Änderung: 10. November 2014, 23:48 von Jidder »
Dieser Text wird unter jedem Beitrag angezeigt.

moritz3101

  • Beiträge: 4
    • Profil anzeigen
Gespeichert
« Antwort #9 am: 11. November 2014, 00:41 »
joa das habe ich mittlerweile auch verstanden   :-D

ich hab mir mal Linux keymaps angeschaut und da wird ja einfach in einer Datei das Layout per #define KEY_XY Keycode erstellt :D
bevor ich die Tastatur aber 100% implementiere mach ich erstmal weiter im Tutorial ^_^

 

Einloggen