1. 内核中断介绍

1.1 中断简介

所有支持Linux的平台都采用了中断(interrupt)的概念,以便(因种种原因)引入周期性的中断。需要区分两种类型的中断。

1. 硬件中断(hardware interrupt):由系统自身和与之连接的外设自动产生。它们用于支持更高效地实现设备驱动程序,也用于引起处理器自身对异常或错误的关注,这些是需要与内核代码进行交互的。

2. 软中断(SoftIRQ):用于有效实现内核中的延期操作。

在Linux中用于处理中断和系统调用相关部分的代码中,汇编和C代码交织在一起, 以解决C语言无法独立处理的一些特殊问题。在中断处理中涉及到许多C代码和底层的硬件交互代码。

在C6678处理器上,硬件中断的最大数目通常是15,这个值可不怎么大,还有考虑到有些中断编号已经永久性地分配给了标准的系统组件(键盘、定时器等),因而限制了可用于其他外部设备的中断编号数目。

外设可共享同一个中断号这个现象称为中断共享(interrupt sharing)。但必须硬件和内核同时支持才能使用共享中断,因为必须要识别出中断来源于哪个设备。

1.2 中断处理

在CPU得知发生中断后,它将进一步的处理委托给一个软件例程,该例程可能会修复故障、提供专门的处理或将外部事件通知用户进程。

由于每个中断和异常都有唯一的编号,内核使用一个数组,数组项是指向处理程序函数的指针。相关的中断号根据数组项在数组中的位置判断。

▲图1.1 中断处理过程

因为需要C语言代码和汇编语言代码之间的交互,所以必须特别小心,才能正确设计在汇编语言层次和C语言层次上的数据交换。对应的代码位于arch/arch/kernel/entry.S中,彻底利用了各个处理器的具体特性。

1.3 中断处理程序

中断处理程序可能会遇到困难,特别是在处理程序执行期间,发生了其他中断。尽管可以通过在处理程序执行期间禁用中断来防止,但这会引起其他问题,如遗漏重要的中断。屏蔽(Masking, 这个术语用于表示选择性地禁用一个或多个中断)因而只能短时间使用。

中断处理数据结构:IRQ相关信息管理的关键点是一个全局数组,每个数组项对应一个IRQ编号。因为数组位置和中断号是相同的,很容易定位与特定的IRQ相关的数组项:IRQ 0在位置0IRQ 15在位置15,等等。IRQ最终映射到哪个处理器中断。irq_desc存储了中断相关信息。

action链表提供了一个操作链,需要在中断发生时执行。由中断通知的设备驱动程序,可以将与之相关的处理程序函数放置在此处。有一个专门的数据结构用于表示这些操作。

chip硬件处理和芯片相关操作被封装在chip中。为此引入了一个专门的数据结构用来处理硬件相关操作。

1.4 处理程序函数的表示

irqaction结构定义如下,每个处理程序函数都对应该结构的一个实例:

<code>

该结构中最重要的成员是处理程序函数本身,即handler成员,这是一个函数指针,位于结构的起始处。在设备请求一个系统中断,而中断控制器通过引发中断将该请求转发到处理器的时候,内核将调用该处理程序函数。

在考虑如何注册处理程序函数时,我们再仔细考察其参数的语义。但请注意,处理程序的类型为irq_handler_t,与电流处理程序的类型irq_flow_handler_t显然是不同的。

name和dev_id唯一地标识一个中断处理程序。name是一个短字符串,用于标识设备(例如, 「e100」、「ncr53c8xx」等等),而dev_id是一个指针,指向在所有内核数据结构中唯一标识了该设备的数据结构实例,例如网卡的net_device实例。如果几个设备共享一个IRQ,那么IRQ编号自身不能标识该设备,此时,在删除处理程序函数时,将需要上述信息。

▲图1.2 中断结构体关系描述图

2. 中断向量表以及中断子程序

2.1 中断子程序实现

在汇编源文件arch/c6x/kernel/vectors.S 中定义了中断子程序,使用宏IRQVEC可以实现不同的中断子程序:

arch/c6x/kernel/vectors.S第 30 行实现了中断处理宏定义IRQVEC

▲图2.1 中断处理向量宏定义

根据如上IRQVEC宏定义结合实际代码使用情况可以生成不同的中断子程序。

▲图2.2 生成中断向量

例如:

79行 IRQVEC INT4,_int4_handler可生成如下中断子程序。

<code>

当中断发生时,进入到汇编代码中的中断子程序,首先保存寄存器A0的值保存在栈中,然后拷贝相应的中断子程序入口地址到A0寄存器中,然后跳转到相应的中断子程序,中断子程序执行完毕后从栈中恢复寄存器A0的值。

在中断子程序_int4_handler中执行如下指令

<code>

SAVE_ALL_INT此行作用为保存所有的寄存器到栈中,然后调用MASK_SYSCALL关闭系统调用,使用CALL_INT 4先将中断号存入A4,然后调用kernel 中的 c6x_do_IRQ 中断处理函数。调用结束后将返回结果存入寄存器B3。

▲图2.3 CALL_INT宏定义

在arch/c6x/kernel/entry.S 中定义了诸多 _DEFINE_MACRO 汇编宏定义。

1. 220行 _DEFINE_MACRO(SAVE_ALL_INT)  中断保存所有寄存器。

2. 325行 _DEFINE_MACRO(MASK_SYSCALL) 屏蔽系统调用。

2.1 c6x_do_IRQ处理流程

c6x_do_IRQ函数的是实现在arch/c6x/kernel/irq.c文件中

64行 asmlinkage void c6x_do_IRQ(unsigned int prio, struct pt_regs *regs)

▲图2.4 c6x_do_IRQ中断函数

获取kernel中断号:

c6x_do_IRQ 获取中断号prio,将中断号通过hw_to_kernel_irq将硬件中断号转换为kernel中断号,转换后传入kernel的中断处理函数generic_handle_irq。

在代码中hw_to_kernel_irq如何将硬件中断号转换为kernel中断号?

在中断初始化的过程中构建prio_to_irq的中断对应数组,将硬件中断号和kernel中断号产生对应关系。当使用hw_to_kernel_irq的时候,hw_to_kernel_irq从中断对应数组 prio_to_irq[(hw)] 中取出kernel中断号。

常规内核处理函数generic_handle_irq 处理中断流程:

在include/linux/irq.h 头文件中实现了generic_handle_irq和

generic_handle_irq_desc两个内联函数。

generic_handle_irq 使用kernel中断号irq获取irq中断号相对应的irq_to_desc,既irq_desc结构体数组,然后调用generic_handle_irq_desc将中断号,和获取的irq_desc结构体数组传给generic_handle_irq_desc。

▲图2.5 generic_handle_irq_desc

在generic_handle_irq_desc函数中检测irq对应的irq_desc结构体中是否有中断处理函数handle_irq。

如果有handle_irq就执行此中断的中断处理函数,这里执行的是handle_level_irq函数,在irq_desc->handle_irq中我们无法直接看到其对应的中断处理函数,可以通过init_IRQ 初始化函数中获得此处填入的中断处理函数名称。

▲图2.6 init_IRQ 中断初始化函数

handle_level_irq函数中执行的流程如下:

1. lock中断。

2. 检测中断是否为处理中状态:IRQ_INPROGRESS。

3. 如果中断为正在处理的状态直接跳到结尾处unlock中断并推出函数。

4. 如果中断为触发状态,将中断设置为正在处理的状态,并且调用handle_IRQ_event执行相应中断处理函数。

如果没有handle_irq就说明此中断为共享中断(IRQ线)执行__do_IRQ(irq)。

__do_IRQ 处理所有普通设备的中断,每一个设备都有其特定的中断处理函数,存在放action列表中。

在kernel/irq/handler.c文件中实现了__do_IRQ函数。__do_IRQ函数主要遍历irq_desc 结构体中的action链表处理中断。

449行 unsigned int __do_IRQ(unsigned int irq)

接下来使用共享中断处理函数:handle_IRQ_event 来遍历irq_desc 里的 action共享中断链表。

handle_IRQ_event函数:

在kernel/irq/handle.c 368行irqreturn_t handle_IRQ_event( unsigned int irq,struct irqaction *action)Handle_IRQ_event 用来处理irq实际的action链表。

c6x Linux 内核中断分析相关推荐

  1. Linux内核中断系统处理机制-详细分析

    原文地址::https://blog.csdn.net/weixin_42092278/article/details/81989449 相关文章 1.Linux中断管理 (1)Linux中断管理机制 ...

  2. Linux内核源代码分析-目录

    第一部分 Linux 内核源代码 arch/i386/kernel/entry.S 2 arch/i386/kernel/init_task.c 8 arch/i386/kernel/irq.c 8 ...

  3. 《linux内核中断》之 法外狂徒张三删库跑路

    法外狂徒张三删库跑路 真实案例:在今年2月份,国内一个程序员删库的消息传遍it界.他的几行代码,直接让上市公司微盟的市值一天蒸发超10亿,300百万用户直接受到影响.网上是谣言四起,可谓是最牛逼的删库 ...

  4. 《Linux内核情景分析》阅读笔记

    <Linux内核情景分析>这本书读过了一遍,不想继续读第二遍了. <Linux Kernel Development>这本书前后读了3遍,写得实在是好,正所谓"布衣暖 ...

  5. linux内核看门狗关闭方法,linux内核中断之看门狗

    一:内核中断 linux内核中的看门狗中断跟之前的裸板的中断差不多,在编写驱动之前,需要线把内核自带的watch dog模块裁剪掉,要不然会出现错误:在Device Drivers /Watchdog ...

  6. linux内核中断详解

    linux内核中断详解 1.中断的硬件触发流程 外设:如果外设有操作或者有数据可用,那么就会产生一个电信号,这个电信号发送给中断控制器. 中断控制器:中断控制器接收到外设发来的电信号以后,进行进一步的 ...

  7. linux 内核抢占分析

    linux 内核抢占分析 在 Linux 2.6 以后版本的 Linux 内核中,一个内核任务可以被抢占,从而提高系统的实时性.这样做最主要的优势在于,可以极大地增强系统的用户交互性,用户将会觉得鼠标 ...

  8. linux内核源代码分析----内核基础设施之klist

    概述 klist是list的线程安全版本,他提供了整个链表的自旋锁,查找链表节点,对链表节点的插入和删除操作都要获得这个自旋锁.klist的节点数据结构是klist_node,klist_node引入 ...

  9. Linux内核源代码分析——可执行文件header处理(二进制文件读写范例,写DUL工具入门指引)...

    在把Linux内核源代码生成Image之前,需要把执行文件头结构信息剔除出来.这个过程对理解Linux内核具有很大的帮助.同时,由于是对可执行文件进行直接读写操作,想写DUL工具的童鞋可以在这里学习到 ...

最新文章

  1. 父亲节遇上端午节,你难道不回家吗?
  2. 技巧:两部解决U盘安装windows 7
  3. linux 编辑hosts 命令,linux下修改hostid
  4. codility上的问题(26) Hydrogenium 2013
  5. 类和对象—对象特性—const修饰成员函数
  6. vmware提示com.vmware.sps.fault.QsConnectionException报错
  7. 在Qt中用默认程序打开文件
  8. Silverlight实用窍门系列:42.读取拖动到控件上的外部txt和jpg文件,多外部文件的拖动【附带实例源码】...
  9. Android之HttpClient 和HttpResponse 小结
  10. HTML5新布局元素布局,HTML5新的布局元素
  11. 软件工程---08.软件测试
  12. 07.30《jQuery》——1.1DOM对和jQuery对象的转化
  13. linux桌面版自动更新关闭了,桌面应用|开启 Ubuntu 系统自动升级
  14. 【java】SPI机制详解
  15. 多乐融依托大数据锻造五重风控防线
  16. 深度学习6-自定义层详解
  17. 什么是java cdm_Java-ORM数据库框架CDM介绍
  18. 【大数据】分布式机器学习平台
  19. ubuntu16.04+Titan Xp安装显卡驱动+Cuda9.0+cudnn
  20. 移动App Store测试的“七宗罪”

热门文章

  1. java编写流星_纯Java代码实现流星划过天空
  2. mysql一共有多少引擎_MySQL存储引擎你们知道多少?
  3. java 带宽控制_如何使用Java netty正确限制带宽使用?
  4. python转二进制字符串_python如何将二进制串(UTF-8)转换为字符串?
  5. 图 之遍历----深度优先遍历0.o
  6. python标准输入_Python 处理标准输入
  7. nginx 带宽_谈谈Nginx和LVS各自的优缺点以及使用
  8. mtk android 5.1 logo,Android ROM DIY之MTK平台手机通用移植
  9. 重叠面积_重叠面积——动点产生的重叠面积问题
  10. java webview 对象_Android – 将JSON对象从webview javascript传递给java