Linux内核异常处理
- 为什么要学习内核:你对技术追求、大厂面试需求、更好地做应用层开发
- 内核我们要学习内容:内核管理、进程管理、文件系统、操作系统调用、网络协议栈、虚拟化等等。
1、异常及非屏蔽中断
- 异常就是CPU内核出现的中断,在CPU执行特定指令时出现非法情况。非屏蔽中断就是计算机内部硬件出错时引起的异常情况。
- Intel把非屏蔽中断作为异常的一种来处理。IntelX86处理器发布大约20种异常。每种异常都会由专门的异常处理程序来处理操作,它们通常把一个UNIX信号发送到引起异常的进程。具体异常处理程序发送的信号如下:
2、中断请求初始化分析
- 由于计算机硬件的限制,很多外部设备不共享中断线,例如,PC配置可以把同一条中断线分配给网卡或图形卡。在Linux系统设计中,专门为每个中断请求IRQ设置一个队列,称为中断请求队列。
- 中断线、中断请求(IRQ)号及中断向量它们之间关系:中断线是中断请求的一种物理描述,逻辑上对应一个中断请求号(中断号),第n个中断号(IRQn)的缺少中向量是n+32。
3、 IRQ队列数据结构
- 在256个中断向量中,除32个分配给异常以外,还有224个作为中断向量。对于第个IRQ,Linux都用一个irq_desc_t数据结构来描述,我们就把它叫IRQ描述符,224个IRQ形成一个数组irq_desc[],具体在内核源码分析如下:
3.1中断服务例程描述符irqaction
- 在IRQ描述符中我们看到指针action的结构为irqaction,它是为多个设备能共享一条中断线而设置的一个数据结构。具体内核源码分析如下:
3.2中断服务例程
- 具体来讲中断处理程序相当于某个中断向量的总处理程序,每个中断服务例程都有相同的参数:
- IRQ:中断号
- dev_id:设备标识符,其类型为void*
- regs:指向内核堆栈区的指针。
3.3中断请求队列的初始化
- 在IDT表初始化完成之初,每个中断服务队列还为空。即使打开中断且某个外设中断真的发生,也得不到实际服务,因为CPU虽然通过中断门进入某个中断向量的总处理程序,具体中断服务例程还没有挂入中断请求队列,因此在设备驱动程序的初始化阶段,必须通过request_irq()函数将对应的中断服务例程挂入中断请求队列。具体内核源码如下:
- 真正对中断请求队列进行初始化的函数如下:
版权声明:本文为知乎博主「Linux内核库」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文 出处链接及本声明。
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 Blog!