使用嵌入式asm向内核模块中引发中断11时出错

问题描述 投票:0回答:1

我正在尝试在内核模块LKM中使用内联asm引发中断11

asm("int $0x3B");

但是在这一行之后,我读了dmesg

do_IRQ: 1.59 No irq handler for vector

这是我从网站https://embetronicx.com/tutorials/linux/device-drivers/linux-device-driver-tutorial-part-13-interrupt-example-program-in-linux-kernel/上获取的驱动程序代码当我尝试执行“ cat / dev / etx_device”时,我是通过dmesg获得的

do_IRQ: 1.59 No irq handler for vector

我的内核版本是5.1.20-200.fc29.x86_64 AMD处理器。有什么问题吗?

  cat /proc/interrupts: 
      CPU0       CPU1       
  0:        110          0   IO-APIC   2-edge      timer
  8:          1          0   IO-APIC   8-edge      rtc0
  9:          0          0   IO-APIC   9-fasteoi   acpi
 11:          0          0   IO-APIC  11-edge      etx_device
c assembly linux-kernel interrupt kernel-module
1个回答
1
投票

这曾经在较旧的内核版本上起作用,但在较新的版本上失败。原因是已更改通用IRQ处理程序do_IRQ()以获得更好的IRQ处理性能。它不使用irq_to_desc()函数获取IRQ描述符,而是从每个CPU的数据中读取它。描述符在物理设备初始化期间放置在那里。由于此伪设备驱动程序没有物理设备,因此do_IRQ()找不到该设备,并返回错误。如果要使用软件中断来模拟IRQ,则必须首先将IRQ描述符写入每个CPU数据。不幸的是,在内核编译期间,没有将符号vector_irq(每个CPU数据中的IRQ描述符的数组)导出到内核模块。更改它的唯一方法是重新编译整个内核。如果您认为值得努力,可以添加以下行:

EXPORT_SYMBOL (vector_irq);

在文件中:arch/x86/kernel/irq.c

在所有包含行之后。从新编译的内核编译并引导后,按如下所示更改驱动程序:

添加包含行:

    #include <asm/hw_irq.h>

将读取功能更改为:

static ssize_t etx_read(struct file *filp,
                char __user *buf, size_t len, loff_t *off)
{
        struct irq_desc *desc;

        printk(KERN_INFO "Read function\n");
        desc = irq_to_desc(11);
        if (!desc) return -EINVAL;
        __this_cpu_write(vector_irq[59], desc);
        asm("int $0x3B");  // Corresponding to irq 11
        return 0;
}
© www.soinside.com 2019 - 2024. All rights reserved.