细说Linux内核中断架构
Linux 内核软中断(softirq)执行分析
Linux 内核软中断(softirq)执行分析Author: sinisterEmail: sinister@Homepage:Date: 2007-01-11本文对 Linux 内核软中断的执行流程进行了分析,并尽可能的结合当前运行环境详细地写出我的理解,但这并不表明我的理解一定正确。
这本是论坛里的一篇帖子,发出来是为了抛砖引玉,如果您在阅读本文时发现了我的错误,还望得到您的指正。
今天无意中看了眼 2.6 内核的软中断实现,发现和以前我看到的大不相同(以前也是走马观花,不大仔细),可以说改动很大。
连 softirq 的调用点都不一样了,以前是三个调用点,今天搜索了一下源代码,发现在多出了ksoftirqd 后,softirq 在系统中的调用点仅是在 ISR 返回时和使用了local_bh_enable() 函数后被调用了。
网卡部分的显示调用,我觉得应该不算是系统中的调用点。
ksoftirqd 返回去调用 do_softirq() 函数应该也只能算是其中的一个分支,因为其本身从源头上来讲也还是在 ISR 返回时irq_exit() 调用的。
这样一来就和前些日子写的那份笔记(Windows/Linux /Solaris 软中断机制)里介绍的 Linux 内核部分的软中断有出处了,看来以后讨论 Linux kernel 代码一定要以内核版本为前题,要不非乱了不可。
得买本 Linux 方面的书了,每次上来直接看相关代码也不是回事,时间也不允许。
//// do_IRQ 函数执行完硬件 ISR 后退出时调用此函数。
//void irq_exit(void){account_system_vtime(current);trace_hardirq_exit();sub_preempt_count(IRQ_EXIT_OFFSET);//// 判断当前是否有硬件中断嵌套,并且是否有软中断在// pending 状态,注意:这里只有两个条件同时满足// 时,才有可能调用 do_softirq() 进入软中断。
linux操作系统的结构及详细说明
linux操作系统的结构及详细说明linux的操作系统的结构你了解多少呢?下面由店铺为大家整理了linux操作系统的结构及详细说明的相关知识,希望对大家有帮助!linux操作系统的结构及详细说明:一、 linux内核内核是操作系统的核心,具有很多最基本功能,它负责管理系统的进程、内存、设备驱动程序、文件和网络系统,决定着系统的性能和稳定性。
Linux 内核由如下几部分组成:内存管理、进程管理、设备驱动程序、文件系统和网络管理等。
系统调用接口:SCI 层提供了某些机制执行从用户空间到内核的函数调用。
这个接口依赖于体系结构,甚至在相同的处理器家族内也是如此。
SCI 实际上是一个非常有用的函数调用多路复用和多路分解服务。
在 ./linux/kernel 中您可以找到 SCI 的实现,并在 ./linux/arch 中找到依赖于体系结构的部分。
1. 内存管理对任何一台计算机而言,其内存以及其它资源都是有限的。
为了让有限的物理内存满足应用程序对内存的大需求量,Linux 采用了称为“虚拟内存”的内存管理方式。
Linux 将内存划分为容易处理的“内存页”(对于大部分体系结构来说都是 4KB)。
Linux 包括了管理可用内存的方式,以及物理和虚拟映射所使用的硬件机制。
不过内存管理要管理的可不止 4KB 缓冲区。
Linux 提供了对 4KB 缓冲区的抽象,例如 slab 分配器。
这种内存管理模式使用 4KB 缓冲区为基数,然后从中分配结构,并跟踪内存页使用情况,比如哪些内存页是满的,哪些页面没有完全使用,哪些页面为空。
这样就允许该模式根据系统需要来动态调整内存使用。
为了支持多个用户使用内存,有时会出现可用内存被消耗光的情况。
由于这个原因,页面可以移出内存并放入磁盘中。
这个过程称为交换,因为页面会被从内存交换到硬盘上。
内存管理的源代码可以在 ./linux/mm 中找到。
2 .进程管理进程实际是某特定应用程序的一个运行实体。
Linux中断处理流程
Linux中断处理流程1. 中断处理流程 当中断发⽣时,Linux系统会跳转到asm_do_IRQ()函数(所有中断程序的总⼊⼝函数),并且把中断号irq传进来。
根据中断号,找到中断号对应的irq_desc结构(irq_desc结构为内核中中断的描述结构,内核中有⼀个irq_desc结构的数组irq_desc_ptrs[NR_IRQS]),然后调⽤irq_desc中的handle_irq函数,即中断⼊⼝函数。
我们编写中断的驱动,即填充并注册irq_desc结构。
2. 中断处理数据结构:irq_desc Linux内核将所有的中断统⼀编号,使⽤⼀个irq_desc[NR_IRQS]的结构体数组来描述这些中断:每个数组项对应着⼀个中断源(也可能是⼀组中断源),记录中断⼊⼝函数、中断标记,并提供了中断的底层硬件访问函数(中断清除、屏蔽、使能)。
另外通过这个结构体数组项中的action,能够找到⽤户注册的中断处理函数。
struct irq_desc {unsigned int irq;irq_flow_handler_t handle_irq;struct irq_chip *chip;struct msi_desc *msi_desc;void *handler_data;void *chip_data;struct irqaction *action; /* IRQ action list */unsigned int status; /* IRQ status */unsigned int depth; /* nested irq disables */unsigned int wake_depth; /* nested wake enables */unsigned int irq_count; /* For detecting broken IRQs */unsigned long last_unhandled; /* Aging timer for unhandled count */unsigned int irqs_unhandled;spinlock_t lock;const char *name;} ____cacheline_internodealigned_in_smp;(1)handle_irq:中断的⼊⼝函数(2)chip:包含这个中断的清除、屏蔽、使能等底层函数struct irq_chip {const char *name;unsigned int (*startup)(unsigned int irq);void (*shutdown)(unsigned int irq);void (*enable)(unsigned int irq);void (*disable)(unsigned int irq);void (*ack)(unsigned int irq);void (*mask)(unsigned int irq);void (*mask_ack)(unsigned int irq);void (*unmask)(unsigned int irq);void (*eoi)(unsigned int irq);void (*end)(unsigned int irq);void (*set_affinity)(unsigned int irq,const struct cpumask *dest);int (*retrigger)(unsigned int irq);int (*set_type)(unsigned int irq, unsigned int flow_type);int (*set_wake)(unsigned int irq, unsigned int on);/* Currently used only by UML, might disappear one day.*/#ifdef CONFIG_IRQ_RELEASE_METHODvoid (*release)(unsigned int irq, void *dev_id);#endif/** For compatibility, ->typename is copied into ->name.* Will disappear.*/const char *typename;};(3)action:记录⽤户注册的中断处理函数、中断标志等内容struct irqaction {irq_handler_t handler;unsigned long flags;cpumask_t mask;const char *name;void *dev_id;struct irqaction *next;int irq;struct proc_dir_entry *dir;};3. 中断处理流程总结(1)发⽣中断后,CPU执⾏异常向量vector_irq的代码;(2)在vector_irq⾥⾯,最终会调⽤中断处理C程序总⼊⼝函数asm_do_IRQ();(3)asm_do_IRQ()根据中断号调⽤irq_des[NR_IRQS]数组中的对应数组项中的handle_irq();(4)handle_irq()会使⽤chip的成员函数来设置硬件,例如清除中断,禁⽌中断,重新开启中断等;(5)handle_irq逐个调⽤⽤户在action链表中注册的处理函数。
x86 linux内核中断处理流程
x86 linux内核中断处理流程下载温馨提示:该文档是我店铺精心编制而成,希望大家下载以后,能够帮助大家解决实际的问题。
文档下载后可定制随意修改,请根据实际需要进行相应的调整和使用,谢谢!并且,本店铺为大家提供各种各样类型的实用资料,如教育随笔、日记赏析、句子摘抄、古诗大全、经典美文、话题作文、工作总结、词语解析、文案摘录、其他资料等等,如想了解不同资料格式和写法,敬请关注!Download tips: This document is carefully compiled by theeditor.I hope that after you download them,they can help yousolve practical problems. The document can be customized andmodified after downloading,please adjust and use it according toactual needs, thank you!In addition, our shop provides you with various types ofpractical materials,such as educational essays, diaryappreciation,sentence excerpts,ancient poems,classic articles,topic composition,work summary,word parsing,copy excerpts,other materials and so on,want to know different data formats andwriting methods,please pay attention!深入解析x86 Linux内核中断处理机制在计算机系统中,中断扮演着至关重要的角色,它使得硬件事件能够及时通知操作系统进行相应的处理。
10-5 Linux操作系统 - 中断、异常及系统调用
10.5.4 中断上半部分的处理 一、 中断控制器 •每个硬件设备控制器都能通过中断请求线 发出中断请求(简称IRQ) •所有设备的中断请求线又连到中断控制器 的输入端。 •在x86单CPU的机器上采用两个8259A芯片作 为中断控制器,一主一从。
•当8259A有中断信号输入同时中断信号不被 屏蔽时,主8259A向CPU发出 INT信号,请求 中断。这时如果CPU是处于允许中断状况, CPU就会发信号给8259A进入中断响应周期。 •在对8259A芯片的初始化过程中,第n号中 断在IDT表中的向量号为 n+32
•IDT中向量号的使用情况如下: 0-31 异常与非屏蔽中断使用。 32-47 可屏蔽中断使用32至47 128(0x80)实现系统调用。 其余 未使用 •保存现场 发生异常时在核心栈的程序计数器eip的 值取决于具体情况。一般情况下eip保存的 下一条指令的地址,但对于页面异常,保存 的产生异常的这条指令的地址而不是下一条 指令的地址
中断向量表IDT •IDT是中断/异常处理在内核的入口。IDT表 项还记录了一些其它信息用以安全检查。 •IDT在系统初始化时创建。 •每个中断/异常都有一个向量号,该号的值 在0-255之间,该值是中断/异常在IDT中的 索引。 •每个中断/异常均有其相应的处理函数,中 断/异常在使用前必须在IDT中注册信息以保 证发生中断/异常时能找到相应的处理函数。
struct hw_interrupt_type { const char * typename; unsigned int (*startup)(unsigned int irq); void (*shutdown)(unsigned int irq); void (*enable)(unsigned int irq); void (*disable)(unsigned int irq); void (*ack)(unsigned int irq); void (*end)(unsigned int irq); void (*set_affinity)(unsigned int irq, unsigned long mask); };
linux中断处理流程
linux中断处理流程Linux中断处理流程Linux中断处理是操作系统中的一个重要组成部分,用于响应硬件设备的事件。
在Linux中,中断可以是外部中断,如硬件设备发送的中断信号,也可以是内部中断,如软件产生的异常或系统调用。
中断处理的目的是及时响应硬件设备的事件,并采取相应的措施来处理这些事件。
一、中断的触发中断是由硬件设备发送的一个信号,用于通知操作系统某个事件的发生。
这个信号可以是一个电平的变化,一个特定的数据包,或者一个指定的硬件寄存器的变化。
当硬件设备检测到某个事件发生时,它会向处理器发送一个中断信号,处理器会立即停止当前正在执行的任务,保存当前的上下文,并跳转到中断处理程序的入口点。
二、中断处理程序的执行中断处理程序是一个特殊的函数,负责处理中断事件。
当中断发生时,处理器会跳转到中断处理程序的入口点,并执行相应的代码。
中断处理程序的执行过程可以分为以下几个步骤:1. 保存上下文:在执行中断处理程序之前,处理器需要保存当前任务的上下文,包括程序计数器、寄存器和堆栈指针等。
这样可以确保在中断处理程序执行完成后,能够正确地返回到原来的任务。
2. 中断处理程序的执行:一旦保存了上下文,处理器就会执行中断处理程序的代码。
中断处理程序根据中断的类型,执行相应的操作。
例如,对于外部中断,中断处理程序可能需要读取硬件设备的状态,处理数据包或执行特定的操作。
对于内部中断,中断处理程序可能需要处理异常或系统调用。
3. 中断处理程序的结束:当中断处理程序执行完成后,处理器会恢复之前保存的上下文,并将控制权返回给原来的任务。
这样原来的任务就可以继续执行,而不会受到中断的影响。
三、中断处理的优先级在Linux中,中断处理有不同的优先级。
这是为了确保对于紧急事件的及时处理。
中断的优先级由硬件设备决定,通常是通过一个优先级编码器来实现的。
当多个中断同时发生时,处理器会按照优先级的顺序来处理中断。
高优先级的中断会立即被处理,而低优先级的中断则会被推迟到稍后处理。
中断处理流程
中断处理流程linux中断处理浅析最近在研究异步消息处理, 突然想起linux内核的中断处理, ⾥⾯由始⾄终都贯穿着"重要的事马上做, 不重要的事推后做"的异步处理思想. 于是整理⼀下~第⼀阶段--获取中断号每个CPU都有响应中断的能⼒, 每个CPU响应中断时都⾛相同的流程. 这个流程就是内核提供的中断服务程序.在进⼊中断服务程序时, CPU已经⾃动禁⽌了本CPU上的中断响应, 因为CPU不能假定中断服务程序是可重⼊的.中断处理程序的第⼀步要做两件事情:1. 将中断号压⼊栈中; (不同中断号的中断对应不同的中断服务程序⼊⼝)2. 将当前寄存器信息压⼊栈中; (以便中断退出时恢复)显然, 这两步都是不可重⼊的(如果在保存寄存器值时被中断了, 那么另外的操作很可能就把寄存器给改写了, 现场将⽆法恢复), 所以前⾯说到的CPU进⼊中断服务程序时要⾃动禁⽌中断.栈上的信息被作为函数参数, 调⽤do_IRQ函数.第⼆阶段--中断串⾏化进⼊do_IRQ函数, 第⼀步进⾏中断的串⾏化处理, 将多个CPU同时产⽣的某⼀中断进⾏串⾏化.其⽅法是如果当前中断处于"执⾏"状态(表明另⼀个CPU正在处理相同的中断), 则重新设置它的"触发"标记, 然后⽴即返回. 正在处理同⼀中断的那个CPU完成⼀次处理后, 会再次检查"触发"标记, 如果设置, 则再次触发处理过程.于是, 中断的处理是⼀个循环过程, 每次循环调⽤handle_IRQ_event来处理中断.第三阶段--关中断条件下的中断处理进⼊handle_IRQ_event函数, 调⽤对应的内核或内核模块通过request_irq函数注册的中断处理函数.注册的中断处理函数有个中断开关属性, ⼀般情况下, 中断处理函数总是在关中断的情况下进⾏的. ⽽调⽤request_irq注册中断处理函数时也可以设置该中断处理函数在开中断的情况下进⾏,这种情况⽐较少见, 因为这要求中断处理代码必须是可重⼊的. (另外, 这⾥如果开中断, 正在处理的这个中断⼀般也是会被阻塞的. 因为正在处理某个中断的时候, 硬件中断控制器上的这个中断并未被ack, 硬件不会发起下⼀次相同的中断.)中断处理函数的过程可能会很长, 如果整个过程都在关中断的情况下进⾏, 那么后续的中断将被阻塞很长的时间.于是, 有了soft_irq. 把不可重⼊的⼀部分在中断处理程序中(关中断)去完成, 然后调⽤raise_softirq 设置⼀个软中断, 中断处理程序结束. 后⾯的⼯作将放在soft_irq⾥⾯去做.第四阶段--开中断条件下的软中断上⼀阶段循环调⽤完当前所有被触发的中断处理函数后, do_softirq函数被调⽤, 开始处理软件中断.在软中断机制中, 为每个CPU维护了⼀个若⼲位的掩码集, 每位掩码代表⼀个中断号. 在上⼀阶段的中断处理函数中, 调⽤raise_softirq设置了对应的软中断, 到了这⾥, 软中断对应的处理函数就会被调⽤(处理函数由open_softirq函数来注册).可以看出, 软中断与中断的模型很类似, 每个CPU有⼀组中断号, 中断有其对应的优先级, 每个CPU处理属于⾃⼰的中断. 最⼤的不同是开中断与关中断.于是, ⼀个中断处理过程被分成了两部分, 第⼀部分在中断处理函数⾥⾯关中断的进⾏, 第⼆部分在软中断处理函数⾥⾯开中断的进⾏.由于这⼀步是在开中断条件下进⾏的,这⾥还可能发⽣新的中断(中断嵌套),然后新中断对应的中断处理⼜将开始⼀个新的第⼀阶段~第三阶段。
Linux内核裁剪与编译
创建一个用于编译的内核目录,并配置相应的环境变量。
内核配置与选择
配置内核
01
使用make menuconfig或其他配置工具进行内核配置,选择所
需的特性和功能。
定制内核
02
根据实际需求,禁用不必要的模块和功能,以减小内核体积。
配置参数
03
在编译过程中,根据需要设置编译参数,如优化级别、编译器
选项等。
编译过程与注意事项
执行编译
在配置完成后,执行make命令开始 编译内核。
等待编译完成
编译过程可能需要较长时间,取决于 系统性能和内核大小。
注意事项
在编译过程中,注意观察日志信息, 以便及时发现和解决问题。
内核安装
编译完成后,按照系统要求进行内核 安装和引导配置。
04
内核编译优化
编译优化简介
-O3
在`-O2`的基础上,进一步开启更多的编译器优化选项。
-Os
以最小化代码大小为目标进行优化,适用于嵌入式系统等资源受限的环境。
-fPIC
生成位置无关代码,便于动态链接。
编译优化实践
根据目标硬件平台和性能 需求,选择合适的编译选 项。
关注内核代码质量,避免 过度优化导致代码可读性 和维护性下降。
优化内核
针对特定需求进行内核优化,如调整调度 策略、优化内存管理等,以提高系统的性 能和响应速度。
定制内核
根据需求分析结果,定制内核的功能和参 数,如禁用不必要的模块、开启特定功能 等。
案例三:使用第三方工具进行内核裁剪与编译
总结词
选择合适的第三方 工具
配置工具链
导入内核源码
自动裁剪与编译
使用第三方工具进行内 核裁剪与编译,可以借 助第三方工具的自动化 和智能化功能,提高内 核裁剪与编译的效率和 准确性。
linux 软中断原理
linux 软中断原理Linux软中断是操作系统中一种用于处理紧急任务的机制。
它采用的是一种特殊的中断方式,可以在用户态和内核态之间切换,以提供高效的中断处理能力。
在Linux内核中,软中断是一种特殊的中断处理机制。
相比硬中断,软中断的处理过程更加高效,可以在短时间内完成中断处理,并且不会占用过多的系统资源。
软中断的原理是通过将中断处理函数放入一个队列中,然后由内核线程负责依次执行队列中的中断处理函数。
在Linux内核中,每个软中断都有一个唯一的标识符,并且有一个对应的中断处理函数。
当某个软中断被触发时,中断处理函数会被调用。
这样,操作系统就可以根据不同的软中断来执行相应的中断处理操作。
软中断的使用可以提高系统的响应速度和处理能力。
在Linux内核中,有一些常用的软中断,如定时器中断、网络中断等。
这些软中断可以及时地处理系统中的紧急任务,并且不会对系统的正常运行产生太大的影响。
软中断的原理是基于内核线程的机制实现的。
在Linux内核中,有一个特殊的内核线程,称为软中断处理线程。
这个线程会不断地检查软中断队列,如果队列中有待处理的中断,就会调用相应的中断处理函数。
软中断的实现需要考虑到多核处理器的情况。
在多核处理器中,每个CPU核心都有自己的软中断处理队列和软中断处理线程。
这样,每个CPU核心都可以独立地处理软中断,提高系统的并发处理能力。
软中断的使用可以提高系统的可靠性和稳定性。
在Linux内核中,软中断可以用于处理系统中的紧急任务,如定时器中断、网络中断等。
这些紧急任务需要及时地处理,以保证系统的正常运行。
Linux软中断是一种高效的中断处理机制,可以提高系统的响应速度和处理能力。
它通过将中断处理函数放入一个队列中,然后由专门的内核线程负责执行,可以及时地处理系统中的紧急任务,并且不会对系统的正常运行产生太大的影响。
通过软中断的使用,可以提高系统的可靠性和稳定性,保证系统的正常运行。
软件中断机制的概念和实例
软件中断机制的概念和实例一、前言软件中断机制在现代操作系统和编程语言中的使用十分普遍,是保证计算机正常工作的基础性机制之一。
本文主要介绍了软件中断机制的基本概念、实现方式和实例,希望能够对读者有所帮助。
二、概念软件中断是一种由计算机软件向处理器发送的输入信号,用于打断当前正在运行的程序,并切换到特定的代码段执行特定的指令处理器。
在实际应用中,软件中断通常用于响应一些外部事件或信号,如来自键盘、鼠标、网络等输入以及操作系统内部的系统调用等。
软件中断机制主要包括中断请求、中断响应和中断处理三个部分。
当一个设备产生了中断请求信号时,计算机中断控制器会通知处理器并将中断请求号发送给处理器。
处理器接收到中断请求后,会中止当前正在执行的程序,并将处理器状态保存到寄存器或堆栈中。
接下来,处理器会根据中断请求号查找中断向量表,并跳转到相应的中断处理程序中执行特定的指令,处理完中断后再恢复处理器状态,返回到原来的程序中继续执行。
三、实现方式在不同的编程语言、操作系统和硬件平台上,软件中断机制的实现方式会有所不同。
下面是一些常见的软件中断机制的实现方式。
1.软中断软中断是一种在操作系统内部使用的中断机制,可用于实现系统调用等功能。
在Linux内核中,软中断使用了一组与硬件中断类似的数据结构,包括中断处理函数、中断处理队列、向量表对应数组等。
当需要执行系统调用时,用户态程序会通过软中断接口发起请求,内核会将该请求加入到软中断队列中,随后中断处理程序会处理该请求,最终返回执行结果。
2.信号信号是一种轻量级的软件中断机制,可以用来发送各种事件通知、异常处理等。
在Unix和Linux系统中,用户可以通过kill、sigaction等系统调用发送和接收信号,操作系统会将信号加入到信号处理队列中,并由信号处理程序处理相应的事件。
对于一些信号,如SIGSEGV(段错误)、SIGINT(中断信号)等,操作系统会默认采取一些预先定义好的处理方式,如向进程发送杀死进程、终止进程、跳转到异常处理程序等。
Linux系统用户态和内核态
Linux 系统⽤户态和内核态Unix/Linux 的体系架构如上图所⽰,从宏观上来看,Linux 操作系统的体系架构分为⽤户态和内核态(或者⽤户空间和内核空间)。
内核从本质上看是⼀种软件-----控制计算机的硬件资源,并提供上层应⽤程序运⾏的环境。
⽤户态即上层应⽤程序的活动空间,应⽤程序的执⾏必须依托于内核提供的资源,包括CPU 资源、存储资源、I/O 资源等。
为了使上层应⽤能够访问到这些资源,内核必须为上层应⽤提供访问的接⼝:。
简单来说::运⾏在内核空间的进程的状态:运⾏在⽤户空间的进程的状态系统调⽤是操作系统的最⼩功能单位,这些系统调⽤根据不同的应⽤场景可以进⾏扩展和裁剪,现在各种版本的Unix 实现都提供了不同数量的系统调⽤,如Linux 的不同版本提供了240-260个系统调⽤,FreeBSD ⼤约提供了320个。
我们可以把系统调⽤看成是⼀种不能再化简的操作(类似于原⼦操作,但是不同概念),有⼈把它⽐作⼀个汉字的⼀个“笔画”,⽽⼀个“汉字”就代表⼀个上层应⽤,我觉得这个⽐喻⾮常贴切。
⼀个汉字有很多笔画组成,因此有时候如果要实现⼀个完整的汉字就必须调⽤很多的系统调⽤。
这有时是⼀件很崩溃的事情,⽐如说这个字,你可能认识,但是有⼏个⼈会写呢?:系统调⽤的封装应⽤程序直接使⽤系统调⽤,这势必会加重程序员的负担,良好的程序设计⽅法是:重视上层的业务逻辑操作,⽽尽可能避免底层复杂的实现细节。
那么有没有优化空间呢?库函数正是为了将程序员从复杂的细节中解脱出来⽽提出的⼀种有效⽅法。
它实现对系统调⽤的封装,将简单的业务逻辑接⼝呈现给⽤户,⽅便⽤户调⽤,从这个⾓度上看,库函数就像是组成汉字的“偏旁”。
这样的⼀种组成⽅式极⼤增强了程序设计的灵活性,对于简单的操作,我们可以直接调⽤来访问资源,如“⼈”;对于复杂操作,我们借助于来实现,如“仁”。
库函数依据不同的标准也可以有不同的实现版本,如ISOC 标准库,POSIX 标准库等。
Linux内核中的时钟中断tic...
第七章 Linux内核的时钟中断(By 詹荣开,NUDT)Copyright © 2003 by 詹荣开E-mail:***************Linux-2.4.0Version 1.0.0,2003-2-14摘要:本文主要从内核实现的角度分析了Linux 2.4.0内核的时钟中断、内核对时间的表示等。
本文是为那些想要了解Linux I/O子系统的读者和Linux驱动程序开发人员而写的。
关键词:Linux、时钟、定时器申明:这份文档是按照自由软件开放源代码的精神发布的,任何人可以免费获得、使用和重新发布,但是你没有限制别人重新发布你发布内容的权利。
发布本文的目的是希望它能对读者有用,但没有任何担保,甚至没有适合特定目的的隐含的担保。
更详细的情况请参阅GNU通用公共许可证(GPL),以及GNU自由文档协议(GFDL)。
你应该已经和文档一起收到一份GNU通用公共许可证(GPL)的副本。
如果还没有,写信给:The Free Software Foundation, Inc., 675 Mass Ave, Cambridge,MA02139, USA欢迎各位指出文档中的错误与疑问。
前言时间在一个操作系统内核中占据着重要的地位,它是驱动一个OS内核运行的“起博器”。
一般说来,内核主要需要两种类型的时间:1. 在内核运行期间持续记录当前的时间与日期,以便内核对某些对象和事件作时间标记(timestamp,也称为“时间戳”),或供用户通过时间syscall进行检索。
2. 维持一个固定周期的定时器,以提醒内核或用户一段时间已经过去了。
PC机中的时间是有三种时钟硬件提供的,而这些时钟硬件又都基于固定频率的晶体振荡器来提供时钟方波信号输入。
这三种时钟硬件是:(1)实时时钟(Real Time Clock,RTC);(2)可编程间隔定时器(Programmable Interval Timer,PIT);(3)时间戳计数器(Time Stamp Counter,TSC)。
ARM Linux对中断的处理
void (*bus_lock)(unsigned int irq);
void (*bus_sync_unlock)(unsigned int irq);
/* Currently used only by UML, might disappear one day.*/
kstat_irqs: irq stats per cpu
irq_2_iommu: iommu with this irq
handle_irq:高层的irq时间处理程序(如果为NULL,则默认调用__do_IRQ())
chip:底层的中断硬件访问,指向PIC对象(irq_chip结构),它服务于IRQ线,Linux中断管理系统使用该成员来进行中断控制器的访问。
struct proc_dir_entry *dir;
#endif
const char *name;
}____cacheline_internodealigned_in_smp;
irq_desc结构体(中断描述符)中各个字段说明:
irq:中断描述符的中断号
timer_rand_state: pointer to timer rand state struct
#endif
irq_flow_handler_t handle_irq;
struct irq_chip *chip;
struct msi_desc *msi_desc;
void *handler_data;
void *chip_data;
struct irqaction *action; /* IRQ action list */
linux内核中断处理的irq_thread机制
Linux内核中断处理的irq_thread机制是一种将中断处理任务分配给单独线程的方法,以提高Linux内核中断处理的irq_thread机制是一种将中断处理任务分配给单独线程的方法,以提高系统的性能和响应速度。
在传统的中断处理模型中,中断处理程序(IRQ handler)是在中断发生时由内核直接调用的,这会导致CPU上下文切换,从而影响系统性能。
而使用irq_thread机制,可以将中断处理任务分配给一个专门的线程来执行,从而减少上下文切换的次数,提高系统的响应速度。
irq_thread机制的主要步骤如下:
1. 当中断发生时,内核首先将中断处理程序标记为可运行状态。
2. 然后,内核启动一个新的线程来执行这个中断处理程序。
这个线程通常被称为irq_thread。
3. irq_thread线程在执行过程中会调用do_IRQ()函数来处理实际的中断事件。
4. do_IRQ()函数会根据中断类型调用相应的硬件抽象层(HAL)中的处理函数,以完成对硬件设备的操作。
5. 最后,irq_thread线程会返回到用户空间,继续执行之前的程序。
通过使用irq_thread机制,Linux内核可以在多个处理器核心之间实现高效的中断处理,从而提高系统的整体性能。
同时,这种机制还可以简化中断处理程序的设计,使其更加模块化和易于维护。
Linux内核组成和架构
统 是 如 何 实现 的 。
低
进程管理
Li x 内核 支 持 所 谓 的 多任 务 运 行 nu ( lirga mut o rmmig ,即 可以 有 多个 用 户 p n) 程 序 同时 运 行 ,用 户 可 以 一 边 听 音乐 一 边 写 文档 。为 了 在一 个 单 C U的 系 统 中 支持 P 多任 务 , iu Ln x内核 使 用 了进 程 的概 念 ( 内
(hr u h u ) t o g p t。
增 加 而 线 性 增 加 。 在 2. 开 发 版 本 中 , 5
S f a r 0785 即 ow rWol 20.. t e d
维普资讯
o p ue eS r 圃 n。C
Ln x内核 采 用 了 由 Ig la 开 发 的 0 L iu n o Mon r () 调 实 现 了 sl 分 配 器 很 好 地 解 决 了 这 些 问题 。 ab 度 器 。 O 1调 度 器采 用 一 个链 表 数 组 ,根据 进 程 S a () l b分 配 器以 对 象 为单 位进 行 管 理 ,把 不 同的 的 优 先 级 把 进 程 放 进 不 同 的 链 表 中 ,每 次 调 度 对 象 组织 在 不 同 的 C c e 。这 种 方式 很 好地 解 ah 中 时 ,总是 从 优先 级 最 高 的链 表 中取 出第 一 个 进 程 决 了内 存浪 费 的 问 题 ,同时 又 能快 速 的分 配 各 种 来 运 行 。 同时 使用 一 个位 图表 (i p bt ma )来记 录 不 同大 小 的 对 象 。 每 一 个 优先 级 链表 中是 否 有可 运 行 的 进程 ,搜 寻 这 张 位 图表 就 可 以找 到 优先 级 最 高 的 链表 。0() 1
IA32上Linux内核中断机制分析
427callsmp_/**/name;\
428jmpret_from_intr;
其中,SAVE_ALL宏就是用来保存寄存器的。
内核书籍中经常提到的中断上下文,指的是内核正在运行中断服务程序或softirq,无法代表当前进程的情形。中断上下文没有自己专有的堆栈,相反,它借用被中断进程的内核堆栈──IA-32上的Linux默认这个堆栈只有8k大小,而且很可能在处理中断的过程中又被另一个中断源中断。因此如果你自己编写中断处理程序,递归层次太深或者函数局部变量太大,都有可能导致栈溢出。(i386有一个4KStacks补丁,如果编译时打开该选项,则中断上下文使用独立的栈,而不占用被中断进程的。)
2)陷阱(Trap)。陷阱处理返回时,不重新执行引发陷阱的那条指令。
3)中止(Abort)。中止是严重的异常,将导致任务的中止而不会返回。
还有一种是程序产生的异常,如INT3指令、BOUND指令等。CPU把这种异常当作是陷阱来处理。
5,中断描述表IDT
异常与中断发生时,都需要到IDT中查找相关信息,以找到对应的处理程序以及其他动作。需要注意的是,保护模式下发生权限提升时,中断穿越的是中断门,而异常穿越的是陷阱门。二者的区别是:当CPU穿越中断门时,是自动关中断的;而穿越异常门则不会。
return1;
}
spin_lock(&desc->lock);
desc->handler->ack(irq);/*给i8259A或APIC应答信号*/
/*
*REPLAYiswhenLinuxresendsanIRQthatwasdroppedearlier
*WAITINGisusedbyprobetomarkirqsthatarebeingtested
linux的irq中断子系统分析
本文以Linux中断子系统架构为视角,旨在提供一个对Linux中断系统的全局认识,不涉及具体实现细节。
一、Linux中断子系统架构在Linux中断子系统(generic irq)出现之前,内核使用__do_IRQ处理所有的中断,这意味着__do_IRQ中要处理各种类型的中断,这会导致软件的复杂性增加,层次不分明,而且代码的可重用性也不好。
通用中断子系统的原型最初出现于ARM体系中,一开始内核的开发者们把3种中断类型区分出来(电平中断、边缘中断、简易中断),后来又针对某些需要回应eoi(end of interrupt)的中断控制器,加入了fast eoi type,针对smp加入了per cpu type。
把这些不同的中断类型抽象出来后,成为了中断子系统的流控层。
要使所有的体系架构都可以重用这部分的代码,中断控制器也被进一步地封装起来,形成了中断子系统中的芯片级硬件封装层。
二、芯片级硬件封装层中断系统与CPU硬件关系密切,linux系统为了兼容各种型号的CPU,提供了对于各种CPU的特性及其中断控制器的底层封装,这样就可以把底层的硬件实现尽可能地隐藏起来,使得驱动程序的开发人员不用关注底层的实现。
该部分主要工作是:●实现不同CPU的中断入口,初始化中断向量表,该部分通常由汇编实现。
●对中断控制器实现软件抽象(struct irq_chip),源码路径如:”arch/arm/plat-s3c24xx/irq.c”该部分初始化过程中,系统根据设备使用的中断控制器的类型,实现irq_chip结构中的接口,并把该irq_chip实例注册到irq_desc.irq_data.chip字段中,这样各个irq和中断控制器就进行了关联,只要知道irq编号,即可得到对应到irq_desc结构,进而可以通过chip指针访问中断控制器。
其初始化流程如下图所示:三、中断流控层由linux内核提供,所谓中断流控是指合理并正确地处理连续发生的中断,比如一个中断在处理中,同一个中断再次到达时如何处理,何时应该屏蔽中断,何时打开中断,何时回应中断控制器等一系列的操作。
linux内核中断处理流程
Linux内核中断处理流程一、中断概述在计算机系统中,中断是一种重要的机制,它允许处理器暂停当前的程序执行,转而处理更为紧急的事件。
Linux内核作为操作系统的核心,负责管理和处理系统中的各种中断。
中断可以分为外中断(硬件中断)和内中断(软件中断或陷阱),它们在Linux内核中有不同的处理流程。
二、中断处理流程1. 中断请求(IRQ)的接收当中断控制器接收到一个外部设备的中断请求时,它会根据优先级等信息决定是否向CPU发送中断信号。
如果决定发送,CPU会暂停当前的执行流程,开始中断处理。
2. 中断向量的确定每个中断都有一个唯一的中断向量与之对应。
中断向量是中断处理程序的入口点。
在x86架构中,中断向量表(Interrupt Descriptor Table,IDT)存储了系统中所有中断处理程序的地址信息。
CPU根据中断向量从IDT中找到对应的中断处理程序入口。
3. 中断处理程序的执行一旦确定了中断处理程序的入口点,CPU会跳转到该程序并执行。
中断处理程序通常被称为中断服务例程(Interrupt Service Routine,ISR)。
ISR负责处理中断事件,如读取设备数据、更新系统状态等。
4. 中断上下文的保存与恢复在执行ISR之前,CPU需要保存当前执行上下文(包括寄存器状态、程序计数器等),以便在中断处理完成后能够恢复到原来的执行状态。
同样,当中断处理完成时,CPU需要恢复被中断程序的执行上下文。
5. 嵌套中断的处理在某些情况下,一个中断处理程序可能会被另一个更高优先级的中断打断。
这种情况称为嵌套中断。
Linux内核通过中断优先级管理和中断屏蔽等技术来处理嵌套中断,确保系统的稳定性和实时性。
6. 中断结束与返回当中断处理程序执行完毕时,它会通过一条特殊的指令(如iret在x86架构中)来通知CPU中断处理已完成。
CPU随后会恢复被中断程序的执行上下文,并继续执行被中断的程序。
三、软件中断(软中断)和任务调度除了硬件中断外,Linux内核还支持软件中断(Softirqs)和任务调度(Tasklets)机制。
中断服务程序基本框架
中断服务程序基本框架
中断服务程序是操作系统中非常重要的部分,它允许计算机在执行程序的过程中,响应来自外部设备的事件。
中断服务程序通常由操作系统内核编写,其基本框架包括以下步骤:
1. 确定中断类型:中断可以分为硬件中断和软件中断,操作系统需要根据中断类型来确定下一步的操作。
2. 保存寄存器状态:在进入中断服务程序之前,操作系统需要将当前处理器状态保存,在处理完中断后再恢复。
3. 执行中断服务程序:根据中断类型,执行相应的中断服务程序代码,完成对外部事件的响应。
4. 恢复寄存器状态:在中断服务程序执行完毕后,需要将先前保存的处理器状态恢复,以便程序可以继续执行。
5. 返回中断源:在完成中断处理后,操作系统需要返回到中断源,继续执行原来的程序。
在实际编写中断服务程序时,需要考虑多种情况和异常情况,例如优先级处理、中断嵌套、中断重入等。
因此,中断服务程序的编写需要考虑周全,并进行充分的测试和验证,以确保系统的可靠性和稳定性。
- 1 -。
linux内核开发面试题
linux内核开发面试题一、简介Linux内核是开源操作系统Linux的核心组成部分,负责管理计算机的硬件资源并提供各种系统服务。
Linux内核开发面试题是在面试过程中常见的一种考察方式,用于评估面试者对Linux内核的理解与掌握程度。
二、常见面试题1. 请简述Linux内核的架构及其组成部分。
2. 什么是进程和线程?它们在Linux内核中的实现方式是什么?3. 请解释虚拟内存的概念,并描述它在Linux内核中的实现原理。
4. Linux内核采用的调度算法有哪些?请分别介绍它们的特点。
5. 请描述Linux内核中的文件系统及其实现原理。
6. 什么是系统调用?请举例说明Linux内核中常用的系统调用接口。
7. 请解释Linux内核中的中断处理机制,并描述硬中断和软中断的区别。
8. 请简述Linux内核的设备驱动模型,并介绍驱动程序的开发流程。
9. 请阐述Linux内核的网络子系统及其组件,包括网络协议栈、套接字和网络设备驱动等。
10. 在进行Linux内核开发时,经常使用的调试技术有哪些?请简要说明它们的作用。
三、回答示范1. Linux内核的架构及组成部分Linux内核的架构主要由五个模块组成,分别是进程管理、内存管理、文件系统、设备驱动和网络子系统。
其中,进程管理模块负责创建、调度和销毁进程,内存管理模块负责管理系统的内存资源,文件系统模块提供了对文件和目录的操作接口,设备驱动模块负责管理硬件设备的访问,网络子系统模块提供了网络通信功能。
2. 进程和线程及其实现方式进程是计算机中正在运行的程序的实例,拥有独立的内存空间和执行上下文。
线程是进程内的一个执行单元,共享进程的资源。
在Linux 内核中,进程通过task_struct结构来表示,线程则通过clone系统调用来创建。
3. 虚拟内存的概念及实现原理虚拟内存是一种对物理内存的抽象和扩展,它为每个进程提供了独立的地址空间。
Linux内核通过页表将虚拟地址映射到物理地址,并采用页面置换算法(如LRU)来管理内存的使用。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
细说Linux内核中断架构分类:网络Unix/Linux内核学习2012-06-14 17:59 38人阅读评论(0) 收藏举报中断和异常一、什么是中断?中断通常被定义为一个事件,该事件改变处理器执行的指令顺序。
这样的事件与CPU芯片内外部硬件电路产生的电信号相对应。
中断通常分为同步中断和异步中断:²同步中断是当指令执行时由CPU控制单元产生的,之所以称为同步,是因为只有在一条指令终止执行后CPU才会发出中断。
◎异步中断是由其他硬件设备依照CPU时钟信号随机产生的。
在Intel微处理器手册中:◎把同步中断称为异常(exception)◎把异步中断称为中断(interrupt)这两类中断的共同特点是什么?如果CPU当前不处于核心态,则发起从用户态到核心态的切换。
接下来,在内核中执行一个专门的例程,称为中断服务例程(interrupt service routine)。
或中断处理程序(interrupthandler)另一方面,异常是由程序的错误产生的,或者是由内核必须处理的异常条件产生的。
第一种情况下,内核通过发送一个每个Unix/Linux程序员都熟悉的信号来处理异常。
第二种情况下,内核执行恢复异常需要的所有步骤,例如缺页异常等。
二、中断信号的作用中断信号提供了一种特殊的方式,使处理器转而去运行正常控制流之外的代码。
当一个中断信号达到时,CPU必须停止它当前正在做的事情,并且切换到一个新的活动。
为了这做到这一点,就要在内核态堆栈保存程序计数器的当前值(即EIP和CS寄存器的内容),并把与中断类型相关的一个地址放进程序计数器。
这可能会让我们想起系统调度的进程切换,发生在内核用一个进程替换另一个进程时。
但是中断处理与进程切换有一个明显的差异:由中断或异常处理程序执行的代码不是一个进程。
更准确的说,它是一个内核控制路径,代表中断发生时正在运行的进程执行。
作为一个内核控制路径,中断处理程序比一个进程要“轻”(中断的上下文很少,建立或终止中断处理需要的时间也很少)中断处理是由内核执行的最敏感的任务之一,因为它必须满足下列约束:◎当内核正打算去完成一些别的事情时,中断随时会到来。
因此,内核的目标就是让中断尽可能快地处理完,尽其所能把更多的处理向后推迟。
因此,内核响应中断后需要进行的操作分为两部分:关键而紧急的部分,内核立即执行;其余推迟的部分,内核随后执行。
◎因为中断随时会到来,所以内核可能正在处理其中的一个中断时,另一个不同类型的中断又发生了。
内核应该尽可能地允许这种情况发生,因为这能维持更多的I/O设备得到处理的机会。
因此,中断处理程序必须编写成使相应的内核控制路径能以嵌套的方式执行。
当最后一个内核控制路径终止时,内核必须能恢复被中断进程的执行,或者,如果中断信号已导致了重新调度,内核也应能切换到另外的进程。
◎尽管内核在处理前一个中断时可以接受一个新的中断,但在内核代码中还是存在一些临界区,在临界区中,中断必须被禁止。
必须尽可能地限制这样的临界区,因为根据以前的要求,内核,尤其是中断处理程序,应该在大部分时间内以开中断的方式运行。
三、IRQ和中断中断这个名词使用得并不是很谨慎,为什么?由于中断是用来表示由CPU和外部硬件发出的信号所产生的。
但是中断不能由处理器外部的外设直接产生,而必须借助于一个称为可编程中断控制器(programmable interrupt controller)的标准组件来请求,该组件存在于每个系统中。
外部设备,会有电路连接到用于向中断控制器发送中断请求的组件。
控制器在执行了各种电工任务之后,将中断请求转发到CPU的中断输入中。
因为外部设备不能直接发出中断,而必须通过中断控制器的标准组件来请求中断,所以这种请求更正确的叫法是IRQ,或中断请求(Interrupt Request)。
每个能够发出中断请求的硬件设备控制器都有这么一条名为IRQ的输出线。
所有现有的IRQ 线都会与这个中断控制器(PIC)的硬件电路的输入引脚相连。
下面来看看这种中断控制器执行下列动作:1) 监视IRQ线,检查产生的信号。
如果有一条或两条以上的IRQ线上产生信号,就选择引脚编号较小的IRQ线。
2) 如果一个引发信号出现在IRQ线上:a) 把接收到的引发信号转换成对应的向量(索引)。
b) 把这个向量存放在中断控器的一个I/O端口,从而允许CPU通过数据总线读取此向量。
c) 把引发信号发送到处理器的INTR引脚,即产生一个中断。
d) 等待,直到CPU通过把这个中断信号写进可编程中断控制器的一个I/O端口来确认它;当这种情况发生时,清INTR线。
3) 返回到第一步。
IRQ线是从0开始顺序编号的,因此,第一条IRQ线通常表示成IRQ0。
与IRQn关联的Intel 缺省向量是n+32。
如前所述,通过向中断控制器端口发布合适的指令,就可以修改IRQ和向量之间的映射。
可以有选择地禁止每条IRQ线。
因此,可以对PIC编程从而禁止IRQ,也就是说,可以告诉PIC停止对给定的IRQ线发布中断,或者激活它们,禁止的中断是丢失不了的,它们一旦激活,PIC就又把它们发送到CPU。
这个特点被大多数中断处理程序使用,因为这允许中断处理程序逐次地处理同一类型的IRQ。
(一)处理中断在CPU得知发生中断后,它将进一步的处理委托给一个软件例程,该例程可能会修复故障、提供专门的处理或将外部事件通知用户进程。
由于每个中断和异常都有唯一的编号,内核使用一个数组项是指向处理程序函数的指针。
相关的中断号根据数组项在数组中位置判断。
如下图所示:1、进入和退出任务如下图,中断处理划分为3部分。
首先,必须建立一个适当的环境,使得处理程序函数能够在其中执行,接下来调用处理程序自身,最后将系统复原到中断之前的状态。
调用中断处理程序前后的两部分,分别称为进入路径和退出路径。
进入和退出任务还负责确保处理器从用户态切换到核心态。
进入路径的一个关键任务是,从用户态栈切换到核心态栈。
但是这一点还不够。
因为内核还要使用CPU资源执行其代码,进入路径必须保存用户应用程序当前的寄存器,以便在中断活动结束后恢复。
这与进程调度间用上下文切换的机制是相同的。
在进入核心态时,只保存整个寄存器集合的一部分。
内核并不使用全部寄存器。
(如内核代码中不使用浮点操作,因而不保存浮点寄存器)。
平台相关的数据结构pt_regs列出了核心态可能修改的所有寄存器,它的定义考虑到了不同的CPU之间的差别。
在退出路径中,内核会检查下列事项。
◎调度器是否应该选择一个新进程代替旧的进程。
◎是否有信号必须投递到原进程从中断返回之后,只有确认了这两个问题,内核才能完成其常规任务,即还原寄存器集合、切换到用户态栈、切换到适用于用户应用程序的适当的处理器状态,或切换到一个不同的保护环。
术语中断处理程序的使用可能引起岐义。
因为它是用于指代CPU对ISR(中断服务程序)的调用,包括了进入/退出路径和ISR本身。
当然,如果只指代在进入路径和退出路径之间进行由C语言实现的例程,将更为准确。
2、数据结构中断技术上的实现有两方面:1) 汇编语言代码:与处理器高度相关,用于处理特定平台上相关的底层细节;2) 抽象接口:是设备驱动程序及其他内核代码安装和管理IRQ处理程序所需的。
描述汇编语言部分的功能会涉及无数细节,可以参考处理器体系方面的手册。
为响应外部设备的IRQ,内核必须为每个潜在的IRQ提供一个函数。
该函数必须能够动态注册和注销。
静态表组织方式是不够的,因为可能为设备编写模块,而且设备可能与系统的其他部分通过中断进行交互。
IRQ相关信息管理的关键点是一个全局数组,每个数组项对应一个IRQ编号。
因为数组位置和中断号是相同的,很容易定位与特定的IRQ相关的数组项:IRQ0在位置0,IRQ15在位置15,等等,IRQ最终映射到哪个处理器中断,在这里不相关的。
尽管各个数组项使用的是一个体系结构无关的数据类型,但IRQ的最大可能数目是通过一个平台相关的常数NR_IRQS指定的,大多数体系结构一,该常数定义在处理器相关的头文件irq.h中。
不同处理器间及同一处理器家庭内,该常数的值变化都很大,主要取决于辅助CPU 管理IRQ的辅助芯片。
与IRQ的最大数目相比,我们对各数组项的数据类型更感兴趣。
在了解细节之前,需要概述内核的IRQ处理子系统。
之前的一些版本包含了大量平台代码来处理IRQ,在许多地方是相同的。
因而,在内核版本2.6开发期间,引入了一个新的通用的IRQ子系统。
它能够以统一的方式处理不同的中断控制器和不同类型的中断。
基本上它由3个抽象层组成。
如下图:◎高层ISR(high-level interrupt service routines):针对设备驱动程序端的中断,执行由此引起的所有必要的工作。
◎中断电流处理(interrupt flow handling):处理不同的中断电流类型之间的各种差别,如边沿触发和电平触发。
边沿触发:意味着硬件通过感知线路上的电位差来检测中断。
电平触发:根据特定的电势值检测中断,与电势是否改变无关。
◎芯片级硬件封装(chip-level hardware encapsulation):需要与电子学层次上产生中断的底层硬件直接通信。
该抽象可以视为中断控制器的某种“设备驱动程序”。
用于表示irq的结构如下:(摘自Linux kernel 3.5)[cpp]view plaincopyprint?1.<span style="font-size:16px;">/**2.*struct irq_desc - interrupt descriptor3.*@irq_data: per irq and chip datapassed down to chip functions4.*@timer_rand_state: pointer to timer randstate struct5.*@kstat_irqs: irq stats per cpu6.*@handle_irq: highlevel irq-eventshandler7.*@preflow_handler: handler called beforethe flow handler (currently used by sparc)8.*@action: the irq action chain9.*@status: status information10.*@core_internal_state__do_not_mess_with_it: core internal status information11.*@depth: disable-depth, for nestedirq_disable() calls12.*@wake_depth: enable depth, for multipleirq_set_irq_wake() callers13.*@irq_count: stats field to detectstalled irqs14.*@last_unhandled: aging timer forunhandled count15.*@irqs_unhandled: stats field forspurious unhandled interrupts16.*@lock: locking for SMP17.*@affinity_hint: hint to user space forpreferred irq affinity18.*@affinity_notify: context fornotification of affinity changes19.*@pending_mask: pending rebalancedinterrupts20.*@threads_oneshot: bitfield to handleshared oneshot threads21.*@threads_active: number of irqactionthreads currently running22.*@wait_for_threads: wait queue for sync_irqto wait for threaded handlers23.*@dir: /proc/irq/ procfs entry24.*@name: flow handler name for/proc/interrupts output25.*/26.struct irq_desc27.{28.struct irq_data irq_data;29.struct timer_rand_state *timer_rand_state;30.unsigned int __percpu *kstat_irqs;31.irq_flow_handler_t handle_irq;32.#ifdef CONFIG_IRQ_PREFLOW_FASTEOI33.irq_preflow_handler_t preflow_handler;34.#endif35.struct irqaction *action; /* IRQ action list*/36.unsigned int status_use_accessors;37.unsigned int core_internal_state__do_not_mess_with_it;38.unsigned int depth; /* nested irqdisables */39.unsigned int wake_depth; /* nested wake enables */40.unsigned int irq_count; /* For detectingbroken IRQs */41.unsigned long last_unhandled; /* Aging timer for unhandled count */42.unsigned int irqs_unhandled;43.raw_spinlock_t lock;44.struct cpumask *percpu_enabled;45.#ifdef CONFIG_SMP46.const struct cpumask *affinity_hint;47.struct irq_affinity_notify *affinity_notify;48.#ifdef CONFIG_GENERIC_PENDING_IRQ49.cpumask_var_t pending_mask;50.#endif51.#endif52.unsigned long threads_oneshot;53.atomic_t threads_active;54.wait_queue_head_t wait_for_threads;55.#ifdef CONFIG_PROC_FS56.struct proc_dir_entry *dir;57.#endif58.struct module *owner;59.const char *name;60.} ____cacheline_internodealigned_in_smp;</span>1.<span style="font-size:16px;">/**2.*struct irq_data - per irq and irq chip data passed down to chip functions3.*@irq: interrupt number4.*@hwirq: hardware interrupt number,local to the interrupt domain5.*@node: node index useful forbalancing6.*@state_use_accessors: status information for irq chip functions.7.* Use accessor functions to deal with it8.*@chip: low level interrupt hardwareaccess9.*@domain: Interrupt translationdomain; responsible for mapping10.* between hwirq number and linux irq number.11.*@handler_data: per-IRQ data for theirq_chip methods12.*@chip_data: platform-specificper-chip private data for the chip13.* methods, to allow shared chip implementations14.*@msi_desc: MSI descriptor15.*@affinity: IRQ affinity on SMP16.*17.*The fields here need to overlay the ones in irq_desc until we18.*cleaned up the direct references and switched everything over to19.*irq_data.20.*/21.struct irq_data22.{23.unsigned int irq;24.unsigned long hwirq;25.unsigned int node;26.unsigned int state_use_accessors;27.struct irq_chip *chip;28.struct irq_domain *domain;29.void *handler_data;30.void *chip_data;31.struct msi_desc *msi_desc;32.#ifdef CONFIG_SMP33.cpumask_var_t affinity;34.#endif35.};</span>◎action提供了一个操作链,需要在中断发生时执行。