Linux

按下 Ctrl + Alt + F<Num> 會發生什麼?

  • September 21, 2017

我正在尋找有關按下此組合鍵以更改目前終端時在 Linux 中發生的情況的解釋。特別是什麼軟體組件攔截了這個組合鍵並改變了終端?是核心嗎?如果是核心,您能否提供處理此問題的源文件的位置?

編輯:我想了解它在圖形(X11)和基於文本的環境中是如何工作的。

它是核心。請記住,鍵盤是硬體,那裡發生的一切都通過核心;在 VT 切換的情況下,它完全自己處理事件並且不會將任何東西傳遞給使用者空間(但是,我相信有一種 ioctl 相關的方法可以通知使用者空間程序發生涉及它們的切換並可能影響它, X 無疑是這樣)。

核心內置了一個鍵盤映射;這可以在執行時修改loadkeys,並使用查看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
[...]   

核心原始碼包含一個預設的鍵盤映射文件,看起來就像這樣;對於 3.12.2,它是src/drivers/tty/vt/defkeymap.map. 您還會注意到有一個相應的defkeymap.c文件(可以使用 生成loadkeys --mktable)。處理在keyboard.c(所有這些文件都在同一個目錄中),它呼叫set_console()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);

我編輯了該列表中的一些熱門歌曲;您可以在倒數第二行看到函式簽名。

所以這些是切換中涉及的東西。如果您查看呼叫順序,最終您會回到kbd_event()in keyboard.c。這被註冊為模組的事件處理程序:

(3.12.2drivers/tty/vt/keyboard.c第 1473 行)

MODULE_DEVICE_TABLE(input, kbd_ids);

static struct input_handler kbd_handler = {
   .event      = kbd_event,   &lt;--- 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);           

因此,kbd_event()應該在實際硬體驅動程序中冒出一些東西(可能來自drivers/hid/or的東西drivers/input/)時呼叫。但是,您不會看到它kbd_event在該文件之外被引用,因為它是通過函式指針註冊的。

審查核心的一些資源

  • Linux 交叉引用標識符搜尋是一個很棒的工具。
  • Interactive Linux Kernel Map是交叉引用工具的一個有趣的圖形前端。
  • 大量的 Linux 核心郵件列表 (LKML) 有一些歷史檔案,至少可以追溯到 1995 年;其中一些沒有維護並且搜尋功能損壞,但gmane似乎工作得很好。人們在郵件列表上提出了很多問題,這也是開發人員之間的主要交流方式。
  • 您可以將自己的printk行注入原始碼作為一種簡單的跟踪方式(並非所有標準 C 庫都可以在核心程式碼中使用,包括 stdio 中的 printf)。printk 的東西最終出現在 syslog 中。

Wolfgang Mauerer 寫了一本很棒的關於 2.6 核心的大書《Professional Linux Kernel Architecture》,其中包含了大量的原始碼。 Greg Kroah-Hartman是過去十年的主要開發者之一,他也有很多事情要做。

引用自:https://unix.stackexchange.com/questions/63688