To use interrupt. #include <linux/kernel.h> /*We're doing kernel work*/ #include <linux/module.h> /*Specifically, a module*/ #include <linux/sched.h> #include <linux/workqueue.h> #include <linux/interrupt.h> /*We want an interrupt*/ #include <asm/io.h> #define MY_WORK_QUEUE_NAME "WQsched.c" static struct workqueue_struct *my_workqueue; /* * This will get called by the kernel as soon as it's safe * to do everything normally allowed by kernel modules. */ static void got_char(void *scancode) { printk("ScanCode%x%s./n", (int)*((char*)scancode)&0x7F, *((char*)scancode)&0x80?"Released":"Pressed"); } /* * This function services keyboard interrupts. It reads the relevant * information from the keyboard and then puts the non time critical * part into the work queue. This will be run when the kernel considers it safe. */ irqreturn_t 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 halfroutine. */ static int initialised=0; static unsigned char scancode; static struct work_struct task; unsigned char status; /* * Read keyboard status */ status=inb(0x64); scancode=inb(0x60); if(initialised==0){ INIT_WORK(&task,got_char,&scancode); initialised=1; } else { PREPARE_WORK(&task,got_char,&scancode); } queue_work(my_workqueue,&task); return IRQ_HANDLED; } int init_module() { my_workqueue=create_workqueue(MY_WORK_QUEUE_NAME); /* * Since the keyboard handler won't co-exist with another handler, * such as us, we have to disable it (free its IRQ) before we do * anything. Since we don't know where it is, there's no way to * reinstate it later - so the computer will have to be rebooted * whenwe'redone. */ free_irq(1,NULL); /* * Request IRQ 1, the keyboard IRQ, to go to our irq_handler. * SA_SHIRQ means we're willing to have othe handlers on this IRQ. * SA_INTERRUPT can be used to make the handler into a fast interrupt. */ return request_irq(1, /*The number of the keyboard IRQ on PCs*/ irq_handler, /*ourhandler*/ SA_SHIRQ,"test_keyboard_irq_handler", (void*)(irq_handler)); } voidcleanup_module() { /* * This is only here for completeness. It's totally irrelevant, since * we don't have a way to restore the normal keyboard interruptsothe * computer is completely useless and has to be rebooted. */ free_irq(1,NULL); } MODULE_LICENSE("GPL");