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

我试图涉足低级编程。我的目标是让用户在终端中键入密钥,捕获该密钥并输出另一个密钥。因此,例如,如果用户键入“ a”,我将键入“ b”,如果用户键入“

b”,我将输出“ c”,依此类推。

这样做的步骤是什么?我已经熟悉如何访问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");

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

免责声明

  • 该模块不是跨平台的(仅在x86架构上可用,因为它正在使用inb()功能)
  • 我相信它仅适用于PS / 2键盘(不适用于USB键盘)
  • pr_info()在硬件IRQ处理程序中执行缓慢的I / O操作(我的意思是),应避免这种情况(应使用理想的线程IRQ)。

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

input_register_device()serio_write()input_event()input_report_key(),等)。

细节

实际的中断处理程序(在键盘驱动程序中)请求为

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

该模块的工作原理如下:

  1. 捕获按键事件(kbd2_isr()每个按键事件都会调用硬件中断处理程序)
  2. 读取按键扫描代码(通过inb()功能)
  3. 并通过打印 pr_info()

现在,您要替换该扫描代码。我相信您可以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

以上是 Linux内核:如何捕获按键并用另一个按键代替? 的全部内容, 来源链接: utcz.com/qa/400251.html

回到顶部