2017-09-17 7 views
0

인터럽트 처리기 사용 방법에 대한 간단한 커널 모듈 예제를 작성합니다. 모듈은 키보드 인터럽트를 처리합니다. 키보드에서 관련 정보를 읽은 다음 누른 키에 대한 정보를 입력합니다. 그것은 모듈을 커널에 성공적으로 insmod하고 잘 작동한다.
그러나 rmmod 모듈을 실행하면 Caps Lock의 LED가 깜박 거리고 PC가 멈 춥니 다 (Vmware 컴퓨터에서 실행). 나는 __exit 함수에 버그가 있다고 생각한다. 그러나 나는 고치는 법을 모른다. 누구든지 나를 도울 수 있습니까? 정말 고맙습니다.
코드 :커널 모듈 프로그래밍 (인터럽트 처리기)

/* 
* An interrupt handler 
*/ 

#include <linux/kernel.h> 
#include <linux/module.h> 
#include <linux/sched.h> 
#include <linux/workqueue.h> 
#include <linux/interrupt.h> 
#include <asm/io.h> 


MODULE_LICENSE("GPL"); 
MODULE_AUTHOR("Hai Dang Hoang"); 

/* 
* This function services keyboard interrupts. It reads the relevant 
* information from the keyboard and then puts information about Key that pressed 
* This example only has 3 key: ESC, F1, and F2 
*/ 

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 half routine. 
*/ 

    static unsigned char scancode; 
    unsigned char status; 

/* 
* Read keyboard status 
*/ 
    status = inb(0x64); 
    scancode = inb(0x60); 

switch (scancode) 
{ 
    case 0x01: printk (KERN_INFO "! You pressed Esc ...\n"); 
       break; 
    case 0x3B: printk (KERN_INFO "! You pressed F1 ...\n"); 
       break; 
    case 0x3C: printk (KERN_INFO "! You pressed F2 ...\n"); 
       break; 
    default: 
       break; 
} 

    return IRQ_HANDLED; 
} 

/* 
* Initialize the module - register the IRQ handler 
*/ 
static int __init irq_ex_init(void) 
{ 
    /* Free interrupt*/ 
    free_irq(1,NULL); 
    return request_irq (1, (irq_handler_t) irq_handler,IRQF_SHARED, "test_keyboard_irq_handler",(void *)(irq_handler)); 
} 

static void __exit irq_ex_exit(void) 
{ 
    free_irq(1,NULL); 
} 

module_init(irq_ex_init); 
module_exit(irq_ex_exit); 

아니면 내 링크 GitHub의에 내 코드를 볼 수 있습니다 Example interrupt handler

+0

모듈 처리기가 알파벳 입력을 지원하지 않기 때문에 rmmod 명령을 어떻게 실행했는지 알고 싶습니다. – Ash

+0

알파벳 입력이란 무엇입니까? –

+0

init 함수에서 내장 키보드 모듈을 제거 했으므로 이제 모듈 만 키보드 인터럽트에 반응합니다. 모듈의 인터럽트 처리기가 ESC, F1 및 F2 용으로 구현되었으므로 터미널이 "rmmod"에 대한 입력을받는 방식에 대해, 나는이 점을 이해하는 데 도움이되는 장치 드라이버에 대해 매우 익숙합니다. – Ash

답변

2

귀하의 예는 어떤 임의의 IRQ를 처리하지 않습니다. 그것은 기계 작업에 중요한 인터럽트를 처리합니다.

등록 시작시 이전 인터럽트 처리기가 제거됩니다. 문제는 자신을 제거한 후에 다시 설치하지 못했기 때문입니다.

결과적으로 모듈 rmmod을 사용할 때 아무도 키보드 인터럽트를 처리하지 못합니다.

+0

무슨 뜻인지 모르겠다. 고정 된 코드를 작성할 수 있습니까? 고맙습니다. –

+0

@HaiDang 현재 핸들러가 누구인지를 확인하는 간단한 방법이 있는지 모르겠습니다. 그것 없이는 필요한 코드를 작성하는 것이 간단하지 않습니다. 학습 프로젝트에 사용되지 않는 인터럽트를 찾으십시오. –

0

코드를 변경하십시오

static void __exitrq_ex_exit(void) 
{ 
    free_irq(1, NULL); 
} 

로 :

static void __exitrq_ex_exit(void) 
{ 
    free_irq(1, (void*)irq_handler); 
} 

당신은 커널이 제거 할 핸들러 알려해야합니다. dev_id으로 irq_handler() 함수를 사용하므로 원래 키보드 인터럽트 처리기를 제거하지 않고 모드를 제거하려면 다시 사용해야합니다.