Abu*_*ish 5 linux linux-kernel
我试图涉足低级编程.我的目标是让用户在终端中键入密钥,捕获并输出另一个密钥.因此,例如,如果用户键入"a",我会键入"b",如果他键入"b",则输出"c"等.
这样做的步骤是什么?我已经熟悉如何访问Linux内核源代码,编译它并使用它.
谢谢.
Sam*_*nko 11
考虑下一个简单的内核模块
#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");
Run Code Online (Sandbox Code Playgroud)
这是最简单和原始的密钥记录器.它可以很容易地重做以替换扫描代码.
inb()功能)pr_info()在硬件IRQ处理程序中执行缓慢的I/O操作(我的意思),应该避免(理想情况下应该使用线程IRQ)).但我认为这是很好的教育目的-它真的很小,证明这个想法相当不错(不与API一样搞乱input_dev, input_register_device(),serio_write(),input_event(),input_report_key(),等).
实际中断处理程序(在键盘驱动程序中)作为共享中断请求,这允许我们也请求中断,从而在我们的ISR中处理它(除了原始键盘驱动程序中的ISR).中断请求完成kbd2_init().
该模块的工作原理如下:
kbd2_isr()为每个按键事件调用硬件中断处理程序)inb()功能)pr_info()现在,您想要替换该扫描代码.我相信你可以使用outb()这个功能(在x86上).所以我留给你.
如果你想知道我们为什么要求1号IRQ,请参阅drivers/input/serio/i8042-io.h:
#else
# define I8042_KBD_IRQ 1
Run Code Online (Sandbox Code Playgroud)
另外一定要检查驱动程序/ input/serio/i8042.c中是否共享此IRQ :
error = request_irq(I8042_KBD_IRQ, i8042_interrupt, IRQF_SHARED,
"i8042", i8042_platform_device);
Run Code Online (Sandbox Code Playgroud)
这是i8042键盘控制器的文档:AT键盘控制器.
为避免幻数,您可以使用下一个定义.
来自drivers/input/serio/i8042-io.h:
/*
* Register numbers.
*/
#define I8042_COMMAND_REG 0x64
#define I8042_STATUS_REG 0x64
#define I8042_DATA_REG 0x60
Run Code Online (Sandbox Code Playgroud)
/*
* 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
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2534 次 |
| 最近记录: |