O que acontece quando o Ctrl + Alt + FNum é pressionado?

38

Estou procurando uma explicação do que acontece no Linux quando essa combinação de teclas é pressionada para alterar o terminal atual. Em particular, qual componente de software intercepta essa combinação de teclas e altera o terminal? É o kernel? Se for o kernel, você poderia fornecer a localização do arquivo de origem que lida com isso?

Editar: Eu quero entender como isso funciona em um ambiente gráfico (X11) e baseado em texto.

    
por user31765 04.02.2013 / 20:22

1 resposta

36

É o kernel. Tenha em mente que o teclado é hardware e tudo o que acontece lá passa pelo kernel; no caso da comutação VT, ele lida com o evento completamente e não passa nada para o userspace (no entanto, acredito que haja um meio relacionado ao ioctl pelo qual os programas userspace podem ser notificados de um switch que os envolva e talvez o afete, que X, sem dúvida, faz).

O kernel tem um keymap embutido nele; isso pode ser modificado durante a execução com loadkeys e visualizado com 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
[...]   

O código-fonte do kernel contém um arquivo de mapa de chaves padrão que é exatamente assim; para 3.12.2 é src/drivers/tty/vt/defkeymap.map . Você também notará que existe um arquivo defkeymap.c correspondente (isso pode ser gerado com loadkeys --mktable ). A manipulação está em keyboard.c (todos esses arquivos estão em o mesmo diretório) que chama set_console() de vt.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);

Eu editei alguns hits dessa lista; você pode ver a assinatura da função na segunda última linha.

Então, essas são as coisas envolvidas na troca. Se você olhar para a sequência de chamadas, eventualmente você volta para kbd_event() em keyboard.c . Isso é registrado como um manipulador de eventos para o módulo:

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

Portanto, kbd_event() deve ser chamado quando algo aparecer no driver de hardware real (provavelmente algo de drivers/hid/ ou drivers/input/ ). No entanto, você não o verá como kbd_event fora desse arquivo, já que está registrado por meio de um ponteiro de função.

Alguns recursos para investigar o kernel

  • A Busca de identificadores de referência cruzada do Linux é uma ótima ferramenta.
  • O Mapa interativo do kernel do Linux é um front end gráfico interessante para a ferramenta de referência cruzada.
  • Existem alguns arquivos históricos da enorme LKML (Linux Kernel Mailing List), que remonta pelo menos a 1995; alguns deles não são mantidos e quebraram os recursos de pesquisa, mas o o gmane parece funcionar muito bem. As pessoas fizeram muitas perguntas na lista de e-mail e também é o principal meio de comunicação entre os desenvolvedores.
  • Você pode injetar suas próprias linhas printk na origem como um meio simples de rastreio (nem todo o C lib padrão pode ser usado no código do kernel, incluindo printf do stdio). O material do printk acaba no syslog.

Wolfgang Mauerer escreveu um grande livro sobre o kernel 2.6, Arquitetura Profissional Linux Kernel , que passa por grande parte da fonte. Greg Kroah-Hartman , um dos principais desenvolvedores da última década, também tem muitas coisas por aí.

    
por 04.02.2013 / 21:59