在mainbord上,我们有一个中断 Controller (IRC),它充当可引发中断的设备与CPU之间的多路复用器:

                             |--------|
          |-----------|      |        |
-(0)------| IRC  _____|______| CPU    |
-(...)----| ____/     |      |        |
-(15)-----|/          |      |--------|
          |-----------|

每个设备都与一个IRQ(左侧的数字)相关联。每次执行后,CPU都会检测到中断请求行。如果检测到信号,则将执行状态保存,CPU将加载一个中断处理程序例程,该例程可以在位于内存中固定地址的中断 vector 中找到。据我所知,IRQ的编号和中断 vector 中的 vector 编号是不相同的,因为例如我的网卡已注册到IRQ8。在Intel Pentium处理器上,这将指向所使用的例程来指示一个错误情况,因此必须在某处指向正确的处理程序的映射。

问题:

1)如果我编写一个设备驱动程序并为其注册一个IRQX。系统从哪里知道应该处理哪个设备?例如,我可以使用带有IRQ编号10的request_irq(),但系统如何知道应将处理程序用于鼠标或键盘或任何我编写的驱动程序?

2)那么中断 vector 看起来如何?我的意思是,如果我将IRQ 10用于我的设备,这将覆盖表中用于错误处理的标准处理程序(根据Silberschatz(操作系统概念),第一个可用的处理程序是32)。

3)谁来设置IRQ? BIOS?操作系统?

4)谁负责中断 vector 的IRQ和偏移量的匹配?

5)可以共享IRQS。那怎么可能?主板上有将设备连接到中断 Controller 的硬件通道。通道如何配置为相同的中断?必须有一张表说明2号和3号车道处理IRQ15,例如该表位于何处,如何调用?

最佳答案

关于linux内核的答案。应该也适用于大多数其他操作系统。

1)如果我编写一个设备驱动程序并为其注册一个IRQX。系统从哪里知道应该处理哪个设备?例如,我可以使用带有IRQ编号10的request_irq(),但系统如何知道应将处理程序用于鼠标或键盘或任何我编写的驱动程序?

没有1个答案。例如,如果这是一个定制的嵌入式系统,则硬件设计人员将告诉驱动程序编写者“我将设备x路由到irq y”。为了获得更大的灵活性,例如,通常使用PCI协议(protocol)的网卡。有硬件/固件级别的仲裁,可在检测到新设备时为新设备分配一个irq号。然后将其写入PCI配置寄存器之一。驱动程序首先读取该设备寄存器,然后为该特定irq注册其中断处理程序。其他协议(protocol)也将有类似的机制。

您可以做的是在内核代码中查找对request_irq的调用,以及驱动程序如何获得irq值。对于每种驱动程序,它都会有所不同。

因此,该问题的答案是系统不知道。硬件设计者或硬件协议(protocol)将此信息提供给驱动程序编写器。然后,驱动程序编写者为该特定irq注册处理程序,并告诉系统在看到该irq时该怎么做。

2)那么中断 vector 看起来如何?我的意思是,如果我将IRQ 10用于我的设备,这将覆盖表中用于错误处理的标准处理程序(根据Silberschatz(操作系统概念),第一个可用的处理程序是32)。

好问题。它有两个部分。

a)当您request_irq(irq,handler)。系统实际上没有在IVT或IDT中编程条目0。但是条目N + irq。其中N是该CPU支持的错误处理程序或通用异常的数量。细节因系统而异。

b)如果您错误地请求另一个驱动程序使用的irq,会发生什么情况。您收到错误,并且您的处理程序未编程IDT。

注意:IDT是中断描述符表。

3)谁来设置IRQ? BIOS?操作系统?

首先是BIOS,然后是OS。但是,某些操作系统(例如MS-DOS)不会对BIOS设置的IVT进行重新编程。诸如Windows或Linux之类的更复杂的现代OS不想依赖特定的bios功能,因此他们对IDT进行了重新编程。但是BIOS最初必须这样做,然后OS才能出现。

4)谁负责中断 vector 的IRQ和偏移量的匹配?

我真的不清楚你的意思。流程是这样的。首先为您的设备分配一个irq编号,然后使用该irq编号为其注册一个处理程序。如果使用错误的irq编号,然后在设备上启用中断,则系统将崩溃。因为处理程序是错误的irq号注册的。

5)可以共享IRQS。那怎么可能?主板上有将设备连接到中断 Controller 的硬件通道。通道如何配置为相同的中断?必须有一张表说明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";
           }
      }

关于linux - 中断处理(Linux/常规),我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/10869549/

10-13 05:52