Low-Level Patch des OS X USB Tastaturtreibers

english version

Die Spielereien mit den Tastaturlayouts und auch die Hacks mit uControl haben mich noch immer nicht ganz glücklich gemacht.

Mac OS X arbeitet auf diesen Ebenen intern mit den ADB Tastaturcodes und die erlauben z.B. schon keine Unterscheidung zwischen linkern und rechten shift, command bzw. alt Tasten mehr. Und das, obwohl die meisten Tastaturen sehr wohl unterschiedliche Codes für diese Tasten aussenden.

Also begab ich mich weiter auf die Suche. Und siehe da: ich wurde auf den OpenDarwin Seiten fündig. Dort stellt Apple grosse Teile des Quelltextes zu Mac OS X zur Verfügung. Insbesondere auch den AppleUSBKeyboard Treiber. Und hier hab' ich dann tatsächlich eine hart codierte Tabelle gefunden, in der für jeden USB Tastencode ein Feld ist, das den zu verwendenden ADB Tastencode enthält.

Der fertige Treiber wird von Apple unter

/System/Library/Extensions/IOUSBFamily.kext/Contents/PlugIns/AppleUSBKeyboard.kext/Contents/MacOS/AppleUSBKeyboard
installiert und siehe da: die Umsetzungstabelle findet sich (fast) 1:1 im binären Treiber wieder (fast heisst: Apple hat anscheinend nicht alles an opendarwin weitergegeben. Oberhalb des Codes 107 hat der OS X Treiber noch ein paar Einträge, die die opendarwin Version nicht hat - vermutlich für asiatische Tastaturen).

Und noch besser: wenn man in dieser Tabelle im System Treiber hart neue Werte einpatcht, kriegt man - nicht etwa eine Kernel Panic (wenn man's richtig macht zumindest) - sondern das System arbeitet so, als hätte man tatsächlich die Tastatur neu verdrahtet!

Also hab' ich mich noch 'nen Tag hingesetzt und ein kleines perl script gebastelt, dass diese Patcherei (etwas) komfortabler gestaltet: usbkbpatch.pl wird mit root rechten aus dem Terminal aufgerufen. Beim ersten Aufruf (oder nach einem System-Update) legt es eine Kopie des original Treibers an. Dann trägt es die Patch Werte von der Kommandozeile in den USB Treiber ein und lädt ihn anschliessend neu. Als Patch Werte werden jeweils Zahlen Paare angegeben (wahlweise dezimal oder in hex mit dem präfix 0x), von denen die erste den USB Tastaturcode definiert, der verändert werden soll, und die zweite den neuen ADB Tastatur Code..

Hier sind ein paar interessante USB codes:
0xe0control (strg) links
0xe1shift links
0xe2option/alt links
0xe3comand links
0xe4control (strg) rechts
0xe5shift rechts
0xe6option/alt rechts
0xe7comand rechts
0x65Windows Kontext-Menü (auf PC USB Tastaturen)
0x64^ (das Dach - auf wintel-usb mit < (kleiner) vertauscht)
0x35< (kleiner - auf wintel-usb mit ^ (dach) vertauscht)
0x53die insert-Taste - auf imac Tastaturen sucht meine Hand da immer delete

Und hier ein paar dazu passende ADB codes:
0x3bcontrol
0x38shift
0x3aoption/alt
0x37command
0x34enter (im ggs. zu return...)
0x32< (kleiner)
0x0a^ (Dach)
0x75delete


Also:

Falls etwas schiefgegangen ist...

(kann eigentlich ja gar nicht sein - oder?)

Der original-Treiber wurde in
System/Library/Extensions/IOUSBFamily.kext/Contents/PlugIns/AppleUSBKeyboard.kext/Contents/MacOS/
mit dem uname namen der aktuellen Betriebssystem Version (z.B. Darwin_6.6) gespeichert. Um den Originaltreiber wieder zu aktivieren führt man das folgende (als root) aus:
 kextunload /System/Library/Extensions/IOUSBFamily.kext/Contents/PlugIns/AppleUSBKeyboard.kext
 cd /System/Library/Extensions/IOUSBFamily.kext/Contents/PlugIns/AppleUSBKeyboard.kext/Contents/MacOS/
 ls
 cp AppleUSBKeyboard.Darwin_6.6 AppleUSBKeyboard 
 kextload /System/Library/Extensions/IOUSBFamily.kext/Contents/PlugIns/AppleUSBKeyboard.kext

Dieser Patch greift recht brutal in das Innere eines Mac OS X Treibers ein und man kann sich auf diese Art natürlich das System ziemlich unbedienbar machen (z.B. indem man die Return- bzw. enter Taste mit irgend einem anderen USB Keycode belegt und dann nicht mehr die nötigen Kommandos zum Wiederherstellen des Ursprungszustandes eingeben kann...)

Falls das Terminal Fenster mit root access noch offen ist, kann man versuchen, das folgende code-schnipsel per copy & paste auszuführen:
 kextunload /System/Library/Extensions/IOUSBFamily.kext/Contents/PlugIns/AppleUSBKeyboard.kext
 cd /System/Library/Extensions/IOUSBFamily.kext/Contents/PlugIns/AppleUSBKeyboard.kext/Contents/MacOS/
 cp AppleUSBKeyboard.Darwin_* AppleUSBKeyboard 
 kextload /System/Library/Extensions/IOUSBFamily.kext/Contents/PlugIns/AppleUSBKeyboard.kext
Das klappt allerdings nur, wenn nur eine solche Backup-Datei (mit "Darwin" im Namen) existiert. Ansonsten hilft nur der Neustart von CD oder einem anderen Medium um die original-Treiberdatei wieder herzustellen...

An meinem iBook war ich natürlich recht sicher vor solchen Problemen: die eingebaute Tastatur arbeitet sowiso mit ADB codes - Ich konnte mir also nur die zusätzliche externe USB Tastatur durcheinander bringen...

Update 19. November 2003:
Anpassung an Panther: das betroffene Kernel Modul ist jetzt IOHIDFamily.kext und die Tabelle hat sich auch ein wenig geändert. Leider braucht es jetzt einen neustart um die geänderte Tabelle zu aktivieren, da IOHIDFamily kein entladbares Modul ist.


 up

 Autor:
Heiko Hellweg, geändert: November 2003