键盘中断处理的Linux设备驱动程序错误 [英] Linux Device Driver Error for the Keyboard Interrupt Handling

查看:170
本文介绍了键盘中断处理的Linux设备驱动程序错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

During the way to learn how to program the Keyboard interrupt handling in Kernel mode, and following the example below, I get such an error after loading the driver in kernel space.

#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.

The unloading also work fine, but after loading by insmod, I get such an error. I was wondering if somebody can explain it. I use 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 ]---

永远不要用NULL调用

推荐答案

free_irq(),您应该传递在注册IRQ时使用的唯一处理程序.

free_irq() should never be called with NULL, you should pass the unique handler that you have used during registering the IRQ.

free_irq(1,(void*)(irq_handler)); //In your case

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

You should not free the IRQ in init function, free_irq() should be called after register_irq() call has been made in the same module.

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

Even if you call free_irq(1,(void*)(irq_handler)); in init function the kernel will taint as the handler was not previously registered.

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

You need to let the kernel know which handler you want to remove.

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

As you don't know which module has already registered the same IRQ so the logic is to use a shared IRQ in your module which you have already implemented in your code.

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

In short, do not free the IRQ in init function.

这篇关于键盘中断处理的Linux设备驱动程序错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆