您好, 欢迎来到 !    登录 | 注册 | | 设为首页 | 收藏本站

Linux内核:如何捕获按键并用另一个按键代替?

Linux内核:如何捕获按键并用另一个按键代替?

考虑下一个简单的内核模块:

#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/interrupt.h>
#include <asm/io.h>

#define KBD_IRQ             1       /* IRQ number for keyboard (i8042) */
#define KBD_DATA_REG        0x60    /* I/O port for keyboard data */
#define KBD_SCANCODE_MASK   0x7f
#define KBD_STATUS_MASK     0x80

static irqreturn_t kbd2_isr(int irq, void *dev_id)
{
    char scancode;

    scancode = inb(KBD_DATA_REG);
    /* NOTE: I/O ops take a lot of time thus must be avoided in HW ISRs */
    pr_info("Scan Code %x %s\n",
            scancode & KBD_SCANCODE_MASK,
            scancode & KBD_STATUS_MASK ? "Released" : "Pressed");

    return IRQ_HANDLED;
}

static int __init kbd2_init(void)
{
    return request_irq(KBD_IRQ, kbd2_isr, IRQF_SHARED, "kbd2", (void *)kbd2_isr);
}

static void __exit kbd2_exit(void)
{
    free_irq(KBD_IRQ, (void *)kbd2_isr);
}

module_init(kbd2_init);
module_exit(kbd2_exit);

MODULE_LICENSE("GPL");

这是最小的和原始的键记录器。可以很容易地将其重新制作以替换扫描代码

但我认为这是很好的教育目的-它真的很小,证明这个想法相当不错(不与API搞乱像input_devinput_register_device()serio_write()input_event()input_report_key(),等)。

实际的中断处理程序(在键盘驱动程序中)请求为 ,这使我们还可以请求该中断,从而在我们的ISR中(除了原始键盘驱动程序中的ISR之外)也可以处理该中断。中断请求在中完成kbd2_init()

该模块的工作原理如下:

现在,您要替换该扫描代码。我相信您可以outb()为此使用功能(在x86上)。所以我留给你。

如果您想知道为什么我们请求编号为1的IRQ,请参阅drivers / input / serio / i8042-io.h

#else
# define I8042_KBD_IRQ  1

另外,还要确保在驱动程序/input/serio/i8042.c中共享此IRQ :

error = request_irq(I8042_KBD_IRQ, i8042_interrupt, IRQF_SHARED,
                    "i8042", i8042_platform_device);

这是i8042键盘控制器的文档:AT键盘控制器

为了避免幻数,可以使用下一个定义。

driver / input / serio / i8042-io.h

/*
 * Register numbers.
 */

#define I8042_COMMAND_REG       0x64
#define I8042_STATUS_REG        0x64
#define I8042_DATA_REG          0x60

include / linux / i8042.h

/*
 * Status register bits.
 */

#define I8042_STR_PARITY        0x80
#define I8042_STR_TIMEOUT       0x40
#define I8042_STR_AUXDATA       0x20
#define I8042_STR_KEYLOCK       0x10
#define I8042_STR_CMDDAT        0x08
#define I8042_STR_MUXERR        0x04
#define I8042_STR_IBF           0x02
#define I8042_STR_OBF           0x01
其他 2022/1/1 18:14:22 有611人围观

撰写回答


你尚未登录,登录后可以

和开发者交流问题的细节

关注并接收问题和回答的更新提醒

参与内容的编辑和改进,让解决方法与时俱进

请先登录

推荐问题


联系我
置顶