 
- UID
- 1029342
- 性别
- 男
|

一、中断的概念
中断是指在CPU正常运行期间,由于内外部事件或由程序预先安排的事件引起的CPU暂时停止正在运行的程序,转而为该内部或外部事件或预先安排的事件服务的程序中去,服务完毕后再返回去继续运行被暂时中断的程序。Linux中通常分为外部中断(又叫硬件中断)和内部中断(又叫异常)。
在实地址模式中,CPU把内存中从0开始的1KB空间作为一个中断向量表。表中的每一项占4个字节。但是在保护模式中,有这4个字节的表项构成的中断向量表不满足实际需求,于是根据反映模式切换的信息和偏移量的足够使得中断向量表的表项由8个字节组成,而中断向量表也叫做了中断描述符表(IDT)。在CPU中增加了一个用来描述中断描述符表寄存器(IDTR),用来保存中断描述符表的起始地址。
二、中断的请求过程
外部设备当需要操作系统做相关的事情的时候,会产生相应的中断。设备通过相应的中断线向中断控制器发送高电平以产生中断信号,而操作系统则会从中断控制器的状态位取得那根中断线上产生的中断。而且只有在设备在对某一条中断线拥有控制权,才可以向这条中断线上发送信号。也由于现在的外设越来越多,中断线又是很宝贵的资源不可能被一一对应。因此在使用中断线前,就得对相应的中断线进行申请。无论采用共享中断方式还是独占一个中断,申请过程都是先讲所有的中断线进行扫描,得出哪些没有别占用,从其中选择一个作为该设备的IRQ。其次,通过中断申请函数申请相应的IRQ。最后,根据申请结果查看中断是否能够被执行。
中断机制的核心数据结构是 irq_desc, 它完整地描述了一条中断线 (或称为 “中断通道” )。以下程序源码版本为linux-2.6.32.2。
其中irq_desc 结构在 include/linux/irq.h 中定义:
typedef void (*irq_flow_handler_t)(unsigned int irq,
struct irq_desc *desc);
struct irq_desc {
unsigned int irq;
struct timer_rand_state *timer_rand_state;
unsigned int *kstat_irqs;
#ifdef CONFIG_INTR_REMAP
struct irq_2_iommu *irq_2_iommu;
#endif
irq_flow_handler_t handle_irq; /* 高层次的中断事件处理函数 */
struct irq_chip *chip; /* 低层次的硬件操作 */
struct msi_desc *msi_desc;
void *handler_data; /* chip 方法使用的数据*/
void *chip_data; /* chip 私有数据 */
struct irqaction *action; /* 行为链表(action list) */
unsigned int status; /* 状态 */
unsigned int depth; /* 关中断次数 */
unsigned int wake_depth; /* 唤醒次数 */
unsigned int irq_count; /* 发生的中断次数 */
unsigned long last_unhandled; /*滞留时间 */
unsigned int irqs_unhandled;
spinlock_t lock; /*自选锁*/
#ifdef CONFIG_SMP
cpumask_var_t affinity;
unsigned int node;
#ifdef CONFIG_GENERIC_PENDING_IRQ
cpumask_var_t pending_mask;
#endif
#endif
atomic_t threads_active;
wait_queue_head_t wait_for_threads;
#ifdef CONFIG_PROC_FS
struct proc_dir_entry *dir; /* 在 proc 文件系统中的目录 */
#endif
const char *name;/*名称*/
} ____cacheline_internodealigned_in_smp; |
|