本文转载自嵌入式Linux中文站
在硬件上,中断源可以通过中断控制器向CPU提交中断,进而引发中断处理程序的执行,不过这种硬件中断体系每一种CPU都不一样,而Linux作为操作系统,需要同时支持这些中断体系,如此一来,Linux中就提出了软中断的概念,也有人叫内核中断,其本质就是使用统一的方式对不同硬件中断体系中的中断号进行再映射,在操作系统中操作的中断号都是这些映射过的软中断号。就是下图中的irq_num
Linux内核中定义了名为irq_desc的中断例程描述符表来描述中断服务例程,每一个irq_desc对象数组中的下标就是软中断号。其中的struct irqaction对象描述了这个中断服务例程的中断的具体信息。
//include/linux/irqdesc.h
40 struct irq_desc { 41 struct irq_data irq_data; 42 unsigned int __percpu *kstat_irqs; 43 irq_flow_handler_t handle_irq; 44 #ifdef CONFIG_IRQ_PREFLOW_FASTEOI
45 irq_preflow_handler_t preflow_handler; 46 #endif
47 struct irqaction *action; /* IRQ action list */
48 unsigned int status_use_accessors; 49 unsigned int core_internal_state__do_not_mess_with_it; 50 unsigned int depth; /* nested irq disables */
51 unsigned int wake_depth; /* nested wake enables */
52 unsigned int irq_count;/* For detecting broken IRQs */
53 unsigned long last_unhandled; /* Aging timer for unhandled count */
54 unsigned int irqs_unhandled; 55 raw_spinlock_t lock; 56 struct cpumask *percpu_enabled; 57 #ifdef CONFIG_SMP
58 const struct cpumask *affinity_hint; 59 struct irq_affinity_notify *affinity_notify; 60 #ifdef CONFIG_GENERIC_PENDING_IRQ
61 cpumask_var_t pending_mask; 62 #endif
63 #endif
64 unsigned long threads_oneshot; 65 atomic_t threads_active; 66 wait_queue_head_t wait_for_threads; 67 #ifdef CONFIG_PROC_FS
68 struct proc_dir_entry *dir; 69 #endif
70 int parent_irq; 71 struct module *owner; 72 const char *name; 73 } ____cacheline_internodealigned_in_smp; 74
76 extern struct irq_desc irq_desc[NR_IRQS]; //NR_IRQS表示中断源的数目
//linux/interrupt.h 104 //一个irq action的描述结构 105 struct irqaction {
106 irq_handler_t handler; 107 void *dev_id; 108 void __percpu *percpu_dev_id; 109 struct irqaction *next; 110 irq_handler_t thread_fn; 111 struct task_struct *thread; 112 unsigned int irq; 113 unsigned int flags; 114 unsigned long thread_flags; 115 unsigned long thread_mask; 116 const char *name; 117 struct proc_dir_entry *dir; 118 } ____cacheline_internodealigned_in_smp;
struct irqaction --105--
|