Apa yang terjadi ketika Ctrl + Alt + F <Num> ditekan?

38

Saya mencari penjelasan tentang apa yang terjadi di Linux ketika kombinasi tombol ini ditekan untuk mengubah terminal saat ini. Secara khusus, komponen perangkat lunak apa yang memotong kombinasi kunci ini dan mengubah terminal? Apakah itu kernel? Jika itu adalah kernel, dapatkah Anda memberikan lokasi file sumber yang menangani ini?

Sunting: Saya ingin memahami cara kerjanya di lingkungan berbasis grafis (X11) dan teks.

pengguna31765
sumber
1
Untuk memperjelas, apakah Anda menekan tombol-tombol ini saat berada di X11 (yaitu, sesi grafis) atau di konsol teks? Jawabannya berbeda.
derobert

Jawaban:

36

Itu adalah kernel. Perlu diingat keyboard adalah perangkat keras dan semua yang terjadi di sana melewati kernel; dalam kasus VT switching, ia menangani peristiwa itu sendiri sepenuhnya dan tidak meneruskan apa pun ke userspace (namun, saya percaya ada cara terkait ioctl di mana program userspace dapat diberitahu tentang switch yang terjadi yang melibatkan mereka dan mungkin mempengaruhinya, yang X tidak diragukan lagi).

Kernel memiliki build keymap di dalamnya; ini dapat dimodifikasi saat berjalan dengan loadkeys, dan dilihat dengan 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
[...]   

Sumber kernel berisi file keymap default yang terlihat persis seperti ini; untuk 3.12.2 itu src/drivers/tty/vt/defkeymap.map. Anda juga akan melihat ada file defkeymap.c yang sesuai (ini dapat dibuat dengan loadkeys --mktable). Penanganannya ada di keyboard.c(semua file ini berada di direktori yang sama) yang memanggil set_console()darivt.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);

Saya mengedit beberapa hit dari daftar itu; Anda dapat melihat tanda tangan fungsi pada baris terakhir kedua.

Jadi ini adalah hal-hal yang terlibat dalam peralihan. Jika Anda melihat urutan panggilan, akhirnya Anda kembali ke kbd_event()dalam keyboard.c. Ini terdaftar sebagai pengendali acara untuk modul:

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

Oleh karena itu, kbd_event()harus dipanggil ketika sesuatu muncul dari driver perangkat keras yang sebenarnya (mungkin sesuatu dari drivers/hid/atau drivers/input/). Namun, Anda tidak akan melihatnya disebut di kbd_eventluar file itu, karena terdaftar melalui penunjuk fungsi.

Beberapa sumber daya untuk meneliti kernel

  • The Linux Referensi Silang Identifier Cari adalah alat yang hebat.
  • The Interaktif Linux Kernel Peta adalah menarik grafis front end ke alat referensi silang.
  • Ada beberapa arsip historis dari Mailing List Kernel Linux (LKML) yang masif, yang kembali ke setidaknya 1995; beberapa dari mereka tidak terawat dan memiliki fitur pencarian yang rusak, tetapi satu gmane tampaknya bekerja dengan sangat baik. Orang-orang telah mengajukan banyak pertanyaan pada daftar surat dan ini juga merupakan sarana komunikasi utama di antara para pengembang.
  • Anda dapat menyuntikkan printkbaris Anda sendiri ke sumber sebagai cara penelusuran sederhana (tidak semua standar C lib dapat digunakan dalam kode kernel, termasuk printf dari stdio). hal-hal printk berakhir di syslog.

Wolfgang Mauerer menulis sebuah buku besar yang hebat tentang kernel 2.6, Arsitektur Linux Kernel Profesional , yang melewati banyak sumber. Greg Kroah-Hartman , salah satu pengembang prinsip untuk dekade terakhir, juga memiliki banyak hal.

goldilocks
sumber
1
Terima kasih, inilah tepatnya yang saya cari. Bisakah Anda menguraikan apa yang terjadi sebelumnya dalam rantai? Bagaimana kode di keyboard.c dipanggil ketika kita menekan Ctrl + Alt + F1? keyboard.c bukan "driver keyboard" yang sebenarnya, bukan?
user31765
1
Tidak, kurasa tidak. Itu semua adalah bagian dari driver tty, yang keyboard.cakan menjadi pengendali acara; "driver keyboard" itu sendiri akan menjadi level yang lebih rendah - ada banyak di antaranya drivers/input/keyboard/untuk hal-hal non-usb. Hal-hal usb standar sehingga hanya akan ada satu (mungkin melibatkan drivers/hid/usbhid/usbkbd.c) Saya menduga bahwa driver keyboard adalah untuk memproduksi scancode yang dapat diserahkan ke vt / keyboard.c (lihat getkeycode () di dekat bagian atas itu). Documentation/input/input.txtmemiliki beberapa petunjuk (sangat kuno, lol).
goldilocks
PS. Banyak dari devs kernel ada di daftar mail kernel Linux (LKML) yang terbuka untuk umum, dan jika Anda keberatan dengan P&Q Anda, dll ( tux.org/lkml ) ada baiknya bertanya di sana ... pastikan Anda mengatur folder untuk itu segera, ada BANYAK surat yang terlibat.
goldilocks
Setelah memeriksa kode lebih dekat, hanya ada tiga fungsi yang tidak usang di keyboard.c yang memanggil set_console: fn_lastcons (), fn_dec_console (), dan fn_inc_console (). Satu untuk pergi ke konsol terakhir dan satu untuk pergi ke kanan atau kiri. Jadi saya masih tidak mengerti bagaimana set_console () dipanggil ketika kita menekan Ctrl + Alt + F <num>. Saya berasumsi kita harus meneruskan <num> sebagai parameter ke set_console () di suatu tempat. Saya melihat set_console () muncul di vt_ioctl.c juga, tetapi bukankah itu hanya untuk ioctl dari ruang pengguna, mis. Dari chvt? Masih ada beberapa lubang dalam pemahaman saya.
user31765
1
Ada lebih banyak hal yang berpotensi terkait di driver / hid. Juga perhatikan 'console_callback ()' di vt.c, yang dapat melakukan pergantian dan terdaftar di atas melalui DECLARE_WORK. Ini berkaitan dengan penjadwal: lxr.free-electrons.com/ident?i=DECLARE_WORK (alat referensi silang tersebut dapat diumpankan dari makelinux.net/kernel_map yang mungkin menarik bagi Anda); Saya akan berasumsi bahwa membuat fungsi semacam "loop utama" untuk vt. Jelas tautan yang hilang di sini adalah persis bagaimana peristiwa papan ketik dilewatkan.
goldilocks