Minix 3 在 /drivers/tty/keymaps/ 文件夹下不同的 *.src 文件中定义了 u16_t keymap[NR_SCAN_CODES * MAP_COLS] 数组,
保存了不同的键盘中 键盘扫描码加修饰键 到 ASCII码 的映射。
如 us-std.src 中的 keymap 是针对 US MF-2 键盘的,japanese.src 中的 keymap 是针对 Japanese 106 键盘的。
文件 /drivers/tty/keyboard.c 中,
键盘输入缓存为环形,其定义如下,
#define KB_IN_BYTES 32 /* size of keyboard input buffer */
PRIVATE char ibuf[KB_IN_BYTES]; /* input buffer */
PRIVATE char *ihead = ibuf; /* next free spot in input buffer */
PRIVATE char *itail = ibuf; /* scan code to return to TTY */
PRIVATE int icount; /* # codes in buffer */
还定义了一些IO端口号和跟踪修饰状态的变量。
宏 map_key0 可视为函数,使用 keymap ,忽略修饰键,将扫描码映射为 ASCII 码。
函数map_key() 使用 keymap 进行扫描码到ASCII码的完全映射,包括处理和普通字符同时按下的(多重)修饰键。
kbd_interrupt() 为键盘中断例程,当一个键被按下或释放时被调用。它调用 scan_keyboard() 获得按键扫描码,
并将此扫描码插入键盘输入缓存中。
kb_read() 从键盘输入缓存中取出扫描码,并把ASCII码放在它的局部缓冲区中,
缓冲区应足够大以保存来自数字键盘的某些扫描码产生的转义序列。
然后它调用硬件无关代码中的in_process把字符放入输入队列。对make_break的调用以整数形式返回ASCII码。
在HOME和INSRT之间的扫描码由按下数字键盘产生,并且通过numpad_map数组被转换为三字符转义序列。
这些序列接着被传送到in_process中。
更高的扫描码不传给in_process,但要检测ALT-LEFT-ARROW,ALT-RIGHT-ARROW和ALT-F1到ALT-F12这些扫描码,
并且如果发现其中之一,就调用select_console切换虚拟控制台。
kb_read() 会持续处理直至键盘输入缓存为空。
make_break() 把扫描码转换为ASCII码然后更新跟踪修饰键状态的变量。
set_leds() 打开或关闭键盘上的 Num Lock,Caps Lock,Scroll Lock 指示灯。
func_key() 被 kb_read() 调用以判断是否按下了意味着局部处理的特殊键。
scan_keyboard() 在硬件接口层工作,从IO端口读写字节。