第10章:键盘输入

本章概述

中断系统建立后,我们终于可以与外界交互了。本章将实现键盘驱动——操作系统的第一个设备驱动程序。

学习目标

  • 理解PS/2键盘的工作原理
  • 处理键盘中断(IRQ1 → 向量33)
  • 实现扫描码(Scan Code)到ASCII的转换
  • 构建输入缓冲区

前置知识

  • 第9章的中断系统(IDT、PIC、IRQ处理)
  • 端口I/O操作(inb/outb)

知识要点

PS/2键盘接口

端口用途
0x60数据端口(读取扫描码)
0x64状态/命令端口

扫描码集

键盘发送的是扫描码而非字符:

  • Make Code: 按下键时发送
  • Break Code: 释放键时发送(Make Code + 0x80)

输入缓冲区

使用环形缓冲区存储键盘输入,供内核其他部分读取。

文件结构

09-中断处理/code/    ← 需要中断系统支持
10-键盘输入/
├── README.md        ← 本文件
├── 理论讲解.md       ← PS/2键盘详解
├── code/
│   ├── keyboard.h   ← 键盘接口定义
│   ├── keyboard.c   ← 键盘驱动实现
│   ├── kernel.c     ← 更新:集成键盘
│   ├── Makefile      ← 更新:编译键盘模块
│   └── [共享文件]    ← 从上一章继承
├── 常见错误.md
└── 练习题.md

关键代码预览

// 键盘中断处理器
void keyboard_handler(registers_t *regs) {
    uint8_t scancode = inb(0x60);
 
    if (scancode & 0x80) {
        // 按键释放,处理修饰键(Shift等)
    } else {
        char c = scancode_to_ascii(scancode);
        if (c) {
            buffer_put(c);   // 存入缓冲区
            screen_putchar(c); // 回显
        }
    }
}

构建与测试

cd code
make
make run
# 在QEMU窗口中键入字符,应该能看到回显

本章收获

完成本章后,你的操作系统将能够:

  • ✅ 接收键盘输入
  • ✅ 将扫描码转换为可读字符
  • ✅ 在屏幕上回显输入
  • ✅ 缓存输入供后续处理