c6x Linux 内核中断分析

 

 

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链表。

 

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/566756.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

ccf 智能运维 裴丹_智能运维 聊一聊实时计算系统

本文是我在实时数据计算系统的设计、开发、运维生涯的一部分经验总结。主要介绍一些设计思路和常见问题的解决方案&#xff0c;不关注具体计算框架的使用。本人主要致力于监控系统数据计算方向&#xff0c;主要业务场景有&#xff1a;监控数据的ETL、数据汇聚、分析、异常检测等…

系统建模、分析、仿真和验证软件工具ModelCodoer

在安全关键领域&#xff0c;基于模型的软件工程已逐渐进入了我国的装备研制过程中。使用SimuLink或者SCADE等嵌入式软件建模工具进行可视化建模&#xff0c;然后生成高可靠的二进制代码逐渐成为了安全关键领域的主流软件开发方式。由迪捷软件自主研发的系统建模、分析、仿真和验…

php配置email支持_使用PHPMailer实现PHP发邮件功能

第一步&#xff1a;打开网址https://github.com/PHPMailer/PHPMailer/ 下载PHPMailer&#xff0c;PHPMailer 需要 PHP 的 sockets 扩展支持&#xff0c;而登录 QQ 邮箱 SMTP 服务器则必须通过 SSL 加密的&#xff0c; PHP 还得包含 openssl 的支持。第二步&#xff1a;使用 php…

如何构建裸机hello world目标程序并在SkyEye全数字实时仿真平台上运行及调试?

SkyEye全数字实时仿真平台&#xff0c;简称SkyEye&#xff0c;是一款支持 ARM、TI DSP、PowerPC、X86、SPARC、龙芯、飞腾等多种处理器体系架构的指令级仿真平台。 SkyEye可以部署在桌面计算机上&#xff0c;开发人员可以基于SkyEye提供的已有模型库的组件&#xff08;如处理器…

bigdicmal除法精度设置_BigDecimal 高精度计算 熟悉扩展,java除法保留小数问题

java保留两位小数问题&#xff1a;方式一&#xff1a;四舍五入double f 111231.5585;BigDecimal b new BigDecimal(f);double f1 b.setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();保留两位小数---------------------------------------------…

「基于模型的系统工程」的发展历程

节选自《「基于模型的系统工程」的发展历程》&#xff0c;因篇幅有限&#xff0c;完整报告文末领取。 当下&#xff0c;人们热衷于讨论基于计算机的建模、模型、数据库和敏捷设计方法。然而&#xff0c;很少有人会耐心地审视和理解大量的技术创新&#xff0c;这些技术创新和发…

Unity使用Rider作为默认编辑器

01.Edit -> Preferences 02.Externel Tools -> Open by file extension 如果界面选项有Rider直接选择&#xff0c;如果没有选择Browse) 03.选择rider64.exe 04.成功关联

群签名和环签名的区别_环签名方案的研究

摘要&#xff1a;信息时代虽然带给我们无限商机与方便,但也充斥着隐患与危险.由于网络容易受到攻击,导致机密信息的泄密,数据被篡改,轻则引发企业,部门工作陷入瘫痪,个人利益受损,重则危及国家安全和社会稳定,因此保证信息安全已经成为关系国计民生的重要问题之一.而数字签名技…

国产自主可控的代码自动生成工具SkyEye

传统的系统开发过程&#xff0c;都是由工程师根据项目需求书来编写代码完成系统的开发&#xff0c;但随着功能的扩充和版本的迭代&#xff0c;系统中庞大的代码量很难确保正确无误&#xff0c;给后期测试和仿真带来了很大的压力和成本&#xff0c;在航空航天、卫星系统、核电等…

同步数据流语言代码生成工具的研究进展

摘要 同步数据流语言(如Lustre,Signal)近年来在航空、高铁、核电等安全关键领域得到了广泛应用&#xff0c;因此与这类语言相关的开发工具本身的安全性问题受到高度关注.同步数据流语言到串行命令式语言的代码生成工具是此类工具的典型代表(如Scade)。构造代码生成工具的途径可…

jstack 脚本 自动日志_深入理解jstack日志

Tags : jstack日志发表时间&#xff1a;2019-03-17 23:53:19在分析线上问题时常使用到jstack 命令将当时Java应用程序的线程堆栈dump出来。面对jstack 日志&#xff0c;我们如何查看&#xff1f;首先要清楚线程的状态线程的状态有&#xff1a;new、runnable、running、waiting、…

swagger默认访问路径_swagger 如何配置项目访问路径

boot子模块的pom文件&#xff1a;xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">swagger-parentcom.test.swagger1.0-SNAPSHOT4.0.0warbo…

layui向body添加html_layui 各项配置

第一、如何全部选中table中每一条记录1.首先给table的父类设置一个唯一id *这种方式不推荐&#xff0c;效果比较差&#xff0c;推荐第2种方式再搜索 alias-table div.layui-table-fixed.layui-table-fixed-l下面的i元素var bbcc $(#alias-table div.layui-table-fixed.layui-ta…

国产自主可控的MBSE解决方案和全数字仿真平台(SkyEye)

2020年6月&#xff0c;哈工大、哈工程被美国商务部列入实体清单&#xff0c;禁用MATLAB事件频繁登上热搜&#xff0c;工业软件被称为「卡脖子」技术。 截止到2020年12月&#xff0c;中国已有超过300家企业和机构被列入美国“实体名单”&#xff0c;被列入名单的大部分是从事安全…

iservice封装有哪些方法_总结WebService的一些封装技巧

今天早上起来&#xff0c;想谈谈.NET中的WebService&#xff0c;当然我不想讲什么是WebService&#xff0c;或者怎么用WebService&#xff0c;因为那个大家随便Google一下前100页都能找到答案。今天我想来分享一下我在用WebService中的一些技巧(至少我认为是技巧&#xff0c;还…

一种全数字实时仿真的安全关键领域解决方案

随着科技的发展&#xff0c;系统工程的设计体量逐渐庞大起来&#xff0c;尤其是对于轨道交通、航空航天、核电站等安全关键领域中&#xff0c;如何在复杂度逐年变大的同时保证其安全性和可靠性&#xff0c;是近年来各大公司需要研究的课题。最近比较火热的基于模型的系统工程&a…

vue 引用网络css_vue如何引用其他组件(css和js)

1.vuejs组件之间的调用components注意&#xff1a;报错Do not use built-in or reserved HTML elements as component id:修改组件的名字&#xff0c;例如不能使用address为组件名字组件名字不要使用内置的或保留HTML元素为组件id&#xff0c;App.vue是一个入口&#xff0c;vue…

国产自主可控的MBSE建模与仿真平台SkyEye

转载&#xff1a; 2020年6月&#xff0c;哈工大、哈工程被美国商务部列入实体清单&#xff0c;禁用MATLAB事件频繁登上热搜&#xff0c;工业软件被称为「卡脖子」技术。 截止到2020年12月&#xff0c;中国已有超过300家企业和机构被列入美国“实体名单”&#xff0c;被列入名…

access求斐波拉契数列_打印目录,斐波那契数列的递归与循环,牧场牛数

实验报告1任务概述(任务说明)1 f(n)f(n-1)f(n-2)f(0)f(1)1&#xff0c;求斐波那契数列第20项&#xff0c;分别用循环和递归的方式&#xff0c;比较时间效率。提示&#xff1a;可以使用c函数clock取出当前系统时间&#xff0c;计算前后各一次&#xff0c;两次相减除以每秒的时钟…

国产自主可控的形式化验证代码自动生成工具ModelCoder可替代Matlab/Sumlink

在安全关键领域&#xff0c;基于模型的软件工程或者软件开发已逐渐进入了我国的装备研制过程中。使用SimuLink或者SCADE等嵌入式软件建模工具对算法或者控制逻辑进行可视化建模&#xff0c;然后生成高可靠的二进制代码逐渐成为了安全关键领域的主流软件开发方式。由我司自主开发…