【问题标题】:Kernel Module Programming ( Interrupt handler )内核模块编程(中断处理程序)
【发布时间】:2018-02-25 21:01:54
【问题描述】:

我写了一个关于如何使用中断处理程序的简单内核模块示例。该模块服务于键盘中断。它从键盘读取相关信息,然后输入有关按下的键的信息。它成功地将模块插入内核,并且中断工作良好。
但是,当我执行 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

【问题讨论】:

  • 我很想知道您是如何执行 rmmod 命令的,因为您的模块处理程序不支持字母输入。
  • 字母输入是什么意思?
  • 您已在 init 函数中删除了内置键盘模块,现在您的模块单独负责键盘中断。由于您的模块的中断处理程序是为 ESC、F1 和 F2 实现的,终端如何为“rmmod”输入输入,我对设备驱动程序非常陌生,请帮助我理解这一点。

标签: c linux linux-kernel linux-device-driver embedded-linux


【解决方案1】:

您的示例不处理一些随机 IRQ。它处理对机器工作至关重要的中断。

在您开始注册时,您删除了之前的中断处理程序。您的问题是您删除自己的后无法重新安装它。

结果是,当你rmmod你的模块时,没有人在处理键盘中断。

【讨论】:

  • 我不确定你的意思?你能写出固定的代码吗?我很感激
  • @HaiDang 我不确定是否有一种简单的方法可以检查当前处理程序是谁。没有它,编写你需要的代码并不简单。我建议你为你的学习项目寻找一个未使用的中断。
  • @"Hai Dang" - 正如@"Shachar Shemesh" 所说,一旦您使用了键盘 IRQ 的 free_irq,您将无法恢复它,您必须重新启动系统。请参阅您的代码源,其中解释了这一点:linuxtopia.org/online_books/…
【解决方案2】:

请修改代码:

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

进入:

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

您需要让内核知道您要删除哪个处理程序。由于您使用函数irq_handler()作为dev_id,您需要再次使用它来移除模式,而不移除原来的键盘中断处理程序。

【讨论】:

    猜你喜欢
    • 2023-04-04
    • 2012-01-23
    • 2015-09-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-05-09
    • 2023-03-12
    相关资源
    最近更新 更多