Nó là hạt nhân. Hãy nhớ rằng bàn phím là phần cứng và mọi thứ xảy ra ở đó đều đi qua kernel; trong trường hợp chuyển đổi VT, nó tự xử lý sự kiện hoàn toàn và không chuyển bất kỳ thứ gì vào không gian người dùng (tuy nhiên, tôi tin rằng có một phương tiện liên quan đến ioctl có thể được thông báo về việc chuyển đổi xảy ra liên quan đến họ và có thể ảnh hưởng đến nó, mà X không nghi ngờ gì).
Hạt nhân có một sơ đồ xây dựng vào nó; điều này có thể được sửa đổi trong khi chạy với loadkeys
và được xem với 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
[...]
Nguồn kernel chứa tệp keymap mặc định trông giống hệt như thế này; cho 3.12.2 src/drivers/tty/vt/defkeymap.map
. Bạn cũng sẽ nhận thấy có một tệp defkeymap.c tương ứng (có thể được tạo bằng loadkeys --mktable
). Việc xử lý nằm trong keyboard.c
(tất cả các tệp này nằm trong cùng một thư mục) sẽ gọi set_console()
từ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);
Tôi đã chỉnh sửa một số lượt truy cập ra khỏi danh sách đó; bạn có thể thấy chữ ký hàm trên dòng cuối cùng thứ hai.
Vì vậy, đây là những điều liên quan đến việc chuyển đổi. Nếu bạn nhìn vào chuỗi các cuộc gọi, cuối cùng bạn trở lại kbd_event()
trong keyboard.c
. Điều này được đăng ký như một trình xử lý sự kiện cho mô-đun:
(3.12.2 drivers/tty/vt/keyboard.c
dòng 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);
Do đó, kbd_event()
nên được gọi khi một cái gì đó nổi lên từ trình điều khiển phần cứng thực tế (có thể là một cái gì đó từ drivers/hid/
hoặc drivers/input/
). Tuy nhiên, bạn sẽ không thấy nó được gọi là kbd_event
bên ngoài tệp đó, vì nó được đăng ký thông qua một con trỏ hàm.
Một số tài nguyên để xem xét kỹ lưỡng kernel
- Các Linux Cross tham khảo Định danh Search là một công cụ tuyệt vời.
- Các Interactive Linux Kernel Bản đồ là một đồ họa ngoại thú vị để các công cụ tham khảo chéo.
- Có một vài tài liệu lưu trữ lịch sử của Danh sách gửi thư hạt nhân Linux (LKML) khổng lồ, trở lại ít nhất là năm 1995; một số trong số chúng không được duy trì và có các tính năng tìm kiếm bị hỏng, nhưng gmane dường như hoạt động rất tốt. Mọi người đã hỏi rất nhiều câu hỏi trong danh sách thư và đó cũng là một phương tiện liên lạc chính giữa các nhà phát triển.
- Bạn có thể đưa các
printk
dòng của riêng mình vào nguồn như một phương tiện theo dõi đơn giản (không phải tất cả các lib C tiêu chuẩn đều có thể được sử dụng trong mã kernel, bao gồm printf từ stdio). công cụ printk kết thúc trong syslog.
Wolfgang Mauerer đã viết một cuốn sách lớn tuyệt vời về hạt nhân 2.6, Kiến trúc hạt nhân Linux chuyên nghiệp , đi qua rất nhiều nguồn. Greg Kroah-Hartman , một trong những nhà phát triển nguyên tắc trong thập kỷ qua, cũng có rất nhiều thứ đang đá xung quanh.