Autor Thema: Tastaturtreiber  (Gelesen 7998 mal)

sfan

  • Beiträge: 94
    • Profil anzeigen
Gespeichert
« am: 04. January 2011, 10:03 »
Hi,

ich habe zwei Fragen:

1.Läuft dieser Tastatureiber auch im Protected Mode?
int key_asciicode() {
  int al;
  asm("mov $0x0, %%ax;int $0x16;mov %%al, %0" : "=r" (al) : );
  return al;
}
2.Wenn ja da steckt ein Fehler drin und
  die Meldung von gcc :
  "Error: Suffix or Operands invalid for 'mov' "
  hilft mir auch nicht weiter.
  Wenn es nicht im Protected Mode läuft:
  Wie bekomme ich das anders hin?

DerHartmut

  • Beiträge: 236
    • Profil anzeigen
    • Mein Blog
Gespeichert
« Antwort #1 am: 04. January 2011, 10:30 »
Hi sfan und Willkommen im Forum (im Wiki bist du ja schon recht aktiv ;-)).

Der Code funktioniert nicht im PM, da du einen BIOS-Interrupt aufrufst. Diese Interrupts stehen dir im PM nicht zur Verfügung (bzw. nicht so ohne weiteres).

Für Hilfe zu Inline-Assembler sei dir erst einmal dieses kleine Tutorial ans Herz gelegt: Assembler 101.

Speziell für Inline-Asssembler auch noch dieser Artikel: Inline-Assembler mit GCC.

Wie du einen Tastaturtreiber entwickelst? Nun, du programmierst dir einen IRQ-Handler, welcher die von der Tastatur ausgelösten Interrupts abfängt und die empfangenen Daten in Form von Key-/Scancodes weiter verarbeitest.

Für die Themen sei dir Interrupts und Keyboard-Controller ans Herz gelegt.
$_="krJhruaesrltre c a cnp,ohet";$_.=$1,print$2while s/(..)(.)//;
Nutze die Macht, nutze Perl ;-)

sfan

  • Beiträge: 94
    • Profil anzeigen
Gespeichert
« Antwort #2 am: 04. January 2011, 10:53 »
Hi sfan und Willkommen im Forum (im Wiki bist du ja schon recht aktiv ;-)).
Danke!
Für Hilfe zu Inline-Assembler sei dir erst einmal dieses kleine Tutorial ans Herz gelegt: Assembler 101.

Speziell für Inline-Asssembler auch noch dieser Artikel: Inline-Assembler mit GCC.

Wie du einen Tastaturtreiber entwickelst? Nun, du programmierst dir einen IRQ-Handler, welcher die von der Tastatur ausgelösten Interrupts abfängt und die empfangenen Daten in Form von Key-/Scancodes weiter verarbeitest.

Für die Themen sei dir Interrupts und Keyboard-Controller ans Herz gelegt.
Werde mich damit befassen!
Der Code funktioniert nicht im PM, da du einen BIOS-Interrupt aufrufst. Diese Interrupts stehen dir im PM nicht zur Verfügung (bzw. nicht so ohne weiteres).
Theoretisch, wie könnte ich Interrupts im PM nutzen?
Wäre für viele Dinge hilfreich!
« Letzte Änderung: 04. January 2011, 11:03 von sfan »

kevin

  • Administrator
  • Beiträge: 2 767
    • Profil anzeigen
Gespeichert
« Antwort #3 am: 04. January 2011, 11:17 »
asm("mov $0x0, %%ax;int $0x16;mov %%al, %0" : "=r" (al) : );  "Error: Suffix or Operands invalid for 'mov' "
Das Problem ist, dass die Operandengrößen nicht passen. al ist ein int, deswegen wird %0 zu z.B. edx, nicht zu dl. Du kannst entweder aus al einen char machen oder %b0 verwenden, wodurch nur das niederwertigste Byte benutzt wird.

In Wirklichkeit willst du das ganze aber sowieso ganz anders schreiben, du kannst nämlich dem Compiler gleich sagen, dass er eax benutzen soll:
asm("int $0x16" : "=a" (al) : "0" (0x0));
Die BIOS-Interrupts zu benutzen ist nicht so furchtbar hilfreich. Das Problem dabei ist, dass das BIOS die Interrupthandler in 16-Bit-Real-Mode-Code implementiert. Dir bleibt also nur, entweder in den Real Mode zurückzuschalten oder den BIOS-Code im VM86 laufen zu lassen, wenn die du BIOS-Interrupts benutzen willst. In der Regel macht man das nur, um in die VESA-Grafikmodi schalten zu können und lässt das BIOS ansonsten in Ruhe.
« Letzte Änderung: 04. January 2011, 11:19 von taljeth »
Thou shalt not follow the NULL pointer, for chaos and madness await thee at its end.

sfan

  • Beiträge: 94
    • Profil anzeigen
Gespeichert
« Antwort #4 am: 04. January 2011, 11:23 »
asm("mov $0x0, %%ax;int $0x16;mov %%al, %0" : "=r" (al) : );  "Error: Suffix or Operands invalid for 'mov' "
Das Problem ist, dass die Operandengrößen nicht passen. al ist ein int, deswegen wird %0 zu z.B. edx, nicht zu dl. Du kannst entweder aus al einen char machen oder %b0 verwenden, wodurch nur das niederwertigste Byte benutzt wird.

In Wirklichkeit willst du das ganze aber sowieso ganz anders schreiben, du kannst nämlich dem Compiler gleich sagen, dass er eax benutzen soll:
asm("int $0x16" : "=a" (al) : "0" (0x0));
Die BIOS-Interrupts zu benutzen ist nicht so furchtbar hilfreich. Das Problem dabei ist, dass das BIOS die Interrupthandler in 16-Bit-Real-Mode-Code implementiert. Dir bleibt also nur, entweder in den Real Mode zurückzuschalten oder den BIOS-Code im VM86 laufen zu lassen, wenn die du BIOS-Interrupts benutzen willst. In der Regel macht man das nur, um in die VESA-Grafikmodi schalten zu können und lässt das BIOS ansonsten in Ruhe.

Genau daran habe ich gedacht die Interrupts für das irgendwann für Grafikmodus-Schalten zu benutzen.

PNoob

  • Beiträge: 106
    • Profil anzeigen
    • Mein Blog
Gespeichert
« Antwort #5 am: 04. January 2011, 13:08 »
Moin

Ein weitere Möglichkeit um 16 Bit Code auszuführen ist en Code zu emulieren. soll heißen du ließt den Code vom BIOS ein, disassembelst ihn und führst ihn auf einer Emulierten CPU wieder aus. Ob dies nun schwerer oder leichter ist, ist schlecht zu sagen. Sie ist einfach anders. Ich selber versuche diese gerade einzubauen. jedoch sind die Sprünge nicht so ganz ohne.

PNoob

DerHartmut

  • Beiträge: 236
    • Profil anzeigen
    • Mein Blog
Gespeichert
« Antwort #6 am: 04. January 2011, 13:09 »
Den Code vom BIOS einlesen, diassemblieren und auf einer emulierten CPU ausführen...

Sorry, aber wovon redest du?
$_="krJhruaesrltre c a cnp,ohet";$_.=$1,print$2while s/(..)(.)//;
Nutze die Macht, nutze Perl ;-)

PNoob

  • Beiträge: 106
    • Profil anzeigen
    • Mein Blog
Gespeichert
« Antwort #7 am: 04. January 2011, 13:23 »
Moin

@DerHartmut: Also du ließt die OPcodes des BIOS Stück für Stück ein, disassembelst die in deinem Kernel/VM86-Emulator und führst den disassembelten Befehl auf einer emulierten CPU aus. nur Speicherzugriffe und IO Zugriffe musst du an den Speicher/CPU weitergeben. und du musst halt den jmps und calls folgen ansonsten disassembelst du irgendwann irgendwelchen Müll.
So versuche ich momentan APM zu implementieren. Will jedoch noch nicht ganz. Irgendwie hab ich da mit 2 Befehlen noch Probleme.

PNoob

Svenska

  • Beiträge: 1 792
    • Profil anzeigen
Gespeichert
« Antwort #8 am: 04. January 2011, 13:30 »
Also ein vollwertiger Disassembler im Kernel. Warum nicht gleich Bochs oder Qemu in den Kernel stecken, um einen Tastaturtreiber zu erzeugen? Ehrlich, der Vorschlag ist Blödsinn.
Theoretisch sind BIOS-Interrupts übrigens nicht auf den Real Mode beschränkt. Praktisch allerdings schon.

edit: Nennen wir es nicht blödsinnig, sondern mit mehr als drei Raketenwerfern gleichzeitig auf einen kleinen Spatz.
« Letzte Änderung: 04. January 2011, 13:32 von Svenska »

DerHartmut

  • Beiträge: 236
    • Profil anzeigen
    • Mein Blog
Gespeichert
« Antwort #9 am: 04. January 2011, 13:49 »
Klingt reichlich kompliziert, junger Padawan. Nutzen die Macht des VM86 du musst.
$_="krJhruaesrltre c a cnp,ohet";$_.=$1,print$2while s/(..)(.)//;
Nutze die Macht, nutze Perl ;-)

kevin

  • Administrator
  • Beiträge: 2 767
    • Profil anzeigen
Gespeichert
« Antwort #10 am: 04. January 2011, 13:59 »
Außer du bist im Long Mode. Da bleibt außer dem Emulator nichts praktikables (wobei man da anstatt sich selber dran abzuarbeiten einfach x86emu hernehmen kann).
Thou shalt not follow the NULL pointer, for chaos and madness await thee at its end.

PNoob

  • Beiträge: 106
    • Profil anzeigen
    • Mein Blog
Gespeichert
« Antwort #11 am: 04. January 2011, 16:32 »
Ich kopiere nicht mehr irgendwelchen Kram zusammen. und das argument Longmode ist auch der Punkt weshalb ich VM86 gar nicht nutze. es ist im longMode nicht verfügbar
Und so schwer ist es nicht. sind halt ein paar knifflige Befehle dabei aber die Intelmanuals helfen einem da schon weiter.

PNoob

 

Einloggen