说明:
- Kernel版本:4.14
- ARM64处理器,Contex-A53,双核
- 使用工具:Source Insight 3.5, Visio
1. 概述
深入分析Linux中断子系统之中断控制器及驱动讲到了底层硬件GIC驱动,以及Arch-Specific的中断代码,本文将研究下通用的中断处理的过程,属于硬件无关层。当然,我还是建议你看一下上篇文章。
这篇文章会解答两个问题:
- 用户是怎么使用中断的(中断注册)?
- 外设触发中断信号时,最终是怎么调用到中断handler的(中断处理)?
2. 数据结构分析
先来看一下总的数据结构,核心是围绕着struct irq_desc来展开:
- Linux内核的中断处理,围绕着中断描述符结构struct irq_desc展开,内核提供了两种中断描述符组织形式:
- 打开CONFIG_SPARSE_IRQ宏(中断编号不连续),中断描述符以radix-tree来组织,用户在初始化时进行动态分配,然后再插入radix-tree中;
- 关闭CONFIG_SPARSE_IRQ宏(中断编号连续),中断描述符以数组的形式组织,并且已经分配好;
- 不管哪种形式,都可以通过linux irq号来找到对应的中断描述符;
- 图的左侧灰色部分,主要在中断控制器驱动中进行初始化设置,包括各个结构中函数指针的指向等,其中struct irq_chip用于对中断控制器的硬件操作,struct irq_domain与中断控制器对应,完成的工作是硬件中断号到Linux irq的映射;
- 图的上侧灰色部分,中断描述符的创建(这里指CONFIG_SPARSE_IRQ),主要在获取设备中断信息的过程中完成的,从而让设备树中的中断能与具体的中断描述符irq_desc匹配;
- 图中剩余部分,在设备申请注册中断的过程中进行设置,比如struct irqaction中handler的设置,这个用于指向我们设备驱动程序中的中断处理函数了;
中断的处理主要有以下几个功能模块:
- 硬件中断号到Linux irq中断号的映射,并创建好irq_desc中断描述符;
- 中断注册时,先获取设备的中断号,根据中断号找到对应的irq_desc,并将设备的中断处理函数添加到irq_desc中;
- 设备触发中断信号时,根据硬件中断号得到Linux irq中断号,找到对应的irq_de