关于linux内核的答案。也应该适用于大多数其他操作系统。
1) 如果我编写一个设备驱动程序并为其注册一个 IRQ X。系统从哪里知道应该处理哪个设备?例如,我可以将 request_irq() 与 IRQ 编号 10 一起使用,但系统如何知道处理程序应该用于鼠标或键盘或我编写的驱动程序?
没有 1 个答案。例如,如果这是一个定制的嵌入式系统,硬件设计人员会告诉驱动程序编写者“我要将设备 x 路由到 irq y”。为了获得更大的灵活性,例如对于通常使用 PCI 协议的网卡。当检测到新设备时,有硬件/固件级别的仲裁将中断号分配给新设备。然后这将被写入 PCI 配置寄存器之一。驱动程序首先读取此设备寄存器,然后为该特定 irq 注册其中断处理程序。其他协议也会有类似的机制。
您可以做的是在内核代码中查找对 request_irq 的调用以及驱动程序如何获取 irq 值。每种驱动程序都会有所不同。
因此,这个问题的答案是,系统不知道。硬件设计者或硬件协议将此信息提供给驱动程序编写者。然后驱动程序编写者为那个特定的 irq 注册处理程序,告诉系统在你看到那个 irq 的情况下要做什么。
2)那么中断向量看起来如何?我的意思是,如果我将 IRQ 10 用于我的设备,这将覆盖用于表中错误处理的标准处理程序(根据 Silberschatz(操作系统概念),第一个可用的处理程序是 32)。
好问题。它有两个部分。
a) 当你 request_irq (irq,handler) 时。系统确实没有在 IVT 或 IDT 中编写条目 0。但是入口 N + irq。其中 N 是该 CPU 上支持的错误处理程序或通用异常的数量。细节因系统而异。
b) 如果您错误地请求另一个驱动程序使用的 irq,会发生什么情况。您收到一个错误,并且 IDT 未使用您的处理程序进行编程。
注意:IDT 是中断描述符表。
3) 谁最初设置了 IRQ?生物?操作系统?
首先是bios,然后是操作系统。但是有某些操作系统,例如 MS-DOS,它不会对 BIOS 设置的 IVT 进行重新编程。更复杂的现代操作系统,如 Windows 或 Linux,不想依赖特定的 bios 功能,他们重新编程 IDT。但是只有在操作系统出现时,bios 才必须首先执行此操作。
4)谁负责IRQ和中断向量中的偏移量的匹配?
我真的不清楚你的意思。流程是这样的。首先,您的设备被分配了一个中断号,然后您使用该中断号为它注册一个处理程序。如果您使用错误的 irq 号,然后在您的设备上启用中断,系统将崩溃。因为处理程序是从错误的 irq 号注册的。
5) 可以共享 IRQS。这怎么可能?主板上有硬件通道将设备连接到中断控制器。如何将通道配置为相同的中断?必须有一个表,上面写着第 2 和第 3 通道处理 IRQ15,例如这个表在哪里以及它是如何被调用的?
这个问题问得好。额外的表不是它在内核中的解决方式。而对于每个共享 irq,处理程序都保存在函数指针的链接列表中。内核循环遍历所有处理程序并一个接一个地调用它们,直到其中一个处理程序将中断声明为自己的。
The code looks like this:
driver1:
d1_int_handler:
if (device_interrupted()) <------------- This reads the hardware
{
do_interrupt_handling();
return MY_INTERRUPT;
}else {
return NOT_MY_INTERRUPT;
}
driver2:
Similar to driver 1
kernel:
do_irq(irq n)
{
if (shared_irq(n))
{
irq_chain = get_chain(n);
while(irq_chain)
{
if ((ret = irq_chain->handler()) == MY_INTERRUPT)
break;
irq_chain = irq_chain->next;
}
if (ret != MY_INTERRUPT)
error "None of the drivers accepted the interrupt";
}
}