You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PS/2鼠标中断无法触发问题排查求助

PS/2鼠标中断无法触发的排查与修复

核心问题分析

你遇到的中断不触发问题,主要有两个关键原因:

  1. 从PIC掩码完全屏蔽了所有中断,包括鼠标对应的IRQ12;
  2. PS/2鼠标初始化命令错误,未正确启用数据报告。

1. 修正PIC掩码设置

PS/2鼠标使用IRQ12,对应从PIC(Slave PIC)的第4位(IRQ8对应从PIC第0位,以此类推)。当前你把从PIC掩码设为0xFF,等于完全关闭了所有从PIC中断,必须修改为允许IRQ12通过:

// 修改pic_remap函数中的掩码部分
void pic_remap(int offset_master, int offset_slave)
{
    // ... 原有重映射代码保持不变 ...

    // 更新掩码:主PIC保留IRQ1(键盘),从PIC打开IRQ12(鼠标)
    outportb(PIC_MASTER_DATA, 0xFD);
    outportb(PIC_SLAVE_DATA, 0xEF);  // 0xEF = 0xFF & ~(1 << 4)
}

2. 修复PS/2鼠标初始化流程

你的mouse_driver里错误发送了0xFA(这是鼠标的ACK响应,不是命令),正确的做法是发送0xF4启用鼠标数据报告:

void mouse_driver()
{
    // 启用第二个PS/2端口(鼠标端口)
    outportb(PS2_CMDPORT, 0xA8);
    
    // 读取并修改PS/2控制器状态字节,启用鼠标中断
    outportb(PS2_CMDPORT, 0x20);
    uint8_t status = inportb(PS2_DATAPORT) | 2;
    outportb(PS2_CMDPORT, 0x60);
    outportb(PS2_DATAPORT, status);
    
    // 向鼠标发送启用数据报告命令
    outportb(PS2_CMDPORT, 0xD4);
    outportb(PS2_DATAPORT, 0xF4);
    
    // 等待并确认鼠标的ACK响应(0xFA)
    while (!(inportb(PS2_CMDPORT) & 0x01));
    inportb(PS2_DATAPORT);
}

3. 中断处理函数必须发送EOI信号

如果你的handler_mouse没有发送中断结束信号(EOI),PIC会停止触发后续中断,务必在处理逻辑末尾添加:

void handler_mouse()
{
    // 你的鼠标数据处理逻辑...

    // 向从PIC发送EOI
    outportb(PIC_SLAVE, 0x20);
    // 向主PIC发送EOI(从PIC中断会级联到主PIC的IRQ2)
    outportb(PIC_MASTER, 0x20);
}

额外验证点

  • 确认PIC_MASTER、PIC_SLAVE、PIC_MASTER_DATA、PIC_SLAVE_DATA的定义正确:通常主PIC端口是0x20/0x21,从PIC是0xA0/0xA1;
  • 确保_start中调用了pic_remap(0x20, 0x28);,这是PIC重映射的必要步骤(你的代码中未显示调用,记得补上)。

内容的提问来源于stack exchange,提问作者Endrix

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.05 07:46:33