Es ist der Kernel. Denken Sie daran, dass es sich bei der Tastatur um Hardware handelt und alles, was dort passiert, durch den Kernel geleitet wird. im Falle einer VT-Umschaltung behandelt sie das Ereignis vollständig selbst und gibt nichts an den Userspace weiter (ich glaube jedoch, dass es eine ioctl-bezogene Methode gibt, mit der Userspace-Programme über eine Umschaltung benachrichtigt werden können, die sie betrifft und sie möglicherweise beeinflusst, welches X zweifellos tut).
In den Kernel ist eine Keymap integriert . Dies kann während der Ausführung mit geändert loadkeys
und angezeigt werden mit dumpkeys
:
[...]
keycode 59 = F1 F13 Console_13 F25
alt keycode 59 = Console_1
control alt keycode 59 = Console_1
keycode 60 = F2 F14 Console_14 F26
alt keycode 60 = Console_2
control alt keycode 60 = Console_2
keycode 61 = F3 F15 Console_15 F27
alt keycode 61 = Console_3
control alt keycode 61 = Console_3
[...]
Die Kernel-Quelle enthält eine Standard-Keymap-Datei, die genau so aussieht. für 3.12.2 ist es src/drivers/tty/vt/defkeymap.map
. Sie werden auch feststellen, dass es eine entsprechende defkeymap.c- Datei gibt (diese kann mit erzeugt werden loadkeys --mktable
). Die Behandlung erfolgt in keyboard.c
(alle diese Dateien befinden sich in demselben Verzeichnis), von dem aus Folgendes set_console()
aufgerufen wirdvt.c
:
» grep set_console *.c
keyboard.c: set_console(last_console);
keyboard.c: set_console(i);
keyboard.c: set_console(i);
keyboard.c: set_console(value);
vt.c:int set_console(int nr)
vt_ioctl.c: set_console(arg);
Ich habe einige Treffer aus dieser Liste herausgeschnitten. Sie können die Funktionssignatur in der vorletzten Zeile sehen.
Das sind also die Dinge, die beim Umschalten eine Rolle spielen. Wenn Sie sich die Reihenfolge der Anrufe ansehen, kehren Sie irgendwann zu kbd_event()
in zurück keyboard.c
. Dies ist als Ereignishandler für das Modul registriert:
(3.12.2 drivers/tty/vt/keyboard.c
Zeile 1473)
MODULE_DEVICE_TABLE(input, kbd_ids);
static struct input_handler kbd_handler = {
.event = kbd_event, <--- function pointer HERE
.match = kbd_match,
.connect = kbd_connect,
.disconnect = kbd_disconnect,
.start = kbd_start,
.name = "kbd",
.id_table = kbd_ids,
};
int __init kbd_init(void)
{
[...]
error = input_register_handler(&kbd_handler);
Daher kbd_event()
sollte aufgerufen werden, wenn vom eigentlichen Hardwaretreiber etwas in die Luft sprudelt (wahrscheinlich etwas von drivers/hid/
oder drivers/input/
). Sie werden es jedoch nicht kbd_event
außerhalb dieser Datei sehen, da es über einen Funktionszeiger registriert wird.
Einige Ressourcen zur Überprüfung des Kernels
- Die Linux-Suche nach Querverweis-IDs ist ein großartiges Tool.
- Die Interactive Linux Kernel Map ist ein interessantes grafisches Frontend für das Querverweistool.
- Es gibt einige historische Archive der massiven Linux-Kernel-Mailingliste (LKML), die auf mindestens 1995 zurückgeht. einige von ihnen sind nicht gewartet und haben kaputte Suchfunktionen, aber die Gmane scheint sehr gut zu funktionieren. Die Leute haben viele Fragen auf der Mailingliste gestellt und es ist auch ein primäres Kommunikationsmittel zwischen den Entwicklern.
- Sie können Ihre eigenen
printk
Zeilen als einfaches Mittel zur Ablaufverfolgung in die Quelle einfügen (nicht alle Standard-C-Bibliotheken können im Kernel-Code verwendet werden, einschließlich printf von stdio). Printk-Inhalte landen im Syslog.
Wolfgang Mauerer hat ein großes Buch über den 2.6er Kernel geschrieben, Professional Linux Kernel Architecture , das einen Großteil der Quellen durchläuft. Greg Kroah-Hartman , einer der Hauptentwickler des letzten Jahrzehnts, hat auch einiges zu bieten.