LinuxKernel核心中文手册(7)[1]

[入库:2005年9月19日] [更新:2007年3月24日]

本文简介:


  Interrupts and Interrupt Handling (中断和中断处理)
  
    本章探讨 Linux 核心如何处理中断。虽然核心有用于处理中断的通用机制和接口,大部分中断处理的细节还是和体系结构相关的。
  
    Linux 使用大量不同的硬件来完成许多不同的任务。显示设备驱动显示器, IDE 设备驱动磁盘等等。你可以同步地驱动这些设备,就是你可以发出一个请求执行一些操作(比如把一块内存写到磁盘)然后等待操作结束。这种方式,虽然可以工作,但是非常没有效率,操作系统当它等待每一个操作完成的时候会花费大量时间“忙于什么也不做”( busy doing nothing )。一个好的,更有效的方法是做出了请求然后去作其他更有用的事情,然后当设备完成请求的时候被设备中断。在这种方案下,系统中同一时刻可能有许多设备的请求在同时发生。
  
    让设备中断 CPU 当前的工作必须有一些硬件的支持。大多数,如果不是所有的话,通用目的的处理器比如 Alpha AXP 都使用相似的方法。 CPU 的一些物理管脚的电路只要改变电压(例如从 +5V 到 -5V )就会让 CPU 停止正在做的工作,开始执行处理中断的特殊代码:中断处理代码。这些管脚之一可能连接一个内部适中,每一个 1000 分之一秒就接收一个中断,其他的也许连接到系统的其他设备,比如 SCSI 控制器。
  
    系统通常使用一个中断控制器把设备的中断集合在一起,然后把信号传送到 CPU 的一个单一的中断管脚。这可以节省 CPU 的中断管教,也给设计系统带来了灵活性。中断控制器有掩码和状态寄存器,用于控制这些中断。设置掩码寄存器的位可以允许和禁止中断,状态寄存器返回系统中当前的中断。
  
    一些系统中的中断可能是硬连接的,例如实时时钟的内部时钟可能永久地连接到中断控制器的第 3 管脚。但是,另一些管脚连接什么可能由在特定的 ISA 或者 PCI 槽位插入什么控制卡决定。例如,中断控制器的第 4 管脚可能和 PCI 槽位 0 相连,可能某一天有一个以太网卡,当时后来可能是一块 SCSI 控制卡。每一个系统都有它自己的中断中转机制,操作系统必须足够灵活才能处理。
  
    大多数现代的通用目的微处理器用相同的方式处理中断。发生硬件中断的时候, CPU 停止它正在运行的指令,跳到内存中一个位置运行,这里或者包含中断处理代码或者是跳到中断处理代码的指令。这种代码通常在 CPU 的特殊模式下工作:中断模式,通常,这种模式下其他中断不能产生。这里也有例外:一些 CPU 将中断划分级别,更高级别的中断可以发生。这意味着写第一级的中断处理程序必须非常小心。中断处理程序通常都有自己的堆栈,用来存放 CPU 的执行状态( CPU 所有的通用寄存器和上下文)并处理中断。一些 CPU 有一组只在中断模式下存在的寄存器,中断处理代码可以使用这些寄存器来存储它需要保存的大部分上下文信息。
  
   
  当处理完中断, CPU 的状态恢复,中断结束。 CPU 会继续做它在中断发生之前做的事情。重要的事中断处理程序必须尽可能地有效,通常操作系统不能经常或者长时间阻塞中断。
  
  7.1 Programmable Interrupt Controllers (可编程中断控制器)
  
    系统设计师可以任意使用他们希望用的中断体系结构,但是 IBM PC 都使用 Intel 82C59A-2 CMOS 可编程中断控制器或者它的衍生物。这种控制器在 PC 最初的时候就使用了。它可通过寄存器编程,这些寄存器在 ISA 地址空间的众所周知的位置。甚至很现代的逻辑芯片组都在 ISA 内存的相同位置保留了等价的寄存器。非 Intel 的系统,例如 Alpha AXP PC 不受这些体系限制,通常使用不同的中断控制器。
  
    图 7.1 显示了两个串联在一起的 8 位控制器:每一个都有一个掩码和一个中断状态寄存器, PIC1 和 PIC2 。掩码寄存器位于地址 0x21 和 0xA1 ,而状态寄存器位于 0x20 和 0xA0 。在掩码寄存器的一个特殊位写 1 允许一种中断,写 0 可以禁止它。所以向位 3 写 1 允许中断 3 ,写 0 会禁止它。不幸的是(也是让人气恼的),中断掩码寄存器只可以写,你无法读回你所写的值。这意味着 Linux 必须为它设置的掩码( mask )寄存器保留一份本地拷贝。它在中断允许和禁止的例程中修改这些保存的掩码,每一次都要把整个掩码写到寄存器中。
  
    当产生中断信号,中断处理程序读取两个中断状态寄存器( ISR )。它把 0x20 的 ISR 看作 16 位的中断寄存器的第 8 位, 0xA0 中的 ISR 看作高 8 位。所以,发生在 0xA0 的 ISR 的第 1 位的中断被看作是中断 9 。 PCI1 的第 2 位不可用,因为它用作串联 PIC2 的中断,任何 PIC2 的中断都会使 PIC1 的第 2 位置位。
  
  7.2 Initializing the Interrupt Handling Data Structures (初始化中断处理数据结构)
  
    当设备驱动程序要求控制系统的中断的时候建立核心的中断处理数据结构。为此,设备驱动程序使用一系列 Linux 核心服务,用来请求一个中断、允许它和禁止它。这些设备驱动程序调用这些例程来登记它们的中断处理例程的地址。
  
  参见 arch/*/kernel/irq.c request_irq() enable_irq() and disable_irq()
  

本文关键:LinuxKernel核心中文手册(7)
  相关方案
Google
 

本站最佳浏览方式为 分辨率 1024x768 IE 6.0(或更高版本的 IE浏览器)

go top