Ste*_*fan 8 interrupt linux-kernel
我正在尝试使用较旧的 PC(HP Pavilion Elite m9660de)启动/安装 Linux 以进行学习。以下消息是启动时显示的第一件事(Ubuntu 和 Fedora,都来自可启动的 USB 记忆棒和全新安装):
do_IRQ:1.55 没有向量的 irq 处理程序
do_IRQ:2.55 没有向量的 irq 处理程序
do_IRQ: 3.55 没有向量的 irq 处理程序
引导过程将在那里停滞很长时间(如 15 分钟),并最终继续。
我不是要求获得对这个具体问题的支持,而是要了解如何解释这样的消息。
我在 do_IRQ 的内核代码中发现 55 是一个向量。据我了解,这或多或少是一个中断的数量,对应于包含中断处理程序地址的内存位置。
我原以为这些数字与导致中断的事件之间存在固定的对应关系。我在哪里可以找到这方面的文档?这是特定于 Linux、特定于处理器还是特定于主板?
do_IRQ:1.55 没有向量的 irq 处理程序
这个消息可以在 Linux 内核源文件中找到arch/x86/kernel/irq.c,所以它是关于 x86 特定的中断处理。
/*
* do_IRQ handles all normal device IRQ's (the special
* SMP cross-CPU interrupts have their own specific
* handlers).
*/
__visible unsigned int __irq_entry do_IRQ(struct pt_regs *regs)
{
struct pt_regs *old_regs = set_irq_regs(regs);
struct irq_desc * desc;
/* high bit used in ret_from_ code */
unsigned vector = ~regs->orig_ax;
entering_irq();
/* entering_irq() tells RCU that we're not quiescent. Check it. */
RCU_LOCKDEP_WARN(!rcu_is_watching(), "IRQ failed to wake up RCU");
desc = __this_cpu_read(vector_irq[vector]);
if (!handle_irq(desc, regs)) {
ack_APIC_irq();
if (desc != VECTOR_RETRIGGERED && desc != VECTOR_SHUTDOWN) {
pr_emerg_ratelimited("%s: %d.%d No irq handler for vector\n",
__func__, smp_processor_id(),
vector);
} else {
__this_cpu_write(vector_irq[vector], VECTOR_UNUSED);
}
}
exiting_irq();
set_irq_regs(old_regs);
return 1;
}
Run Code Online (Sandbox Code Playgroud)
因此,第一个数字(点之前)是报告处理器的 ID,而 55 是您发现的中断向量。如果 IRQ 向量处于VECTOR_SHUTDOWN或状态,则可以避免该消息VECTOR_RETRIGGERED。
根据arch/x86/kernel/apic/vector.c状态VECTOR_SHUTDOWN指示有意清除的中断向量(例如,硬件设备被停止并且其驱动程序以受控方式卸载)。
的VECTOR_RETRIGGERED是在设置fixup_irqs()在的端部arch/x86/kernel/irq.c,似乎是与CPU热插拔,或者更具体地标记以CPU为离线。
因此,在启动时,这两种状态都不应该适用于普通 PC。
您关于中断向量编号和中断原因之间的固定对应关系的想法对于原始 IBM PC 的 ISA 总线体系结构是有效的……而且在那之后的很长一段时间里。
但是在 486 处理器和第一个奔腾时代的某个地方,引入了 APIC(高级可编程中断控制器)。它是使多个处理器能够在 PC 架构中共存的组件之一。它开辟了将可用硬件中断线的数量从 15 个(如第一台 IBM PC-AT 中的 8259 个中断控制器对)增加到最终 224 个离散硬件中断的途径。这使设计更复杂的系统成为可能,也有助于使真正的自动配置总线成为可能。
本质上,系统固件或操作系统应该将总线上的设备配置为使用特定的中断线,然后对 APIC 进行编程以将中断信号路由到 CPU 中的可用中断向量。这需要了解总线实际上是如何连接到主板上的,因此实际上这几乎完全由系统固件完成,并且许多例外都是专门用于修补固件错误。
PCI 总线最初将其中断映射到 ISA 样式的中断,但是当 APIC 集成到 CPU 中时,可以消除此限制,减少 IRQ 延迟并允许构建更复杂的系统。在 PCI 总线 2.2 版中,引入了消息信号中断 (MSI),它允许在没有专用物理中断线的情况下进行离散硬件中断。在 PCI Express 中,MSI 成为处理中断的标准方式。
所以...看起来您的系统硬件包括路由到 IRQ 向量 55 的活动中断源,但 Linux 当前没有加载驱动程序来处理它。由于 PCI 配置空间以标准方式可读并且 Linux 确实读取它,因此应该检测、识别 PCI 总线(或 PCIe 链接)上的任何设备,并且应该知道它们的中断配置。
也可能是 IRQ 的来源不是 PCI 设备,即平台设备,例如是系统芯片组的一部分或使用某些非 PCI 兼容接口连接到它们的东西。所有这些设备都应该由固件 ACPI 表来描述......但显然在你的情况下,这些 IRQ 的来源不是。
我的结论是这可能是固件错误:查看 HP 是否为您的系统提供 BIOS 更新。(此时,HP 的 Pavilion Elite m9660de 支持下载页面似乎无法为我加载。)
根据Ubuntu 论坛中的这个帖子,它也可能是 VIA 芯片组中的硬件错误:如果您的系统有这个芯片组,pci=nomsi,noaer在 GRUB 中添加引导选项可能会修复它。
如果您当前的内核debugfs支持并启用了 CONFIG_GENERIC_IRQ_DEBUGFS 内核选项,您可能会以 root 身份使用以下命令获得有关 IRQ 向量 55 状态的大量信息:
mount -t debugfs none /sys/kernel/debug
grep "Vector.*55" /sys/kernel/debug/irq/irqs/*
Run Code Online (Sandbox Code Playgroud)
这应该会告诉您该目录中的哪些文件提到了“Vector: 55”。阅读这些文件应该可以告诉你内核知道的关于中断向量的所有信息。