¿Qué sucede cuando se presiona Ctrl + Alt + F <Num>?


38

Estoy buscando una explicación de lo que sucede en Linux cuando se presiona esta combinación de teclas para cambiar el terminal actual. En particular, ¿qué componente de software intercepta esta combinación de teclas y cambia el terminal? ¿Es el núcleo? Si es el núcleo, ¿podría proporcionar la ubicación del archivo fuente que maneja esto?

Editar: Quiero entender cómo funciona esto en un entorno gráfico (X11) y basado en texto.


1
Para aclarar, ¿está presionando estas teclas mientras está en X11 (es decir, una sesión gráfica) o en la consola de texto? La respuesta es diferente.
derobert

Respuestas:


36

Es el núcleo. Tenga en cuenta que el teclado es hardware y todo lo que sucede allí pasa a través del núcleo; en el caso del cambio de VT, maneja el evento completamente por sí mismo y no pasa nada al espacio de usuario (sin embargo, creo que hay un medio relacionado con ioctl por el cual los programas de espacio de usuario pueden ser notificados de un cambio que los involucra y tal vez lo afecte, que X sin duda lo hace).

El núcleo tiene un mapa de teclas incorporado; esto se puede modificar mientras se ejecuta con loadkeysy ver 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
[...]   

La fuente del núcleo contiene un archivo de mapa de teclas predeterminado que se ve exactamente así; para 3.12.2 es src/drivers/tty/vt/defkeymap.map. También notará que hay un archivo defkeymap.c correspondiente (esto se puede generar con loadkeys --mktable). El manejo está en keyboard.c(todos estos archivos están en el mismo directorio) que llama set_console()desdevt.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);

Edité algunos éxitos de esa lista; Puede ver la firma de la función en la segunda última línea.

Estas son las cosas involucradas en el cambio. Si nos fijamos en la secuencia de llamadas, con el tiempo se llega de nuevo a kbd_event()en keyboard.c. Esto está registrado como un controlador de eventos para el módulo:

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

Por lo tanto, kbd_event()debe llamarse cuando algo surge del controlador de hardware real (probablemente algo de drivers/hid/o drivers/input/). Sin embargo, no verá que se mencione kbd_eventfuera de ese archivo, ya que está registrado a través de un puntero de función.

Algunos recursos para escudriñar el núcleo

  • La búsqueda de identificador de referencia cruzada de Linux es una gran herramienta.
  • El mapa interactivo del kernel de Linux es una interfaz gráfica interesante para la herramienta de referencia cruzada.
  • Hay algunos archivos históricos de la masiva lista de correo del kernel de Linux (LKML), que se remonta al menos a 1995; algunos de ellos no se mantienen y tienen funciones de búsqueda rotas, pero el gmane parece funcionar muy bien. La gente ha hecho muchas preguntas en la lista de correo y también es un medio principal de comunicación entre los desarrolladores.
  • Puede inyectar sus propias printklíneas en la fuente como un medio simple de rastreo (no todas las C lib estándar se pueden usar en el código del kernel, incluido printf de stdio). El material printk termina en syslog.

Wolfgang Mauerer escribió un gran libro sobre el kernel 2.6, Professional Linux Kernel Architecture , que abarca gran parte de la fuente. Greg Kroah-Hartman , uno de los principales desarrolladores de la última década, también tiene muchas cosas dando vueltas.


1
Gracias, esto es exactamente lo que estaba buscando. ¿Puedes dar más detalles sobre lo que sucede antes en la cadena? ¿Cómo se llama el código en keyboard.c cuando presionamos Ctrl + Alt + F1? keyboard.c no es el "controlador de teclado" real, ¿verdad?
user31765

1
No, no lo creo. Todo es parte del controlador tty, para lo cual keyboard.csería un controlador de eventos; el "controlador del teclado" en sí mismo sería de nivel inferior: hay muchos de ellos drivers/input/keyboard/para cosas que no son usb. El material USB está estandarizado, por lo que solo habría uno (probablemente relacionado drivers/hid/usbhid/usbkbd.c). Supongo que el controlador del teclado es para producir un código de escaneo que se puede entregar a vt / keyboard.c (ver getkeycode () cerca de la parte superior de eso). Documentation/input/input.txttiene algunos (maravillosamente antiguos, jajaja) pistas.
Ricitos de oro

PD. Muchos de los desarrolladores del kernel están en la lista de correo del kernel de Linux (LKML), que está abierta al público, y si le importan sus P&Q, etc. ( tux.org/lkml ) vale la pena preguntar allí ... solo asegúrese de configura una carpeta de inmediato, hay MUCHO correo involucrado.
Ricitos de oro

Al inspeccionar el código más de cerca, solo hay tres funciones no obsoletas en keyboard.c que llaman a set_console: fn_lastcons (), fn_dec_console () y fn_inc_console (). Uno para ir a la última consola y otro para ir a la derecha o a la izquierda. Entonces todavía no entiendo cómo se llama a set_console () cuando presionamos Ctrl + Alt + F <num>. Supongo que tenemos que pasar <num> como parámetro para set_console () en alguna parte. Veo que set_console () también aparece en vt_ioctl.c, pero ¿no es eso solo para ioctl desde el espacio de usuario, por ejemplo, desde chvt? Todavía hay algunos agujeros en mi comprensión.
user31765

1
Hay más cosas potencialmente relacionadas en drivers / hid. Observe también 'console_callback ()' en vt.c, que puede hacer el cambio y está registrado en la parte superior a través de DECLARE_WORK. Esto se relaciona con el planificador: lxr.free-electrons.com/ident?i=DECLARE_WORK (esa herramienta de referencia cruzada se puede alimentar desde makelinux.net/kernel_map que puede encontrar interesante); Supongo que eso hace que esa función sea un "bucle principal" para el vt. Obviamente, el enlace que falta aquí es exactamente cómo se pasan los eventos del teclado.
Ricitos de oro
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.