当前位置: 技术问答>linux和unix
linux内核态下有没有类似于用户态下scanf()这种等待输入的语句?
来源: 互联网 发布时间:2016-04-27
本文导语: linux内核态下有没有类似于用户态下scanf()这种等待输入的语句? | 你可以 自己 来处理 键盘中断 或者hook 你可以 看看 内核源文件 drivers/char/keyboard.c 里面应该有你想要知道的东西 ...
linux内核态下有没有类似于用户态下scanf()这种等待输入的语句?
|
你可以 自己 来处理 键盘中断 或者hook
你可以 看看 内核源文件 drivers/char/keyboard.c
里面应该有你想要知道的东西
你可以 看看 内核源文件 drivers/char/keyboard.c
里面应该有你想要知道的东西
|
在insmod这段代码前,在另一个终端sleep 120上做一次,如果要评估文件 系统的话,需要reboot。
这段代码把它自己绑定到IRQ1上,在Interl结构下这是键盘控制的IRQ。然后,当它接到一个键盘中断时,读出键盘的状态(这是inb(0x64)的目的)和由键盘返回的扫描码。然后,只要内核认为可以时,它就运行got_char给出键的编码(扫描码的前7位)和是否被按下的信息(如果第8位是0则表示按下,是1表示释放)。
ex intrpt.c
/* intrpt.c - An interrupt handler. */
/* Copyright (C) 1998 by Ori Pomerantz */
/* The necessary header files */
/* Standard in kernel modules */
#include /* Were doing kernel work */
#include /* Specifically, a module */
/* Deal with CONFIG_MODVERSIONS */
#if CONFIG_MODVERSIONS==1
#define MODVERSIONS
#include
#endif
#include
#include
/* We want an interrupt */
#include
#include
/* In 2.2.3 /usr/include/linux/version.h includes a
* macro for this, but 2.0.35 doesnt - so I add it
* here if necessary. */
#ifndef KERNEL_VERSION
#define KERNEL_VERSION(a,b,c) ((a)*65536+(b)*256+(c))
#endif
/* Bottom Half - this will get called by the kernel
* as soon as its safe to do everything normally
* allowed by kernel modules. */
static void got_char(void *scancode)
{
printk(""Scan Code %x %s. "",
(int) *((char *) scancode) & 0x7F,
*((char *) scancode) & 0x80 ? ""Released"" : ""Pressed"");
}
/* This function services keyboard interrupts. It reads
* the relevant information from the keyboard and then
* scheduales the bottom half to run when the kernel
* considers it safe. */
void irq_handler(int irq,
void *dev_id,
struct pt_regs *regs)
{
/* This variables are static because they need to be
* accessible (through pointers) to the bottom
* half routine. */
static unsigned char scancode;
static struct tq_struct task =
{NULL, 0, got_char, &scancode};
unsigned char status;
/* Read keyboard status */
status = inb(0x64);
scancode = inb(0x60);
/* Scheduale bottom half to run */
#if LINUX_VERSION_CODE > KERNEL_VERSION(2,2,0)
queue_task(&task, &tq_immediate);
#else
queue_task_irq(&task, &tq_immediate);
#endif
mark_bh(IMMEDIATE_BH);
}
/* Initialize the module - register the IRQ handler */
int init_module()
{
/* Since the keyboard handler wont co-exist with
* another handler, such as us, we have to disable
* it (free its IRQ) before we do anything. Since we
* dont know where it is, theres no way to
* reinstate it later - so the computer will have to
* be rebooted when were done.
*/
free_irq(1, NULL);
/* Request IRQ 1, the keyboard IRQ, to go to our
* irq_handler. */
return request_irq(
1, /* The number of the keyboard IRQ on PCs */
irq_handler, /* our handler */
SA_SHIRQ,
/* SA_SHIRQ means were willing to have othe
* handlers on this IRQ.
*
* SA_INTERRUPT can be used to make the
* handler into a fast interrupt.
*/
""test_keyboard_irq_handler"", NULL);
}
/* Cleanup */
void cleanup_module()
{
/* This is only here for completeness. Its totally
* irrelevant, since we dont have a way to restore
* the normal keyboard interrupt so the computer
* is completely useless and has to be rebooted. */
free_irq(1, NULL);
}
这段代码把它自己绑定到IRQ1上,在Interl结构下这是键盘控制的IRQ。然后,当它接到一个键盘中断时,读出键盘的状态(这是inb(0x64)的目的)和由键盘返回的扫描码。然后,只要内核认为可以时,它就运行got_char给出键的编码(扫描码的前7位)和是否被按下的信息(如果第8位是0则表示按下,是1表示释放)。
ex intrpt.c
/* intrpt.c - An interrupt handler. */
/* Copyright (C) 1998 by Ori Pomerantz */
/* The necessary header files */
/* Standard in kernel modules */
#include /* Were doing kernel work */
#include /* Specifically, a module */
/* Deal with CONFIG_MODVERSIONS */
#if CONFIG_MODVERSIONS==1
#define MODVERSIONS
#include
#endif
#include
#include
/* We want an interrupt */
#include
#include
/* In 2.2.3 /usr/include/linux/version.h includes a
* macro for this, but 2.0.35 doesnt - so I add it
* here if necessary. */
#ifndef KERNEL_VERSION
#define KERNEL_VERSION(a,b,c) ((a)*65536+(b)*256+(c))
#endif
/* Bottom Half - this will get called by the kernel
* as soon as its safe to do everything normally
* allowed by kernel modules. */
static void got_char(void *scancode)
{
printk(""Scan Code %x %s. "",
(int) *((char *) scancode) & 0x7F,
*((char *) scancode) & 0x80 ? ""Released"" : ""Pressed"");
}
/* This function services keyboard interrupts. It reads
* the relevant information from the keyboard and then
* scheduales the bottom half to run when the kernel
* considers it safe. */
void irq_handler(int irq,
void *dev_id,
struct pt_regs *regs)
{
/* This variables are static because they need to be
* accessible (through pointers) to the bottom
* half routine. */
static unsigned char scancode;
static struct tq_struct task =
{NULL, 0, got_char, &scancode};
unsigned char status;
/* Read keyboard status */
status = inb(0x64);
scancode = inb(0x60);
/* Scheduale bottom half to run */
#if LINUX_VERSION_CODE > KERNEL_VERSION(2,2,0)
queue_task(&task, &tq_immediate);
#else
queue_task_irq(&task, &tq_immediate);
#endif
mark_bh(IMMEDIATE_BH);
}
/* Initialize the module - register the IRQ handler */
int init_module()
{
/* Since the keyboard handler wont co-exist with
* another handler, such as us, we have to disable
* it (free its IRQ) before we do anything. Since we
* dont know where it is, theres no way to
* reinstate it later - so the computer will have to
* be rebooted when were done.
*/
free_irq(1, NULL);
/* Request IRQ 1, the keyboard IRQ, to go to our
* irq_handler. */
return request_irq(
1, /* The number of the keyboard IRQ on PCs */
irq_handler, /* our handler */
SA_SHIRQ,
/* SA_SHIRQ means were willing to have othe
* handlers on this IRQ.
*
* SA_INTERRUPT can be used to make the
* handler into a fast interrupt.
*/
""test_keyboard_irq_handler"", NULL);
}
/* Cleanup */
void cleanup_module()
{
/* This is only here for completeness. Its totally
* irrelevant, since we dont have a way to restore
* the normal keyboard interrupt so the computer
* is completely useless and has to be rebooted. */
free_irq(1, NULL);
}