每个需要中断的 PCI 设备都带有一个固定的 PCI 中断,这个中断是无法更改的。它由插槽号和一个字母 A、B、C 或 D 指定。例如 3:B。但是,这个 PCI 中断通过主板上的一个芯片映射(路由或重定向)到一个中断号,比如 21。
这种路由是通过“可编程中断路由器”= PIR 完成的。或者,中断线也可以直接路由(无需任何 PIR)。如果存在 PIR(路由器),它可以由 BIOS 或 Linux 编程。因此,PCI 设备的中断有时可以被更改,不是通过在不同的导线上发送中断,而是通过编程 PIR 来更改该导线上脉冲的路由。当路由更改时,这种新路由提供的中断会被写入设备芯片中的一个配置寄存器。
在 PCI 总线之前,PC 使用的是 ISA 总线,然后在向较新的 PCI 总线过渡期间,大多数 PC 计算机同时使用了 PCI 和 ISA 总线。ISA 总线的所有中断线都连接到每张卡,因此任何卡都可以通过在不同的线路(不同的引脚)上发送其中断信号来更改其 irq 号。所有中断信号都被发送到中断控制器,然后中断控制器向 CPU 发出信号,暂时停止它正在做的事情,并运行驱动程序代码来处理中断。
当 PCI 首次出现时,简单的解决方案是将 PCI 中断映射到未使用的可用 ISA 中断。这需要使用“可编程中断路由器”= PIR(硬件)来完成这种映射。但是由于只有 15 个这样的中断,因此通常将许多 PCI 设备放在少数几个可用的中断上。解决这个问题很简单:提供新的硬件来增加中断的数量。结果就是 APIC。但它的普及速度很慢,因为 PCI 总线共享中断的能力缓解了中断短缺问题。因此,APIC 主要用于需要双处理器的场合。
它可以提供(取决于型号)16、24、32 或 64 个中断等。它还可以处理多个 CPU 情况下的中断从一个 CPU 到另一个 CPU 的路由。请参阅内核文档 i386 目录中的文件“IO-APIC”和 ACPI-HOWTO。不要将 APIC 与 ACPI(高级配置和电源接口)混淆,ACPI 可能被内核用来配置 APIC。
连接到中断线的实际 APIC 控制器是一个 I/O APIC(或 IO-APIC 或 IOAPIC)。通过使用多个 IO-APIC,可以获得更多的中断,并且它们的编号是唯一的。例如,第一个控制器可以有输入引脚 0-23,第二个控制器会将其输入引脚称为 24-47,从而产生 48 个编号为 0-47 的中断。但有些人发现他们有很高的中断号。会不会是第二个 IO-APIC 的起始基数高于它应有的基数,留下了一个很长的不存在的 irq 间隔?
除了 IO-APIC 之外,还有本地 APIC (LAPIC),它是每个 CPU 的一部分。IO-APIC 通过与 CPU 内部的 LAPIC 通信来完成其工作。
当 APIC 被引入时,旧的 ISA PIC 也被保留下来,让人们可以选择是否使用 APIC 或 ISA 的 PIC(有时在/proc/interrupts中简称为 PIC 或 XT-PIC;“XT”来自 IBM 在 1983 年推出的第二款 PC 型号 XT PC)。可以告诉内核(在内核命令行上)不要使用 APIC,在这种情况下,如果 XT-PIC 可用,它将使用旧的 XT-PIC。但是,由于 APIC 可以比 XT-PIC 提供的 15 个中断拥有更多的中断,可能会出现问题 ??
要查看您是否有 PIC 或 APIC,请查看/proc/interrupts。如果您只看到 irq 2 的 XT-PIC,但其他中断的 IO-APIC,这可能意味着您有旧的 XT-PIC,但目前未使用。嗯,irq 2 可用于两个旧的 XT-PIC 之间的通信,以防万一您在禁用 APIC 时可能需要使用它们。有两个 XT-PIC,因为每个只支持 8 个中断。
另一项发展是消息信号中断 (MSI),其中中断只是通过主计算机总线发送到特殊地址的消息(不需要中断线)。但是,发送此类消息的设备必须首先获得对主总线的控制权,以便它可以发送中断消息。这样的消息包含的信息比仅仅“我正在发送中断”更多。它包含一个索引,用于需要运行以服务 IRQ 的程序的地址。该索引(例如 3)意味着 cpu 在 cpu 知道的特殊表的第 3 个元素中找到它必须跳转到的地址。
由于卡必须支持 MSI,而许多卡不支持,因此传统的硬件中断支持方法(称为 INTx)似乎将长期存在。
PCI 中断可以共享,这意味着两个或多个 PCI 设备将生成相同的 IRQ。如果可行,通常最好不要共享。共享对于以下情况无法正常工作:1. 非常旧的 PCI 硬件(1995 年之前 ??)2. 有缺陷的 PCI 硬件,可能存在出厂缺陷(它是那样制造的)。例如,如果 IRQ9 上的 PCI 设备错误地声称任何 IRQ9 都是为它准备的,那么使用 IRQ9 的其他设备最终可能会忽略它们发出的所有 IRQ,因为坏设备错误地声称了它们的 IRQ。在没有共享的情况下,可以避免这个问题。
有关在两个 PCI 设备之间共享相同 IRQ 的示例,请参阅 PCI 中断共享 这种共享能力内置于硬件中,所有设备驱动程序都应该支持它。请注意,您通常不能在 PCI 和 ISA 总线之间共享相同的中断。
启动时消息提供了一些信息,可以通过键入 dmesg 查看。以下查看表格的方法涉及您可能没有(或尚不存在)的软件。要检查 PCI 路由到 16 个 ISA 中断的路由,请使用 pirtool,它显示了 $PIR 路由表。如果您有带硬连线路由的 APIC(没有 PIR),请使用 mptable 查看 MP 表。对于可路由的 APIC,可以通过 ACPI _PRT 方法访问表(但是是否有命令行命令来执行此操作?)
关于中断的详细技术信息请访问 FreeBSD 下 x86 机器的 PCI 中断。微软有 在单处理器 PC 上实现基于 APIC 的中断子系统的重要性
以下是 PCI 中断系统的一些细节。每张 PCI 卡(和安装在主板上的设备)都有 4 个可能的中断:INTA#、INTB#、INTC#、INTD#。从现在开始,我们将它们简称为 A、B、C 和 D。每个中断在 PCI 卡的边缘连接器上都有自己的引脚。因此,对于一个 7 插槽系统(对于 7 张卡),这些卡可能有 7 x 4 = 28 条不同的中断线。内置于主板的设备也有额外的中断。但是规范允许更少数量的中断线,因此一些 PCI 总线似乎只制造了 4 或 8 条中断线。这并不是太严格的限制,因为中断可以共享。对于 4 条中断线(导线、迹线或链接)LNKA、LNKB、LNKC、LNKD,有一个可编程的“中断路由器”芯片,它将 LNKA、LNKB、LNKC、LNKD 路由到选定的 IRQ。这种路由可以由 BIOS 或 Linux 更改。例如,LNKA 可以路由到 IRQ5。假设我们将来自插槽 3 的 B 中断指定为中断 3B。那么中断 3B 和 2A 都可以永久连接到路由到 IRQ5 的 LNKA。这两个中断:3B 和 2A 通过主板上的硬连线永久共享。
可以在命令行上键入“dmesg”来查看中断线(如 LNKA)如何路由(或链接)到 IRQ(*5 表示它链接到 IRQ 5)。查找“PCI Interrupt Link”。请注意,“link”在这里使用了两个含义:1. PCI 中断线到 IRQ 的链接(路由)。2. 中断线的标签,例如 LNKB(链接 B)。中断线标签似乎是由 Bios 提供的 ?? 它们可能有许多不同的名称,例如:LNKC、LNK2、APCF、LUBA、LIDE 等。问题:当大量中断线显示为禁用时,它们是否都物理存在于主板上?还是它们只存在于 ACPI BIOS 软件中,以便 BIOS 可以与具有更多中断线的主板一起工作?
将这些线从 PCI 设备(例如 3B)连接到中断 LNKA 等的一种简单方法是将所有 A 中断 (INTA#) 连接到线 LNKA,将所有 B 中断连接到 LNKB,等等。这种方法多年前曾使用过,但这不是一个好的解决方案。原因如下。如果一张卡只需要一个中断,则必须使用 A。如果它需要两个中断,则必须同时使用 A 和 B,等等。因此,INTA# 的使用频率远高于 INTD#。因此,最终会导致过多的中断共享第一条线(LNKA 连接到所有 INTA#)。为了克服这个问题,可以以更随机的方式连接它们,以便 4 条中断线(LNKA、LNKB、LNKC、LNKD)中的每一条都共享大致相同数量的实际 PCI 中断。
一种实现此目的的方法是让导线 LNKA 共享中断 1A、2B、3C、4D、5A、6B、7C。这是通过物理连接导线 W 到导线 1A、2B 等来完成的。同样,导线 LNKB 可以连接到导线 1B、2C、3D、4A、5B、6C、7D 等。然后在启动时,BIOS 将 LNKB、LNKA、LNKC、LNKD 映射到 IRQ。之后,它将每个设备使用的 IRQ 写入每个设备中的硬件配置寄存器。从那时起,任何查询此寄存器的程序都可以找出设备使用的 IRQ。请注意,仅仅将 IRQ 写入 PCI 卡上的寄存器并不会以任何方式为该设备设置 IRQ。
此信息的实际用途是,作为最后的手段,可以通过将 PCI 卡插入不同的插槽来更改 PCI 卡的 IRQ。在上面的示例中,如果将 PCI 卡插入插槽 1(1A 映射到 LNKA),则 PCI 卡的 INTA# 将连接到导线 LNKA,但当插入插槽 4(4A 映射到 LNKB)时,INTA# 将连接到导线 LNKB。
插槽中的卡最多可以有 8 个设备,但它只有 4 个 PCI 中断(A、B、C、D)。这是可以的,因为中断可以共享,因此 8 个设备中的每一个(如果它们存在)都可以有一个共享的中断。设备的 PCI 中断字母通常是固定的,并硬连线到设备中。中断的分配由 BIOS 或 Linux 将 PCI 中断映射到如上所述的类似 ISA 的中断来完成。
如果只有 4 条线(LNKA、LNKB、LNKC 和 LNKD),如上面的示例所示,则 PCI BIOS 的映射选择是有限的。一些主板可能会使用更多的线,因此有更多的选择。例如 LNKA-LNKH(8 条线)。启动时消息(和 dmesg)可能会显示它们以及它们的映射方式。BIOS 知道它们是如何接线的。
在 PCI 总线上,BIOS(或 Linux)分配 IRQ(中断)以避免与它知道的 ISA 总线上的 IRQ 冲突。有时 CMOS BIOS 菜单可能允许您将 IRQ 分配给 PCI 卡,或告诉 BIOS 哪些 IRQ 要为 ISA 设备保留。这些分配被称为“路由表”。在 MS Windows 中,它被称为“IRQ 转向”,但这也涵盖了启动后动态 IRQ 路由的情况。BIOS 可能支持它自己的 IRQ 转向。
如果您的 PC 使用映射到 ISA 中断的 PCI 中断,您可能会认为中断可能会很慢,因为 ISA 总线很慢。并非如此。ISA 中断控制器芯片有直接连接到 CPU 的中断线,因此它可以立即获得关注。虽然旧 ISA 地址和数据总线上的信号到达 CPU 的速度很慢,但 IRQ 中断信号到达 CPU 的速度非常快。