每个内核版本的代码都会有小部分不同,但是大体流程基本相同,只是调用关系和函数名称有些变化,下面来分析中断流程
1:在 arch/arm/kernel/ 下有个traps.c 文件中的 void __init early_trap_init(void *vectors_base) 函数 进行重定位中断向量列表
搜索 __vectors_start 可以知道 在arch/arm/kernel/entry_armv.S 中有宏定义 在这个文件中找到 vector_stub irq, IRQ_MODE, 4 以这个为例分析一下游程
vector_stub 是一个宏。
下面以 __irq_usr 用户模式的中断来找流程 搜索 __irq_usr
有个 irq_handler 这也是一个宏,继续搜索 还是在这个 entry_armv.S 中
搜索 arch_irq_handler_default 后里面会调用 asm_do_IRQ
到这里 前面都是用汇编写的,asm_do_IRQ 后面都用C函数实现的
调用关系如下:
early_trap_init //内核用的是虚拟地址,这里只是把原来的中断向量复制到新的虚拟地址去 在内核配置文件有 0xffff0000 或 0x00000000都可以
vector_stub irq //以这用户模式中断为倒分析
__irq_usr
irq_handler
arch_irq_handler_default
asm_do_IRQ
下面来分析一下 asm_do_IRQ 了解中断是如何进行的
2:先列出调用关系图
asm_do_IRQ
handle_IRQ
generic_handle_irq
struct irq_desc *desc = irq_to_desc(irq);
generic_handle_irq_desc
desc->handle_irq(irq, desc); //desc是一个结构体 这个函数实现了 1:分辨是那一个中断 2:调用处理函数 3:清中断
=================================================分割线=====================================================
desc->handle_irq(irq, desc); 分析它 handle_irq指向那个函数?搜索它 在 kernel/irq/chip.c 中找到 __irq_set_handler 这个函里调用了 desc->handle_irq = handle;
再搜索 __irq_set_handler 这个函数,看谁调用 include/linux/ irq.h 中 irq_set_chained_handler 里调用了 再搜这个函数在那调用 得到 在 arch/arm/plat-s3c24xx 里
s3c24xx_init_irq 这个函数调用 在这个函数里构造了 irq_desc 结构体 即初始化中断里的设置这个函数里调用 这只是例子,不同的中断初始化函数都可以调用这__irq_set_handler
handle_edge_irq
handle_irq_event(desc); //这个函数就是处理中断
层次就是这样的,我们还需要分析一下 irq_desc 结构体 这个结构体在 include/linux/irqdesc.h 中定义 下面只列出一部分
以上这些都是内核中断体系架构都做好的,这就是中断框架,我们如果要用我们自已的中断,我们怎么告诉内核呢?用 request_irq 注册,下面再来分析
irq_desc 是一个以中断号为下标的数组,里面有各种处理函数,链表等内容,我们要使用自已的中断驱动,就需要构造 填充 然后 注册到这个链表里。
request_irq
request_threaded_irq
action = kzalloc(sizeof(struct irqaction), GFP_KERNEL); //分配一个irqaction结构体
action->handler = handler; //填充 把传入的参数填充到结构体
action->thread_fn = thread_fn;
action->flags = irqflags;
action->name = devname;
action->dev_id = dev_id;
retval = __setup_irq(irq, desc, action); //设置中断
__irq_set_trigger
ret = chip->irq_set_type(&desc->irq_data, flags); //设置中断类型
__enable_irq(desc, irq, false); //使能中断
到此基本分析完毕,下一节 写一个基本中断的按键驱动程序