我正在寻找有关按下此组合键来更改当前终端时 Linux 中发生的情况的解释。特别是,什么软件组件拦截此组合键并更改终端?是内核吗?如果是内核,您能否提供处理此问题的源文件的位置?
编辑:我想了解它在图形(X11)和基于文本的环境中如何工作。
答案1
它是内核。请记住,键盘是硬件,那里发生的一切都会通过内核;在 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()
在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, <--- 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/
或drivers/input/
)时,应该调用它。但是,您不会看到它在kbd_event
该文件外部被引用,因为它是通过函数指针注册的。
用于检查内核的一些资源
- 这Linux 交叉引用标识符搜索是一个很棒的工具。
- 这交互式 Linux 内核图是交叉引用工具的一个有趣的图形前端。
- 大量 Linux 内核邮件列表 (LKML) 的历史档案至少可以追溯到 1995 年;其中一些没有维护并且搜索功能已损坏,但是格曼一号似乎效果很好。人们在邮件列表上提出了很多问题,这也是开发人员之间的主要沟通方式。
- 您可以将自己的
printk
行注入到源代码中,作为一种简单的跟踪方法(并非所有标准 C 库都可以在内核代码中使用,包括来自 stdio 的 printf)。 printk 的内容最终会出现在 syslog 中。
Wolfgang Mauerer 写了一本关于 2.6 内核的伟大著作,专业Linux内核架构,它经历了很多来源。 格雷格·克罗哈特曼是过去十年的主要开发者之一,也有很多事情正在发生。