从零写 OS 内核-第二十九篇:鼠标驱动 —— 为你的图形界面添加指针控制

“键盘虽高效,但图形界面离不开鼠标。 今天,我们实现 PS/2 鼠标驱动,让你的窗口管理器支持点击与拖拽!”

在上一篇中,我们实现了 键盘驱动的窗口管理器 , 但真正的图形界面需要 鼠标支持 :

点击按钮
拖拽窗口
精确定位

而 x86 PC 最经典的鼠标接口是 PS/2 (通过 i8042 键盘控制器复用)。

今天,我们就来: ✅ 解析 PS/2 鼠标协议 ✅ 实现 i8042 控制器驱动 ✅ 注册鼠标设备到 devfs ✅ 在 Display Server 中集成鼠标事件

让你的 OS 拥有 完整的指针控制能力 !


🔌 一、PS/2 鼠标硬件基础

PS/2 接口特点:

6 针 Mini-DIN 接口

(鼠标通常为绿色)
串行通信

:时钟线(CLK) + 数据线(DATA)
由 i8042 键盘控制器管理

(端口 0x60/0x64)

i8042 端口:

端口 名称 作用
0x60 数据端口 读写鼠标/键盘数据
0x64 状态端口 读取控制器状态
0x64 命令端口 发送控制器命令

状态寄存器位:

bit 0 (OBF)

:1 = 输出缓冲区满(可读数据)
bit 1 (IBF)

:1 = 输入缓冲区满(勿写命令)
bit 5 (AUX_BSY)

:1 = 鼠标忙

💡 PS/2 鼠标使用 AUX 端口(与键盘主端口分离) !


📡 二、PS/2 鼠标协议

初始化流程:

  1. 检测鼠标存在
  2. 启用鼠标
  3. 设置采样率/分辨率
  4. 启用数据报告

鼠标数据包格式(3 字节):

L/R/M

:左/右/中键状态(1=按下)
X/Y 符号

:1=负方向(左/上)
溢出位

:位移超出 -255~255 范围

✅ 我们只处理标准 3 字节包 (忽略滚轮等扩展)。


⚙️ 三、i8042 控制器驱动

  1. 等待控制器就绪

  2. 发送 AUX 命令

  3. 初始化鼠标


🖱️ 四、鼠标中断处理

  1. 注册 IRQ12 中断

  2. 中断处理程序

🔑 中断只收集数据,解析在用户态线程完成 (避免内核复杂逻辑)!


📁 五、鼠标设备文件(/dev/input/mouse0)

  1. 注册字符设备

  2. read 系统调用

  3. 鼠标事件结构


🖥️ 六、Display Server 集成鼠标

  1. 启动鼠标监听线程

  2. 维护绝对坐标


🧪 七、测试:鼠标控制窗口

操作流程:

  1. 系统启动

    → 检测到 PS/2 鼠标

  2. 移动鼠标

    → 屏幕显示十字指针

  3. 点击窗口标题栏

    → 窗口获得焦点(标题变蓝)

  4. 拖拽标题栏

    → 窗口跟随鼠标移动

  5. 点击关闭提示

    → 窗口关闭

QEMU 测试命令:

💡 QEMU 默认模拟 USB 鼠标,但 i8042 驱动可兼容 。


⚠️ 八、高级话题

  1. 滚轮支持

    扩展为 4 字节包
    byte3

    包含滚轮位移

  2. 多鼠标支持

    /dev/input/mouse0

    ,
    /dev/input/mouse1
    通过设备树区分

  3. 鼠标加速

    根据移动速度动态调整 dx/dy

  4. USB 鼠标驱动

    实现 USB HID 类驱动
    支持现代 USB 鼠标

💡 Linux 的 psmouse 驱动支持从 PS/2 到 USB 的无缝切换 !


💬 写在最后

鼠标驱动是图形界面的 最后一块拼图 。 它将物理移动转化为屏幕坐标, 让用户能直观地与窗口交互。

今天你实现的第一个鼠标事件, 正是无数 GUI 交互的起点。

🌟 指针的每一次移动,都是人机对话的优雅舞蹈。


📬 动手挑战 : 添加鼠标右键菜单(在窗口标题栏右键弹出菜单)。 欢迎在评论区分享你的鼠标驱动调试技巧!

👇 下一篇你想看: USB 鼠标驱动 ,还是 触摸屏支持 ?


#操作系统 #内核开发 #鼠标驱动 #PS2 #i8042 #图形界面 #从零开始

代码仓库:

从0写OS内核 代码仓库:WandOS: An OS kernel developed using C++, 欢迎加星 + 贡献代码~

公众号:

欢迎关注我的公众号, 从0写OS内核 持续更新中~

过往文章链接 :

30分钟,教会一个AI小白用浏览器“训练一个会认猫狗的AI”
从VAE到Stable Diffusion:一张图是怎么“产生”的?30行代码读懂AI生图的底层逻辑
不用装环境、不买显卡,免费用上GPU跑AI模型?这个网站让你秒变AI工程师!
1000行代码,读懂大模型推理:手把手解析llama.c,这才是学习LLM的终极入门课
从零写 OS 内核-第二十六篇:用户态 Display Server 与 Client —— 真正的图形系统架构
从零写 OS 内核-第八篇:fork 与 exec —— 让进程“繁衍”起来!
从零开始写一个操作系统内核-第一篇:不只是“Hello World”
从零写 OS 内核-第九篇:用户态程序加载 —— ELF 解析与简易文件系统

最后修改: 2026年7月1日

作者

评论

发表评论

您的邮箱地址不会被公开。