5

我正在使用 Linux 3.6.0 开发 x86 系统。对于一些实验,我需要知道 IRQ 是如何映射到向量的。我从很多书中了解到,向量 0x0 到 0x20 用于陷阱和异常,然后从向量 0x20 开始用于外部设备中断。而这也在源代码Linux/arch/x86/include/asm/irq_vectors.h中定义

但是,我感到困惑的是,当我检查 do_IRQ 函数时, http ://lxr.linux.no/linux+v3.6/arch/x86/kernel/irq.c#L181 我发现 IRQ 是由查找“vector_irq”数组:

unsigned int __irq_entry do_IRQ(struct pt_regs *regs)
{
    struct pt_regs *old_regs = set_irq_regs(regs);
    /* high bit used in ret_from_ code  */
    unsigned vector = ~regs->orig_ax;
    unsigned irq;
    ...
    irq = __this_cpu_read(vector_irq[vector]); // get the IRQ from the vector_irq
    // print out the vector_irq
    prink("CPU-ID:%d, vector: 0x%x  - irq: %d", smp_processor_id(), vector, irq); 
}

通过使用 printk 检测代码,我得到的向量-irq 映射如下所示,我不知道为什么这是映射。我虽然映射应该是(irq + 0x20 = vector),但似乎不是这样。

from: Linux/arch/x86/include/asm/irq_vector.h
*  Vectors   0 ...  31 : system traps and exceptions - hardcoded events
*  Vectors  32 ... 127 : device interrupts = 0x20 – 0x7F

但我的输出是:

CPU-ID=0.Vector=0x56 (irq=58)
CPU-ID=0.Vector=0x66 (irq=59)
CPU-ID=0.Vector=0x76 (irq=60)
CPU-ID=0.Vector=0x86 (irq=61)
CPU-ID=0.Vector=0x96 (irq=62)
CPU-ID=0.Vector=0xa6 (irq=63)
CPU-ID=0.Vector=0xb6 (irq=64)

顺便说一句,这些 irq 是我启用了 MSIX 的 10GB 以太网卡。谁能给我一些关于为什么这是映射的想法?制作这种映射的规则是什么?

谢谢。威廉

4

2 回答 2

2

irq 编号(这是您在软件中使用的)与向量编号(这是中断控制器实际使用的)不同。

x86 I/OAPIC 中断控制器以 16 个为一组分配中断优先级,因此向量编号被隔开以防止它们相互干扰(参见 arch/x86/kernel/apic/io_apic.c 中的__assign_irq_vector函数

于 2013-09-24T07:02:49.333 回答
2

我想我的问题是如何为特定的 IRQ 编号分配向量以及背后的规则是什么。

IOAPIC 为每个 IRQ 输入支持一个名为 IOREDTBL 的寄存器。软件使用该寄存器的位 7-0 为 IRQ 输入分配所需的向量编号。正是这个向量号用作处理器中断描述符表的索引。引用 IOAPIC 手册 (82093AA)

7:0 中断向量 (INTVEC)—R/W:向量字段是一个 8 位字段,包含此中断的中断向量。矢量值范围从 10h 到 FEh。

请注意,软件不能直接访问这些寄存器。要访问 IOAPIC 寄存器(不要与本地 APIC 寄存器混淆),软件必须使用 IOREGSEL 和 IOWIN 寄存器来间接与 IOAPIC 交互。这些寄存器也在 IOAPIC 手册中有所描述。

IOAPIC 的源信息可能有点难以挖掘。这是我使用的示例的链接: IOAPIC 数据表链接

于 2013-09-24T20:51:06.010 回答