Cosa succede quando si preme Ctrl + Alt + F <Num>?


38

Sto cercando una spiegazione di ciò che accade in Linux quando si preme questa combinazione di tasti per cambiare il terminale corrente. In particolare, quale componente software intercetta questa combinazione di tasti e cambia il terminale? È il kernel? Se è il kernel, potresti fornire l'ubicazione del file sorgente che lo gestisce?

Modifica: voglio capire come funziona in un ambiente grafico (X11) e basato su testo.


1
Per chiarire, stai premendo questi tasti mentre sei in X11 (ovvero una sessione grafica) o sulla console di testo? La risposta è diversa
derobert,

Risposte:


36

È il kernel. Tieni presente che la tastiera è hardware e tutto ciò che accade lì passa attraverso il kernel; nel caso di commutazione VT, gestisce l'evento completamente da solo e non passa nulla allo spazio utente (tuttavia, credo che ci sia un mezzo correlato a ioctl mediante il quale i programmi userspace possono essere avvisati di un interruttore che li coinvolge e forse influenzarlo, che X senza dubbio fa).

Il kernel ha una keymap integrata in esso; questo può essere modificato durante l'esecuzione loadkeyse visualizzato con 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
[...]   

Il sorgente del kernel contiene un file keymap predefinito che assomiglia esattamente a questo; per 3.12.2 è src/drivers/tty/vt/defkeymap.map. Noterai anche che esiste un file defkeymap.c corrispondente (questo può essere generato con loadkeys --mktable). La gestione è in keyboard.c(tutti questi file sono nella stessa directory) che chiama set_console()davt.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);

Ho modificato alcuni hit da quell'elenco; puoi vedere la firma della funzione sull'ultima riga.

Quindi queste sono le cose coinvolte nel passaggio. Se guardate la sequenza di chiamate, finalmente si torna a kbd_event()in keyboard.c. Questo è registrato come un gestore eventi per il modulo:

(3.12.2 drivers/tty/vt/keyboard.clinea 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);           

Quindi, kbd_event()dovrebbe essere chiamato quando qualcosa bolle dal vero driver hardware (probabilmente qualcosa da drivers/hid/o drivers/input/). Tuttavia, non lo vedrai indicato come kbd_eventesterno a quel file, poiché è registrato tramite un puntatore a funzione.

Alcune risorse per il controllo del kernel

  • La Ricerca identificatore di riferimenti incrociati di Linux è un ottimo strumento.
  • L' Interactive Linux Kernel Map è un interessante front end grafico per lo strumento di riferimento croce.
  • Ci sono alcuni archivi storici della massiccia Linux Kernel Mailing List (LKML), che risale almeno al 1995; alcuni di essi non sono mantenuti e hanno funzionalità di ricerca rotte, ma quello di Gmane sembra funzionare molto bene. Le persone hanno posto molte domande sulla mailing list ed è anche uno dei principali mezzi di comunicazione tra gli sviluppatori.
  • Puoi iniettare le tue printklinee nel sorgente come un semplice mezzo per tracciare (non tutto il C lib standard può essere usato nel codice del kernel, incluso printf da stdio). roba di printk finisce in syslog.

Wolfgang Mauerer ha scritto un grande libro sul kernel 2.6, Professional Linux Kernel Architecture , che analizza gran parte dei sorgenti. Greg Kroah-Hartman , uno dei principali sviluppatori dell'ultimo decennio, ha anche molte cose in giro.


1
Grazie, questo è esattamente quello che stavo cercando. Puoi approfondire cosa succede prima nella catena? Come viene chiamato il codice in keyboard.c quando si preme Ctrl + Alt + F1? keyboard.c non è il vero "driver della tastiera", vero?
user31765

1
No, non la penso così. Fa tutto parte del driver tty, per il quale keyboard.csarebbe un gestore di eventi; lo stesso "driver della tastiera" sarebbe di livello inferiore - ce ne sono un sacco drivers/input/keyboard/per roba non USB. La roba USB è standardizzata quindi ce ne sarebbe solo una (probabilmente coinvolgente drivers/hid/usbhid/usbkbd.c). Immagino che il driver della tastiera sia per la produzione di uno scancode che può essere passato a vt / keyboard.c (vedi getkeycode () nella parte superiore). Documentation/input/input.txtha alcuni suggerimenti (meravigliosamente antichi, lol).
Riccioli d'oro

PS. Molti degli sviluppatori del kernel sono nella lista di posta del kernel linux (LKML) che è aperta al pubblico, e se ti dispiace i tuoi P&Q ecc. ( Tux.org/lkml ) vale la pena informarti lì ... assicurati solo di imposta subito una cartella, c'è molta posta in gioco.
Riccioli d'oro

Esaminando il codice più da vicino, ci sono solo tre funzioni non obsolete in keyboard.c che chiamano set_console: fn_lastcons (), fn_dec_console () e fn_inc_console (). Uno per andare all'ultima console e uno per andare a destra o a sinistra. Quindi ancora non capisco come viene chiamato set_console () quando premiamo Ctrl + Alt + F <num>. Presumo che dobbiamo passare <num> come parametro a set_console () da qualche parte. Vedo che set_console () cresce anche in vt_ioctl.c, ma non è solo per ioctl dallo spazio utente, ad esempio da chvt? Ci sono ancora alcuni buchi nella mia comprensione.
user31765,

1
Ci sono altre cose potenzialmente correlate nei driver / nascosti. Notare anche 'console_callback ()' in vt.c, che può eseguire lo switch ed è registrato nella parte superiore tramite DECLARE_WORK. Questo si riferisce allo scheduler: lxr.free-electrons.com/ident?i=DECLARE_WORK (quello strumento di riferimento incrociato può essere alimentato da makelinux.net/kernel_map che potresti trovare interessante); Suppongo che renda tale funzione un "ciclo principale" per la vt. Ovviamente il link mancante qui è esattamente come gli eventi della tastiera vengono passati.
Riccioli d'oro,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.