# 05 输入事件与键盘 ## 目标 建立输入事件模型,让键盘成为输入设备的一种,而不是直接绑定 shell 的特殊逻辑。 ## 前置条件 - 中断可用。 - 等待队列或事件队列可用。 - early log 可用于调试。 ## 建议边界 - `drivers/input/`:通用输入事件。 - `drivers/input/keyboard/`:键盘设备。 - `arch/x86/`:PS/2 控制器相关 I/O。 ## 实现内容 - 接入 PS/2 keyboard。 - 解码 scancode。 - 生成标准 key event。 - 建立输入事件队列。 - 为终端输入提供读取接口。 ### 1. Input core - 建立通用 input device 和 input event 结构,键盘只是 input device 的一种。 - input core 负责设备注册、事件入队、事件读取和等待队列唤醒。 - event 结构要能表达 key press/release、key code、modifier、设备来源和时间戳。 - 事件队列要有容量、溢出策略和统计信息,不能无限增长。 ### 2. Keyboard driver - PS/2 keyboard driver 只负责读取 scancode、维护按键状态、转换为通用 key event。 - scancode set、keyboard layout 和 keymap 要分层,不能把美式键盘布局写死到驱动主路径。 - modifier、repeat、release event、extended scancode 要逐步补齐。 - 键盘驱动不直接写 terminal、shell 或 VFS。 ### 3. IRQ 与 deferred processing - keyboard IRQ handler 只做短路径:读取数据、确认硬件状态、入队原始或半处理事件。 - 复杂解码、repeat 和 terminal line discipline 可以推迟到线程上下文。 - IRQ handler 不能 sleep,不能直接等待队列条件,不能调用 shell。 - 如果需要较复杂处理,先建立 deferred work 或 input worker。 ### 4. Terminal input boundary - terminal/tty 层从 input core 读取 key event,再处理行编辑、回显、控制字符和后续 job control。 - shell 只读取 terminal 字节流或行,不直接读取 keyboard scancode。 - 后续 USB HID、图形终端或串口终端应复用同一 terminal/input 边界。 - 输入路径要保留 blocking read、nonblocking read 和 poll/select 的接口位置。 ## Linux 参考原则 - 参考 Linux input subsystem:设备驱动上报通用 input event,上层消费者不绑定具体硬件。 - 参考 Linux serio/i8042/atkbd 分层:控制器、键盘协议和 input 事件上报分开。 - 参考 Linux tty/line discipline 思路:键盘事件到 shell 输入之间应有 terminal 层,不让 shell 直接处理硬件事件。 - 参考 Linux IRQ bottom half/workqueue 思路:中断路径短,复杂处理推迟。 ## 非玩具化约束 - 键盘驱动只产生事件,不直接操作 shell。 - 键盘布局要可替换。 - 输入队列接口要允许未来接 USB HID。 - 中断 handler 中不要做复杂处理。 - input core 不依赖 PS/2,PS/2 driver 不依赖 terminal。 - event queue 要有锁和等待语义,不能靠忙等读取。 - 事件丢失、队列满和未知 scancode 必须可观测。 - blocking read 必须通过 wait queue 或等价机制睡眠,不能轮询。 - terminal 控制字符和 shell 命令解析不能写进 keyboard driver。 ## 验收方式 - 按键触发中断。 - kernel 能读取 key event。 - 后续 shell 可复用同一输入接口。 - press/release event 可区分。 - unknown scancode 不会破坏输入队列。 - 没有输入时读取方会睡眠,有输入时被唤醒。 - keyboard selftest 或 QEMU 输入测试能验证事件路径。 - 后续接入 shell 时不需要修改 keyboard driver 主逻辑。 ## 当前状态 未开始。 进入本阶段前,`04-time-scheduler.md` 至少应具备可靠 wait queue 和明确的可睡眠/不可睡眠上下文规则。 ## 后续扩展 - USB HID keyboard。 - 鼠标和相对/绝对坐标事件。 - key repeat。 - 多 keyboard 设备。 - terminal line discipline。 - nonblocking input、poll/select。 - session、foreground process group 和 job control。