让鼠标漫天飞舞:在内核中实现鼠标的中断处理

代码的调试和运行,以及更详细的讲解,请参看视频:
Linux kernel Hacker, 从零构建自己的内核

上一节,我们成功实现了键盘按键的中断响应,本节,我们看如何响应鼠标的中断信号,并做相应处理。

这里写图片描述

如果大家还记得描述8259A中断控制器那一小节的话,鼠标发送中断信号的数据线在从8259A芯片的IRQ4信号线,因此,为了接收鼠标中断信号,我们在初始化中断控制芯片时,必须启用该信号线,同时,从8259A芯片是通过主8259A的IRQ2信号线连接在一起的,所以,也必须同时启动主8259A芯片的IRQ2信号线,这样,我们在内核中要对init8259A代码段做一些改动:

init8259A:
...
mov  al, 11111001b ;允许键盘中断
out  021h, al
call io_delay

mov  al, 11101111b ;允许鼠标中断
out  0A1h, al
call io_delay

ret

mov al, 11111001b 这一句指令,启用了主8259A芯片的IRQ1和IRQ2两根信号线,mov al, 11101111b 这句指令启用了从8259A的IRQ4信号线,这根信号线就是用来发送鼠标信号的。
我们上几节说过,只要是外接硬件,要想使用,就得对其进行配置和初始化,就像我们前面看到的,硬件的初始化,一般就是对给定端口发送几个数据而已,鼠标自然也不例外。

鼠标电路的初始化

鼠标电路对应的一个端口是 0x64, 通过读取这个端口的数据来检测鼠标电路的状态,内核会从这个端口读入一个字节的数据,如果该字节的第二个比特位为0,那表明鼠标电路可以接受来自内核的命令,因此,在给鼠标电路发送数据前,内核需要反复从0x64端口读取数据,并检测读到数据的第二个比特位,知道该比特位为0时,才着手发送控制信息,代码如下:

#define  PORT_KEYDAT  0x0060
#define  PORT_KEYSTA  0x0064
#define  PORT_KEYCMD  0x0064
#define  KEYSTA_SEND_NOTREADY  0x02
#define  KEYCMD_WRITE_MODE  0x60
#define  KBC_MODE     0x47

void  wait_KBC_sendready() {
    for(;;) {
        if ((io_in8(PORT_KEYSTA) & KEYSTA_SEND_NOTREADY) == 0) {
            break;
        }
    }
}

for循环一直从端口读取数据,然后检测比特位,只有对应比特位是0时,才返回。大家看到,上面代码中,居然有一个端口是 0x60, 你可能会困惑,0x60不是键盘电路的端口吗?没错,鼠标的初始化,就是得通过键盘电路来实现的,当对应比特位为0,也就是鼠标可以接收数据了,这时候,我们就得通过向端口0x60发送数据来配置鼠标:

void init_keyboard(void) {
    wait_KBC_sendready();
    io_out8(PORT_KEYCMD, KEYCMD_WRITE_MODE);
    wait_KBC_sendready();
    
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值