c - 键盘中断处理的 Linux 设备驱动程序错误

标签 c linux linux-kernel driver device

在学习如何在内核模式下编写键盘中断处理程序的过程中,按照下面的示例,在内核空间加载驱动程序后出现这样的错误。

#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");
irqreturn_t irq_handler(int irq, void *dev_id, struct pt_regs *regs) {
    static unsigned char scancode, 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;
}
static int __init irq_ex_init(void) {
    printk (KERN_INFO "DEVICE OPEN...\n");
    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) {
    printk (KERN_INFO "!DEVICE CLOSE...\n");
    free_irq(1,(void*)(irq_handler));
}
module_init(irq_ex_init);
module_exit(irq_ex_exit);

卸载也正常,但是用insmod加载后,出现这样的错误。我想知道是否有人可以解释一下。 我使用 Ubuntu 16.04.2 LTS。

Dec  5 12:02:01 iman kernel: [  502.506500] ------------[ cut here ]------------
Dec  5 12:02:01 iman kernel: [  502.506510] WARNING: CPU: 1 PID: 4240 at /build/linux-hwe-zOpU13/linux-hwe-4.10.0/kernel/irq/manage.c:1484 __free_irq+0xa4/0x290
Dec  5 12:02:01 iman kernel: [  502.506511] Trying to free already-free IRQ 1
Dec  5 12:02:01 iman kernel: [  502.506512] Modules linked in: DDriver(OE+) Driver(OE) xt_CHECKSUM iptable_mangle ipt_MASQUERADE nf_nat_masquerade_ipv4 iptable_nat nf_nat_ipv4 nf_nat libcrc32c nf_conntrack_ipv4 nf_defrag_ipv4 xt_conntrack nf_conntrack ipt_REJECT nf_reject_ipv4 xt_tcpudp bridge stp llc ebtable_filter ebtables ip6table_filter ip6_tables iptable_filter ip_tables x_tables snd_hda_codec_hdmi eeepc_wmi asus_wmi sparse_keymap intel_rapl x86_pkg_temp_thermal intel_powerclamp coretemp crct10dif_pclmul crc32_pclmul ghash_clmulni_intel cryptd intel_cstate intel_rapl_perf joydev input_leds snd_seq_midi snd_seq_midi_event snd_hda_codec_realtek snd_hda_codec_generic snd_rawmidi snd_hda_intel snd_hda_codec lpc_ich snd_seq snd_hda_core snd_hwdep snd_seq_device snd_pcm snd_timer snd soundcore mei_me shpchp mei mac_hid kvm binfmt_misc
Dec  5 12:02:01 iman kernel: [  502.506560]  irqbypass parport_pc ppdev lp parport autofs4 hid_cherry hid_generic usbhid hid nouveau mxm_wmi i2c_algo_bit ttm drm_kms_helper ahci syscopyarea libahci sysfillrect r8169 sysimgblt mii fb_sys_fops drm wmi fjes video [last unloaded: DDriver]
Dec  5 12:02:01 iman kernel: [  502.506584] CPU: 1 PID: 4240 Comm: insmod Tainted: G        W  OE   4.10.0-40-generic #44~16.04.1-Ubuntu
Dec  5 12:02:01 iman kernel: [  502.506585] Hardware name: ASUSTeK Computer INC. V-P8H67E/V-P8H67E, BIOS 1401 12/12/2011
Dec  5 12:02:01 iman kernel: [  502.506586] Call Trace:
Dec  5 12:02:01 iman kernel: [  502.506593]  dump_stack+0x63/0x90
Dec  5 12:02:01 iman kernel: [  502.506596]  __warn+0xcb/0xf0
Dec  5 12:02:01 iman kernel: [  502.506598]  warn_slowpath_fmt+0x5f/0x80
Dec  5 12:02:01 iman kernel: [  502.506602]  __free_irq+0xa4/0x290
Dec  5 12:02:01 iman kernel: [  502.506604]  free_irq+0x39/0x90
Dec  5 12:02:01 iman kernel: [  502.506607]  ? 0xffffffffc0183000
Dec  5 12:02:01 iman kernel: [  502.506611]  irq_ex_init+0x26/0x1000 [DDriver]
Dec  5 12:02:01 iman kernel: [  502.506614]  do_one_initcall+0x53/0x1c0
Dec  5 12:02:01 iman kernel: [  502.506619]  ? kmem_cache_alloc_trace+0x152/0x1c0
Dec  5 12:02:01 iman kernel: [  502.506624]  do_init_module+0x5f/0x1ff
Dec  5 12:02:01 iman kernel: [  502.506629]  load_module+0x1825/0x1bf0
Dec  5 12:02:01 iman kernel: [  502.506632]  ? __symbol_put+0x60/0x60
Dec  5 12:02:01 iman kernel: [  502.506636]  ? ima_post_read_file+0x7d/0xa0
Dec  5 12:02:01 iman kernel: [  502.506640]  ? security_kernel_post_read_file+0x6b/0x80
Dec  5 12:02:01 iman kernel: [  502.506644]  SYSC_finit_module+0xdf/0x110
Dec  5 12:02:01 iman kernel: [  502.506648]  SyS_finit_module+0xe/0x10
Dec  5 12:02:01 iman kernel: [  502.506652]  entry_SYSCALL_64_fastpath+0x1e/0xad
Dec  5 12:02:01 iman kernel: [  502.506655] RIP: 0033:0x7f0f6a2a3499
Dec  5 12:02:01 iman kernel: [  502.506656] RSP: 002b:00007fff1b8c96f8 EFLAGS: 00000202 ORIG_RAX: 0000000000000139
Dec  5 12:02:01 iman kernel: [  502.506659] RAX: ffffffffffffffda RBX: 00007f0f6a566b20 RCX: 00007f0f6a2a3499
Dec  5 12:02:01 iman kernel: [  502.506661] RDX: 0000000000000000 RSI: 000055649bd65246 RDI: 0000000000000003
Dec  5 12:02:01 iman kernel: [  502.506663] RBP: 0000000000001011 R08: 0000000000000000 R09: 00007f0f6a568ea0
Dec  5 12:02:01 iman kernel: [  502.506664] R10: 0000000000000003 R11: 0000000000000202 R12: 00007f0f6a566b78
Dec  5 12:02:01 iman kernel: [  502.506665] R13: 00007f0f6a566b78 R14: 000000000000270f R15: 00007f0f6a5671a8
Dec  5 12:02:01 iman kernel: [  502.506668] ---[ end trace 4b89a13407b08cea ]---

最佳答案

free_irq() 不应使用 NULL 调用,您应该传递在注册 IRQ 期间使用的唯一处理程序。

free_irq(1,(void*)(irq_handler));//在你的情况下

您不应该在 init 函数中释放 IRQ,free_irq() 应该在同一模块中调用 register_irq() 之后调用。

即使您在 init 函数中调用 free_irq(1,(void*)(irq_handler)); 内核也会受到污染,因为处理程序之前未注册。

您需要让内核知道您要删除哪个处理程序。

因为您不知道哪个模块已经注册了相同的 IRQ,所以逻辑是在您的模块中使用您已经在代码中实现的共享 IRQ。

简而言之,不要释放 init 函数中的 IRQ。

关于c - 键盘中断处理的 Linux 设备驱动程序错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47652391/

相关文章:

c - 为什么下面的代码不能正确扫描所有输入?

linux - Apache Spark 使用 Homebrew 软件从 1.5.2 升级到 1.6.0 导致执行期间出现权限被拒绝错误

ruby - Python 或 Ruby 用于 Linux 上的新应用程序?

linux-kernel - 创建简单的内核模块

c - 在 Lua 中与嵌套函数一起使用 C 变量

c - 如何有效地阻塞线程直到满足特定条件

c - 尽管RAW套接字和HDRINCL,IP源地址仍然由系统填充

linux - 如何创建具有权限的linux用户

c - 等待用户输入的进程实际上发生了什么?

c - 在 linux 内核中持有互斥量时 sleep