LINUX.ORG.RU

Сообщения bellum

 

lkm, keyboard, method outb

В Linux Kernel Module Programming Guide упоминается пример, где сперва заменяют стандартный обработчик прерываний клавиатуры на свой, а затем играются с ней через порты (но там используется лишь inb() для чтения). Но мне по заданию необходимо, получив прерывание с символом «Q» (0x10) заменить его на «W» (0x11). Вопрос состоит в том, можно ли это осуществить с помощью метода outb_p(data,port) и если да, то почему при загрузке этого модуля при вводе «Q» я получаю всё тот же символ «Q» и сообщение: «Spurious NAK on isa0060/serio0. Some program might be trying access hardware directly».

Код таков:
#include <linux/kernel.h> /* Работа с ядром */
#include <linux/module.h> /* Необходимо для любого модуля */
#include <linux/interrupt.h> /* Определение irqreturn_t */
#include <asm/io.h> /* Функция inb(port) */

/*
* Обработчик прерываний от клавиатуры. Он считывает информацию с клавиатуры
* и в случае, если была нажата клавиша «Q» выводит вместо неё символ «W»
*/
irqreturn_t irq_handler(int irq, void *dev_id, struct pt_regs *regs)
{
unsigned char scancode;
unsigned char status;


   int value;

/*
* Прочитать состояние клавиатуры
*/
status = inb(0x64);
scancode = inb(0x60);

value = (int)scancode & 0x7f;
if ( value == 0x10 ){
status = inb(0x64);
outb_p(0x11, 0x60); //spurious NAK on isa0060/serio0. Some program might be trying access hardware directly
value = (int)inb(0x60) & 0x7f;
}
printk(«Scan Code %x %s.\n»,
   value,   
   //(int)scancode & 0x7f,
   scancode & 0x80 ? «Released»: «Pressed»);

return IRQ_HANDLED;
}
/*
* Инициализация модуля - регистрация обработчика прерывания
*/
int init_module()
{
/*
* Поскольку стандартный обработчик прерываний от клавиатуры не может
* сосуществовать с таким как наш, то придется запретить его
* (освободить IRQ) прежде, чем что либо сделать.
* Но поскольку мы не знаем где он находится в ядре, то мы лишены
* возможности переустановить его - поэтому компьютер придется перезагрузить
* после опробования этого примера.
*/
free_irq(1, NULL);
/*
* Подставить свой обработчик (irq_handler) на IRQ 1.
* IRQF_SHARED(SA_SHIRQ) означает, что мы допускаем возможность совместного
* обслуживания этого IRQ другими обработчиками.
*/
return request_irq(1, /* Номер IRQ */
irq_handler, /* наш обработчик */
   IRQF_SHARED,
   //=SA_SHIRQ,
«test_keyboard_irq_handler»,
(void *)(irq_handler));
}
/*
* Завершение работы
*/
void cleanup_module()
{
/*
* Эта функция добавлена лишь для полноты изложения.
* Она бессмысленна, поскольку нет способа
* восстановить стандартный обработчик прерываний от клавиатуры,
* поэтому необходимо выполнить перезагрузку системы.
*/
free_irq(1, NULL);
}
/*
* некоторые функции доступны только если модуль лицензирован под GPL
*/
MODULE_LICENSE(«GPL»);

bellum
()

RSS подписка на новые темы