以一个IRQ中断为例子。
内核启动-------调用start_kernel()函数------调用setup_arch(&command_line)函数-----------调用early_trap_init()函数,实现异常向量表,异常处理代码的搬运
如果产生IRQ中断---------PC指向搬运后的异常向量表的vector_irq + stubs_offset地址 -------跳到搬运后的vector_irq地址-----调用函数asm_do_IRQ函数------调用generic_handle_irq(irq)函数,该函数里的handle_irq(irq, desc)作用就是irq中断号条用irq_desc数组中对应的handle_irq-------判断irq对应的中断是不是以组为形式是的话,是的话调用相应的函数判断是那个中断产生-----判断中断什么类型------若是电平触发,调用函数handle_level_irq,若是边沿触发调用函数handle_edge_irq---------条用action链表上用户定义的中断处理函数。
struct irq_desc {
unsigned intirq; //中断号
} ____cacheline_internodealigned_in_smp;
struct irq_chip {
const char *name;
unsigned int (*startup)(unsigned int irq); //打开中断
void (*shutdown)(unsigned int irq); //关闭中断
void (*enable)(unsigned int irq); //使能中断
void (*disable)(unsigned int irq); //禁止中断
void (*ack)(unsigned int irq); //响应中断
void (*mask)(unsigned int irq); //屏蔽中断源
void (*mask_ack)(unsigned int irq); //开启中断源
void (*unmask)(unsigned int irq);
void (*eoi)(unsigned int irq);
void (*end)(unsigned int irq);
void (*set_affinity)(unsigned int irq, cpumask_t dest);
int (*retrigger)(unsigned int irq);
int (*set_type)(unsigned int irq, unsigned int flow_type);
int (*set_wake)(unsigned int irq, unsigned int on);
/* Currently used only by UML, might disappear one day.*/
#ifdef CONFIG_IRQ_RELEASE_METHOD
void (*release)(unsigned int irq, void *dev_id);
#endif
/*
* For compatibility, ->typename is copied into ->name.
* Will disappear.
*/
const char *typename;
};
struct irqaction {
irq_handler_t handler; //
unsigned long flags; //中断标志
cpumask_t mask;
const char *name;
void *dev_id; //用户传给handler的参数,也可以区分共享中断
struct irqaction *next;
int irq;
struct proc_dir_entry *dir;
};