Sen*_*Sen 41 linux kernel interrupt
我只知道这Interrupt是hardware signal assertion处理器引脚造成的。但我想知道 Linux 操作系统如何处理它。
发生中断时发生的所有事情是什么?
Gil*_*il' 45
这是低级处理的高级视图。我正在描述一个简单的典型架构,真实的架构可能更复杂,或者在这种细节级别无关紧要的方式上有所不同。
当中断发生时,处理器查看中断是否被屏蔽。如果是,则在它们被揭开之前什么也不会发生。当中断被取消屏蔽时,如果有任何挂起的中断,处理器就会选择一个。
然后处理器通过跳转到内存中的特定地址来执行中断。该地址处的代码称为中断处理程序。当处理器在那里分支时,它会屏蔽中断(因此中断处理程序具有独占控制权)并将某些寄存器的内容保存在某个地方(通常是其他寄存器)。
中断处理程序做它必须做的事情,通常是通过与触发中断的外设通信来发送或接收数据。如果中断是由计时器引发的,则处理程序可能会触发 OS 调度程序,以切换到不同的线程。当处理程序完成执行时,它会执行一条特殊的中断返回指令,该指令恢复保存的寄存器并取消屏蔽中断。
中断处理程序必须快速运行,因为它会阻止任何其他中断运行。在Linux内核中,中断处理分为两部分:
像往常一样,有关此主题的更多信息,请阅读Linux 设备驱动程序;第 10 章是关于中断的。
wag*_*wag 25
Gilles 已经描述了中断的一般情况,以下特别适用于 Intel 架构上的 Linux 2.6(其中一部分也基于 Intel 的规范)。
中断是改变处理器执行指令顺序的事件。
有两种不同类型的中断:
异常是由必须由内核处理的编程错误(fe Divide error , Page Fault , Overflow)引起的。他向程序发送信号并尝试从错误中恢复。
对以下两种例外情况进行分类:
中断可由 I/O 设备(键盘、网络适配器等)、间隔计时器和(在多处理器系统上)其他 CPU 发出。当中断发生时,CPU 必须停止其当前指令并执行新到达的中断。他需要保存旧的中断进程状态以(可能)在中断处理后恢复它。
处理中断是一项敏感任务:
定义了两种不同的中断级别:
每个硬件设备都有自己的中断请求 (IRQ) 线。IRQ 从 0 开始编号。所有 IRQ 线都连接到可编程中断控制器 (PIC)。PIC 侦听 IRQ 并将它们分配给 CPU。也可以禁用特定的 IRQ 线。
现代多处理 Linux 系统通常包括更新的 Advanced PIC (APIC),它在 CPU 之间平均分配 IRQ 请求。
中断或异常与其处理之间的中间步骤是中断描述符表 (IDT)。该表将每个中断或异常向量(一个数字)与指定的处理程序(fe Divide error由函数处理divide_error())相关联。
通过 IDT,内核确切地知道如何处理发生的中断或异常。
那么,当中断发生时内核会做什么呢?
小智 8
首先参与中断处理的参与者是外围硬件设备、中断控制器、CPU、操作系统内核和驱动程序。外围硬件设备负责产生中断。当它们需要操作系统内核的注意时,它们会断言中断请求线。这些信号由负责中断信号采集的中断控制器复用。它还负责确定将中断信号传递给 CPU 的顺序。中断控制器能够暂时禁用特定的中断请求线 (IRQL) 并重新启用它(IRQL 屏蔽)。中断控制器将收集到的中断请求依次传递给 CPU。CPU 执行完每条指令后,CPU 会检查是否有来自中断控制器的等待中断请求。如果 CPU 发现有等待请求并且在 CPU 内部控制寄存器中设置了中断使能标志,则 CPU 开始中断处理。如您所见,Linux 内核通过对 CPU 中中断标志的操作以及与中断控制器的通信来控制中断接受。例如,Linux 可以禁止接受来自特定设备的中断或完全禁止中断接受。Linux 内核能够控制中断接受。例如,Linux 可以禁止接受来自特定设备的中断或完全禁止中断接受。Linux 内核能够控制中断接受。例如,Linux 可以禁止接受来自特定设备的中断或完全禁止中断接受。
当处理器收到中断请求时会发生什么?首先,CPU 通过重置中断标志来自动禁用中断。一旦中断处理完成,它们将被重新启用。同时,CPU 将 CPU 从用户模式切换到内核模式所需的工作量最小,从而允许它恢复执行被中断的代码。CPU 咨询由 Linux 内核填充的特殊 CPU 控制结构,以找到将控制传递到的代码地址。这个地址是中断处理程序的第一条指令的地址,它是Linux内核的一部分。
作为中断处理的第一步,内核识别接收到的中断向量,以识别系统中发生了什么样的事件。中断向量定义了 Linux 将采取什么行动来处理它。第二步,Linux 保存其余的 CPU 寄存器(CPU 不会自动保存这些寄存器),这些寄存器可能会被中断的程序使用。这是非常重要的操作,因为它允许 Linux 透明地处理被中断的程序的中断。第三步,Linux通过设置内核环境和设置它所需的CPU状态,完成向内核模式的切换。最后,调用向量相关中断处理程序。(您可以查看 arch\x86\kernel\entry_32 中的 BUILD_INTERRUPT3 宏。S 获取 x86 架构相关示例的其他详细信息)在外围设备的情况下,这是一个 do_IRQ() 例程。(查看arch\x86\kernel\irq.c)
依赖向量的中断处理程序通常通过调用 irq_enter() 和 irq_exit() 来包装。包含在这些函数对中的代码区域对于任何其他此类区域是原子的,并且对于 cli/sti 对也是原子的。Irq_enter() 和 irq_exit() 还捕获一些与中断处理相关的统计信息。最后,内核查看 vector_irq 表以找到分配给接收到的中断向量的 irq 编号并调用 handle_irq()(来自 arch\x86\kernel\irq_32.c)。
至此,Linux 中中断处理的公共部分结束,因为内核将设备驱动程序安装的设备相关中断处理程序例程视为 irq 描述符的一部分并调用它。如果驱动程序没有安装这样的处理程序,内核只是在中断控制器上确认中断并退出通用中断处理程序。
中断处理内核在中断处理结束后恢复先前中断的程序的状态并恢复该程序的执行。
| 归档时间: |
|
| 查看次数: |
92213 次 |
| 最近记录: |