2017-09-17 47 views
0

割り込みハンドラの使い方の簡単なカーネルモジュールの例を書いています。モジュールはキーボード割り込みを処理します。キーボードから関連情報を読み込み、押されたKeyに関する情報を入力します。それはモジュールをカーネルに正常に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の場合、誰もキーボード割り込みを処理していません。あなたは、カーネルはあなたが削除するハンドラ知らせる必要があり

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

:へ

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

+0

私はあなたが何を意味するか分からない?あなたは固定コードを書くことができますか?私はそれを感謝します –

+0

@HaiDang私は現在のハンドラが誰であるかをチェックする簡単な方法があるか分からない。それがなければ、必要なコードを書くのは簡単ではありません。私はあなたの学習プロジェクトのための未使用の割り込みを探すことをお勧めします。 –

0

コードを変更してください。 dev_idにはirq_handler()という関数が使用されているので、元のキーボード割り込みハンドラを削除せずにモードを削除するには、再度使用する必要があります。

関連する問題