Linux内核学习(六)—— 中断(基于Linux 2.6内核)

一、中断

中断使得硬件得以发出通知给处理器。中断随时都可以产生,如键盘敲击就会触发中断,通知操作系统有按键按下。

不同设备对应的中断不同,而每个中断都通过一个唯一的数字标识。这些中断值通常被称为中断请求(IRQ)线。每个 IRQ 线都会关联一个数值量。

异常与中断不同,它在产生时必须考虑与处理器时钟同步,异常也常常被称为同步中断。在处理器执行到错误指令时候(如除数为0),或者是在执行期间出现特殊情况(如缺页),这些异常需要通过内核来处理,处理器就会产生一个异常。中断还可以通过软中断实现系统调用。

二、中断处理程序

在响应一个特定中断的时候,内核会执行一个函数,该函数叫做中断处理程序(interrupt handler) 或中断服务例程(interrupt service routine,ISR)。每种类型的中断都有一个相应的中断处理程序。一个设备的中断处理程序是它设备驱动程序(driver)的一部分——设备驱动程序是用于对设备进行管理的内核代码

中断处理程序与其他内核函数的真正区别在于,中断处理程序是被内核调用来响应中断的,而它们运行于我们称之为中断上下文的特殊上下文中。

中断可能随时发生,因此中断处理程序也就随时可能执行。所以必须保证中断处理程序能够快速执行,这样才能保证尽可能快地恢复中断代码的执行。

一般把中断处理切位两个部分:中断处理程序是上半部(top half)——接收到一个中断,上半部立刻开始执行,但只做有严格时限的工作,例如对接收的中断进行应答或复位硬件,这些工作都是在所有中断被禁止的情况下完成的。能够被允许稍后完成的工作会推迟到下半部(bottom half)去。

三、注册中断处理程序

中断处理程序是管理硬件的驱动程序的组成部分。如果设备使用中断,那么相应的驱动程序就注册一个中断处理程序。

驱动程序可以通过 request_irq() 函数注册一个中断处理程序(声明在 <linux/interrupt.h>),并且激活给定的中断线,以处理中断:

第一个参数 irq 表示要分配的中断号。

第二个参数 handler 是一个指针,指向处理这个中断的实际中断处理程序。只要操作系统一接收到中断,该函数就被调用。

注意 handler 函数的原型,它接受两个参数,并有一个类型为 irqreturn_t 的返回值。

第三个参数 flags 可以为 0,也可能是下列一个或多个标志的位掩码。定义在 <linux/interrupt.h>。其中最重要的几个标志是:

  • IRQF_DISABLED——该标志被设置后,意味着内核在处理中断处理程序本身期间,要禁止所有的其他中断。多数中断处理程序是不会设置该位,这种用法留给希望快速执行的轻量级中断。
  • IRQF_TIMER——该标志是特别为系统定时器的中断处理而准备的。
  • IRQF_SHARED——此标志标明可以在多个中断处理程序之间共享中断线。

第四个参数 name 是与中断相关的设备的 ASCII 文本表示

第五个参数 dev 用于共享中断线。当一个中断处理程序需要释放时,dev 将提供唯一的标志信息(cookie),以便从共享中断线的诸多中断处理程序中删除指定的那一个。如果无需共享中断线则设置为 NULL 即可。内核每次调用中断处理程序时,都会把这个指针传递给它。实践中往往会通过它来传递驱动程序的设备结构

request_irq() 函数成功执行会返回 0,非 0 值则代表有错误发生。

request_irq() 函数可能会睡眠,因此不能在中断上下文或其他不允许阻塞的代码中调用该函数。因为 kmalloc() 是可睡眠的。

四、卸载中断处理程序

卸载驱动程序时,需要注销相应的中断处理程序,并释放中断线。上述动作需要调用:

void free_irq(unsigned int irq, void *dev)

如果指定的中断线不是共享的,则删除处理程序的同时将禁用这条中断线。如果中断线是共享的,则删除 dev 所对应的处理程序,并不禁用中断线。

 

五、编写中断处理程序

以下是一个中断处理程序声明:

static irqreturn_t intr_handler(int irq, void *dev)

中断处理程序的返回值为 irqreturn_t。中断处理程序可能返回两个特殊的值:IRQ_NONE 和 IRQ_HANDLED。当中断处理程序检测到一个中断,但该中断对应的设备并不是在注册处理函数期间指定的产生源的时候,返回 IRQ_NONE。反之则返回 IRQ_HANDLED。

Linux 的中断处理程序是无需重入的。同一个中断处理程序绝不会被同时调用以处理嵌套的中断。

共享的处理程序的特点有:

  • request_irq() 的参数 flags 必须设置 IRQF_SHARED 标志。
  • 对于每个注册的中断处理程序来说,dev 参数必须唯一。指向任一设备结构的指针就是唯一的。
  • 中断处理程序必须能够区分它的设备是否真的产生了中断。

内核在接收一个中断后,它将依次调用在该中断线上注册的共享的处理程序,所以,一个处理程序必须知道它是否应该为这个中断负责,如果与它相关的设备并没有产生中断,那么处理程序应该立即退出。

六、中断上下文

当执行一个中断处理程序的时候,内核处于中断上下文(interrupt context)中。

进程上下文是一种内核所处的操作模式,此时内核代表进程执行。进程上下文可以睡眠,也可以调用调度程序,因为进程有 task_struct 结构,当进程再次被调度时能恢复进程执行环境。

中断上下文和进程没有什么关联,并且中断上下文是不可睡眠的,因为中断上下文没有某种结构记录它的执行状态,一旦睡眠就无法再被重新唤起了(没有东西来恢复它的执行环境),所以在中断上下文中不可使用信号量,因为信号量会导致睡眠。因为中断打断了其他代码的执行,所以中断上下文的代码应该简洁、迅速,尽量把工作从中断处理程序中分离出来,放到下半部执行。

procfs 是一个虚拟文件系统,它只存在于内核内存,一般安装于 /proc 目录。在 procfs 中读写文件都要调用内核函数。/proc/interrupt 文件存放系统中与中断相关的统计信息。

通过禁止中断,可以确保某个中断处理程序不会抢占当前的代码。锁提供保护机制,防止来自其他处理器的并发访问,而禁止中断提供保护机制,则是防止来自其他中断处理程序的并发访问。

禁止当前处理器上的本地中断,随后又激活它们的语句为:

local_irq_disable();
/* 禁止中断 */
local_irq_enable();

x86 上这两个函数是通过单个汇编指令实现的,cli 指令和 sti 指令。

但是上述用法并不安全,万一在调用 local_irq_disable() 之前中断就是关闭的,之后再调用 local_irq_enable()相当于无条件把中断打开了,所以为了更安全的关闭中断,我们使用如下方式:

unsigned long flags;

local_irq_save(flags); /* 禁止中断 */

local_irq_restore(flags)l /* 中断恢复到原来的状态 */

 

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Dockerfile制作镜像与搭建LAMP环境

1、编写Dockerfile制作Web应用系统nginx镜像&#xff0c;生成镜像nginx:v1.1&#xff0c;并推送其到私有仓库。 具体要求如下&#xff1a; &#xff08;1&#xff09;基于centos基础镜像&#xff1b; &#xff08;2&#xff09;指定作者信息&#xff1b; &#xff08;3&#x…

VMware虚拟机Ubuntu无法连接网络的解决方法

一、解决办法 网络适配器设置 终端依次执行下面命令即可 sudo nmcli networking off sudo nmcli networking onsudo service network-manager start #或者 sudo service NetworkManager start成功出现这个图标&#xff0c;即代表网络连接成功。

AveMaria 传播手段的变化

AveMaria 是一种最早在 2018 年 12 月出现的窃密木马&#xff0c;攻击者越来越喜欢使用其进行攻击&#xff0c;运营方也一直在持续更新和升级。在过去六个月中&#xff0c;研究人员观察到 AveMaria 的传播手段发生了许多变化。 2022 年 12 月攻击行动 研究人员发现了名为 .Vh…

Linux中shell脚本——for、while循环及脚本练习

目录 一.for循环 1.1.基本格式 1.2.类C语言格式 二.while循环 2.1.基本格式 2.2.死循环语句 三.跳出循环 3.1.continue跳出循环 3.2.break跳出循环 四.常用循环 4.1.循环打印九九乘法表 4.2.循环ping测试某个网段网络连通性 4.3.while死循环实现猜数字游戏 4.4.数…

Python自动化小技巧18——自动化资产月报(word设置字体表格样式,查找替换文字)

案例背景 每月都要写各种月报&#xff0c;经营管理月报&#xff0c;资产月报.....这些报告文字目标都是高度相似的&#xff0c;只是需要替换为每个月的实际数据就行&#xff0c;如下&#xff1a; (打码是怕信息泄露.....) 可以看到&#xff0c;这个报告的都是高度模板化&…

Linux 线程安全

一、线程安全的概念 线程安全即就是在多线程运行的时候&#xff0c;不论线程的调度顺序怎样&#xff0c;最终的结果都是 一样的、正确的。那么就说这些线程是安全的。 二、如何保证线程安全 1.线程同步 保证同一时刻只有一个线程访问临界资源。线程同步的方法有4种&#xf…

python中使用xml快速创建Caption和URL书签管理器应用程序

导语&#xff1a; 本文介绍如何使用wxPython库创建一个Caption和URL管理器应用程序。该应用程序具有图形用户界面&#xff0c;允许用户输入Caption和URL&#xff0c;并将其保存到XML文件中。此外&#xff0c;还提供了浏览文件夹并选择HTML文件的功能&#xff0c;并可以运行另一…

低代码开发 轻松解决企业数字化能力建设困局

谈及数字化&#xff0c;这是一个几乎所有领域都在使用的概念。当下&#xff0c;数字化正在经历从以企业为中心向产业为中心转移、从追求效能为主的价值诉求向追求业务创新和业务发展的价值诉求转变&#xff0c;不断增加的不确定性也为数字化的发展蒙上了一层阴影。 除了企业自…

基于Spring Boot的机场VIP客户管理系统的设计与实现(Java+spring boot+MySQL)

获取源码或者论文请私信博主 演示视频&#xff1a; 基于Spring Boot的机场VIP客户管理系统的设计与实现&#xff08;Javaspring bootMySQL&#xff09; 使用技术&#xff1a; 前端&#xff1a;html css javascript jQuery ajax thymeleaf 微信小程序 后端&#xff1a;Java s…

数据结构作业——哈夫曼树

/*【基本要求】 &#xff08;1&#xff09; 从文件中读出一篇英文文章&#xff0c;包含字母和空格等字符。 &#xff08;2&#xff09; 统计各个字符出现的频度。 &#xff08;3&#xff09; 根据出现的频度&#xff0c;为每个出现的字符建立一个哈夫曼编码&#xff0c;并输出。…

深入源码分析kubernetes informer机制(二)Reflector

[阅读指南] 这是该系列第二篇 基于kubernetes 1.27 stage版本 为了方便阅读&#xff0c;后续所有代码均省略了错误处理及与关注逻辑无关的部分。 文章目录 Reflector是什么整体结构工作流程list拉取数据缓存resync操作watch监听操作 总结 Reflector是什么 reflector在informer…

爬虫逆向实战(七)--猿人学第十六题

一、数据接口分析 主页地址&#xff1a;猿人学第十六题 1、抓包 通过抓包可以发现数据接口是api/match/16 2、判断是否有加密参数 请求参数是否加密&#xff1f; 通过查看“载荷”模块可以看出m是加密参数 请求头是否加密&#xff1f; 无响应是否加密&#xff1f; 无cook…

云聊天项目测试

前言 以下将对云聊天项目编写测试用例以及主要功能的自动化测试。 1. 测试用例的编写 2. 自动化测试 以下进行部分自动化测试用例的执行&#xff0c;检验项目功能是否符合预期。 2.1 登录功能测试 测试代码&#xff1a; 输入非法用户名或密码逻辑相似&#xff0c;不重复描…

安防监控视频汇聚平台EasyCVR视频平台调用iframe地址无法播放的问题解决方案

安防监控视频汇聚平台EasyCVR基于云边端一体化架构&#xff0c;具有强大的数据接入、处理及分发能力&#xff0c;可提供视频监控直播、云端录像、视频云存储、视频集中存储、视频存储磁盘阵列、录像检索与回看、智能告警、平台级联、云台控制、语音对讲、AI算法中台智能分析无缝…

冷冻冷藏自动化立体库|HEGERLS四向穿梭车助力打造冷链智能仓储新力量

随着中国仓储物流整体规模和低温产品消费需求的稳步增长&#xff0c;冷链市场应用潜力不断释放。而在实际运行中&#xff0c;由于冷库容量不足、基础设施落后、管理机制欠缺等原因&#xff0c;经常出现“断链”现象&#xff0c;严重威胁到产品质量和消费者安全。 河北沃克金属…

React Native expo项目修改应用程序名称

https://expo.dev/accounts/xutongbao/projects npm install --global eas-cli && \eas init --id e32cf2c0-da5b-4a65-814a-4958d58f0ca7 eas init --id e32cf2c0-da5b-4a65-814a-4958d58f0ca7 app.config.js: export default {name: 学习,slug: learn-gpt,owner: x…

Comparable和Comparator区别

Comparable和Comparator接口都是实现集合中元素的比较、排序的&#xff0c;众所周知&#xff0c;诸如Integer&#xff0c;double等基本数据类型&#xff0c;java可以对他们进行比较&#xff0c;而对于类的比较&#xff0c;需要人工定义比较用到的字段比较逻辑。总体来讲&#x…

【微服务技术二】Feign、Gateway(路由、过滤器、跨域)的初步认知

微服务技术二 五、Feign远程调用Feign替代RestTemplate自定义Feign配置方式一&#xff1a;配置文件方式&#xff1a;方式二&#xff1a;java代码方式 Feign性能优化Feign的最佳实践* 六、Gateway网关搭建网关服务路由断言工厂Route Predicate Factory路由过滤器 GatewayFilter默…

负载均衡下的 WebShell 连接

目录 负载均衡简介负载均衡的分类网络通信分类 负载均衡下的 WebShell 连接场景描述难点介绍解决方法**Plan A** **关掉其中一台机器**&#xff08;作死&#xff09;**Plan B** **执行前先判断要不要执行****Plan C** 在Web 层做一次 HTTP 流量转发 &#xff08;重点&#xff0…

排名前 6 位的数学编程语言

0 说明 任何对数学感兴趣或计划学习数学的人&#xff0c;都应该至少对编程语言有一定的流利程度。您不仅会更有就业能力&#xff0c;还可以更深入地理解和探索数学。那么你应该学习什么语言呢&#xff1f; 1.python 对于任何正在学习数学的人来说&#xff0c;Python都是一门很棒…