| |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
-> 系统运维 -> 深入理解linux内核的中断和信号 -> 正文阅读 |
|
[系统运维]深入理解linux内核的中断和信号 |
参考文章:<<linux设备驱动>>第十章节 <<linux内核之旅>>(http://www.kerneltravel.net/book/book/%E7%AC%AC%E4%B8%89%E7%AB%A0%E4%B8%AD%E6%96%AD%E6%9C%BA%E5%88%B6.pdf) 概述中断这个话题很早以前就接触过,尤其是以前接触嵌入式的时候,这项技术是为了解决io等待的问题,硬件设备io很多时候收到数据时候检查标准是高低沿变化,当发生变化的时候我们就认为收到数据,如果没有中断那么我们要写一个while循环去不停的检查一个标志位,这毫无疑问对cpu资源来说是一个浪费,于是我们便引入了中断,cpu从中断控制器IO端口接收中断事件,然后进行运行栈切换,从而避免了忙等待。 Intel x86 通过两片中断控制器 8259A 来响应 15 个外中断源 中断资源是很宝贵的,我们把和中断控制器连接的每条线称为中断线,图中从0开始编号,共有16条中断线 中断控制器的作用是: 1.监视中断线,检查产生中断请求的信号,然后把irq转化为向量,放到io端口上等待cpu读取 2.把产生的向量放到cpu的引脚上 3.cpu确认这个信号,然后把他写进可中断编程控制器 异常就是cpu内部出现中断比如: 对应的unix信号 ?中断描述符表在实地址模式中断描述符表从0开始占用1k的字节。表中的每一个表项占用四个字节,由两个字节的段地址,两个字节的偏移量组成 这些描述符可以分为3大类 任务门(Task gate) 中断门(Interrupt gate) 陷阱门(Trap gate) 系统门(System gate) 最后,在保护模式下,中断描述符表在内存的位置不再限于从地址 0 开始的地方,而是 可以放在内存的任何地方。为此,CPU 中增设了一个中断描述符表寄存器 IDTR,用来存放中 断描述符表在内存的起始地址。中断描述符表寄存器 IDTR 是一个 48 位的寄存器,其低 16 位保存中断描述符表的大小,高 32 位保存 IDT 的基址,如图 3.3 所示 中断描述符表初始化?8259A 通过两个端口来进行数据传送,,这两个端口是 0xA0 和 0xA1。代码在 /usr/src/linux-source-5.4.0/linux-source-5.4.0/arch/x86/kernel/i8259.c?
outb具体介绍见<<linux设备驱动>>,里面介绍了这个api是和硬件io交互的重要函数,也就是说通过这个函数 和中断控制器端口进行交互,从而进行初始化 当计算机运行在实模式时,IDT 被初始化并由 BIOS 使用。然而,一旦真正进入了 Linux 内核,IDT 就被移到内存的另一个区域,并进行进入实模式的初步初始化。 中断请求队列的数据结构 256个中断向量,32个分配个异常了,剩下224个作为中断向量 符,224 个 IRQ 形成一个数组 irq_desc[],其定义在/include/linux/irq.h 中: status 描述 IRQ 中断线状态的一组标志(在 irq.h 中定义),其具体含义及应用将在 do_IRQ() 函数中介绍。 handler 指向 hw_interrupt_type 描述符,这个描述符是对中断控制器的描述? action 指向一个单向链表的指针,这个链表就是对中断服务例程进行描述的 irqaction 结构, depth 如果启用这条 IRQ 中断线,depth 则为 0,如果禁用这条 IRQ 中断线不止一次,则为一 个正数。每当调用一次 disable_irq( ),该函数就对这个域的值加 1;如果 depth 等于 0, 该函数就禁用这条 IRQ 中断线。相反,每当调用 enable_irq( )函数时,该函数就对这个 域的值减 1;如果 depth 变为 0,该函数就启用这条 IRQ 中断线。 hw_interrupt_type 介绍:
中断服务例程描述符 irqaction
handler 指向一个具体 I/O 设备的中断服务例程。这是允许多个设备共享同一中断线的关键域。 flags 用一组标志描述中断线与 I/O 设备之间的关系。 SA_INTERRUPT 中断处理程序必须以禁用中断来执行。 SA_SHIRQ 该设备允许其中断线与其他设备共享。 SA_SAMPLE_RANDOM 可以把这个设备看作是随机事件发生源;因此,内核可以用它做随机数产生器(用户可以从/dev/random 和/dev/urandom 设备文件中取得随机数而访问这种特征)。 SA_PROBE 内核在执行硬件设备探测时正在使用这条中断线。 name I/O 设备名(读取/proc/interrupts 文件,可以看到,在列出中断号时也显示设备名)。 dev_id 指定 I/O 设备的主设备号和次设备号。 next 指向 irqaction 描述符链表的下一个元素。共享同一中断线的每个硬件设备都有其对应 的中断服务例程,链表中的每个元素就是对相应设备及中断服务例程的描述。 中断请求队列的初始化中断请求队列初始化发生在安装中断处理例程上,具体参见<<linux设备驱动程序>> 书里面说了两个十分重要的api
前面已经说过中断线只有16根,非常珍贵 在现在linux 代码中,中断控制器request_irq 函数被切分开了,直接看书中的request_irq实现
setup_irq
也就是简单说request_irq主要申请了一个中断服务实例,挂载到了队列上 中断处理当中断发生的时候根据中断紧急程度不同又分为 紧急的(Critical) 这样的操作诸如:中断到来时中断控制器做出应答,对中断控制器或设备控制器重新编程, 或者对设备和处理器同时访问的数据结构进行修改。这些操作都是紧急的,应该被很快地执行, 也就是说,紧急操作应该在一个中断处理程序内立即执行,而且是在禁用中断的状态下。 非紧急的(Noncritical) 这样的操作如修改那些只有处理器才会访问的数据结构(例如,按下一个键后,读扫描码)。 这些操作也要很快地完成,因此,它们由中断处理程序立即执行,但在启用中断的状态下。 3.非紧急可延迟的(Noncritical deferrable) 这样的操作如,把一个缓冲区的内容拷贝到一些进程的地址空间(例如,把键盘行缓冲 区的内容发送到终端处理程序的进程)。这些操作可能被延迟较长的时间间隔而不影响内核操 作:有兴趣的进程会等待需要的数据。非紧急可延迟的操作由一些被称为“下半部分”(bottom halves)的函数来执行 当中断发生的时候 如果在用户态,要进行用户态和内核态的切换切换到内核态 然后切换后,会从中断描述符表中找到中断描述符,然后逐条执行中断服务例程,见handle_IRQ_event
?处理完后如果有软中断,则会执行软中断
从中断返回: ret_from_intr() 终止中断处理程序。 ret_from_sys_call( ) 终止系统调用,即由 0x80 引起的异常。 ret_from_exception( ) 终止除了 0x80 的所有异常。 中断的后半部分处理机制中断可能非常多,如果一口气全部执行完,可能会用很多cpu,所以内核提供了下半部分中断处理, 内核提供了三种下半部中断 1、软中断 2、tasklet 3、work_queue 软中断一般运行在中断上下文,一般要求实时性较高,执行要短,并且是并行 tasklet 和work_queue一般用在驱动中,tasklet运行在中断上下文而且是建立在软中断上,一个tasklet只会运行在一个cpu上;work_queue运行在进程上下文 具体的不多看了,参考<<linux 设备驱动>>第10章节,里面有不错的介绍,具体的使用区别都有 总结:原理介绍完了,真做内核开发工作中,我们要记住以下几个中断要点: 1、上半部中断就是request_irq 和 free_irq 主要是这两个api,一般在kernel模块初始化和卸载的时候用,要尽量简单 2、下半部中断,软中断这个就不要用了,尽量使用tasklet和workqueue。tasklet 一般用在低延迟的任务,触发时候会关闭中断,使用的时候更不能使其阻塞睡,tasklet不能使用多喝;如果要使用多核,并且内部可能有阻塞、睡眠,那么毫无疑问,work_queue是你的首选 |
|
|
上一篇文章 下一篇文章 查看所有文章 |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 | -2024/11/15 23:41:18- |
|
网站联系: qq:121756557 email:121756557@qq.com IT数码 |