PS/2鼠标中断无法触发问题排查求助
PS/2鼠标中断无法触发的排查与修复
核心问题分析
你遇到的中断不触发问题,主要有两个关键原因:
- 从PIC掩码完全屏蔽了所有中断,包括鼠标对应的IRQ12;
- 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
相关产品推荐
相关产品推荐

