繁体   English   中英

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

[英]Linux Device Driver Error for the Keyboard Interrupt Handling

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

#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)); //In your case

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

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

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

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

简而言之,不要在初始化函数中释放IRQ。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM