没有合适的资源?快使用搜索试试~ 我知道了~
【摘要】本文详解了 Linux 内核的中断实现机制。首先介绍了中断的一些基本概念,然后分 析了面向对象的 Linux 中断的组织形式、三种主要数据结构及其之间的关系。随后介绍了 Linux 处理异常和中断的基本流程, 在此基础上分析了中断处理的详细流程, 包括保存现场、 中断处理、中断退出时的软中断执行及中断返回时的进程切换等问题。最后介绍了中断相关 的 API,包括中断注册和释放、中断关闭和使能、如何编写中断 ISR、共享中断、中断上下 文中断状态等。 【关键字】中断,异常,hw_interrupt_type,irq_desc_t,irqaction,asm_do_IRQ,软中断, 进程切换,中断注册释放 request_irq,free_irq,共享中断,可重入,中断上下文 1 中断概述 1.1 为什么需要中断? 处理器的速度跟外围硬件设备的速度往往不在一个数量级上,因此,如果内核采取让处理器 向硬件发出一个请求,然后专门等待回应的办法,显然差强人意。既然硬件的响应这么慢, 那么内核就应该在此期间处理其他事务,等到硬件真正完成了请求的操作之后,再回过头来 对它进行处理。想要实现这种功能,轮询(polling)可能会是一种解决办法。可以让内核定期 对设备的状态进行查询, 然后做出相应的处理。 不过这种方法很可能会让内核做不少无用功, 因为无论硬件设备是正在忙碌着完成任务还是已经大功告成,轮询总会周期性地重复执行。 更好的办法是由我们来提供一种机制,让硬件在需要的时候再向内核发出信号(变内核主动 为硬件主动)。这就是中断机制。
资源推荐
资源详情
资源评论
深入剖析 Linux 中断机制
--中断概述
【摘要】本文详解了 Linux 内核的中断实现机制。首先介绍了中断的一些基本概念,然后分
析了面向对象的 Linux 中断的组织形式、三种主要数据结构及其之间的关系。随后介绍了
Linux 处理异常和中断的基本流程,在此基础上分析了中断处理的详细流程,包括保存现场、
中断处理、中断退出时的软中断执行及中断返回时的进程切换等问题。最后介绍了中断相关
的 API,包括中断注册和释放、中断关闭和使能、如何编写中断 ISR、共享中断、中断上下
文中断状态等。
【关键字】中断,异常,hw_interrupt_type,irq_desc_t,irqaction,asm_do_IRQ,软中断,
进程切换,中断注册释放 request_irq,free_irq,共享中断,可重入,中断上下文
1 中断概述
1.1 为什么需要中断?
处理器的速度跟外围硬件设备的速度往往不在一个数量级上,因此,如果内核采取让处理器
向硬件发出一个请求,然后专门等待回应的办法,显然差强人意。既然硬件的响应这么慢,
那么内核就应该在此期间处理其他事务,等到硬件真正完成了请求的操作之后,再回过头来
对它进行处理。想要实现这种功能,轮询(polling)可能会是一种解决办法。可以让内核定期
对设备的状态进行查询,然后做出相应的处理。不过这种方法很可能会让内核做不少无用功,
因为无论硬件设备是正在忙碌着完成任务还是已经大功告成,轮询总会周期性地重复执行。
更好的办法是由我们来提供一种机制,让硬件在需要的时候再向内核发出信号(变内核主动
为硬件主动)。这就是中断机制。
1.2 中断的表示形式
硬件设备生成中断的时候并不考虑与处理器的时钟同步—换句话说就是中断随时可以产生。
因此,内核随时可能因为新到来的中断而被打断。
从物理学的角度看,中断是一种电信号,由硬件设备生成,并直接送入中断控制器的输入引
脚上。然后再由中断控制器向处理器发送相应的信号。处理器一经检测到此信号,便中断自
己的当前工作转而处理中断。此后,处理器会通知操作系统已经产生中断,这样,操作系统
就可以对这个中断进行适当的处理了。
不同的设备对应的中断不同,而每个中断都通过一个惟一的数字标识。因此,来自键盘的中
断就有别干来自硬盘的中断,从而使得操作系统能够对中断进行区分,并知道哪个硬件设备
产生了哪个中断。这样,操作系统才能给不同的中断提供不同的中断处理程序。
这些中断值通常被为中断请求(IRQ)线。通常 IRQ 都是一些数值量。例如在 PC 上,IRQ0 是
时钟中断,而 IRQ 1 是键盘中断。但并非所有的中断号都是这样严格定义的。例如,对于连
接在 PCI 总线上的设备而言,中断是动态分配的。而在嵌入式系统中,由于中断线有限,
一般外设和中断都是一一匹配的,很少有动态分配中断的。不管怎样,重点在于特定的中断
总是与特定的设备相关联,并且内核要知道这些信息。
1.3 异常
在操作系统中,讨论中断就不能不提及异常。广义的中断可分为同步(synchronous)中断
和异步(asynchronous)中断:
同步中断:是当指令执行时由 CPU 控制单元产生,之所以称为同步,是因为只有在一条指
令执行完毕后 CPU 才会发出中断,而不是发生在代码指令执行期间,比如系统调用。
异步中断:是指由其他硬件设备依照 CPU 时钟信号随机产生,即意味着中断能够在指令之
间发生,例如键盘中断。
一般由处理器本身产生的同步中断称为异常(exception),异步中断被称为中断(interrupt)。
中断可分为可屏蔽中断(Maskable interrupt)和非屏蔽中断(Nomaskable interrupt)。异常可
分为故障(fault)、陷阱(trap)、终止(abort)三类。
表 1:中断类别及其行为
类别
原因
异步/同步
返回行为
中断
来自 I/O 设备的信号
异步
总是返回到下一条指令
陷阱
有意的异常
同步
总是返回到下一条指令
故障
潜在可恢复的错误
同步
返回到当前指令
终止
不可恢复的错误
同步
不会返回
在处理器执行到由于编程失误而导致的错误指令(例如被 0 除)的时候,或者是在执行期间出
现特殊情况(例如缺页
),必须靠内核来处理的时候,处理器就会产生一个异常。因为许多处
理器体系结构处理异常与处理中断的方式类似,因此,内核对它们的处理也很类似。
通过软中断实现系统调用,那就是陷人内核,然后引起一种特殊的异常—系统调用处理程序
异常。你将会看到,中断的工作方式与之类似,其差异只在于中断是由硬件而不是软件引起
的。
1.4 中断处理程序
在响应一个特定中断的时候,内核会执行一个函数,该函数叫做中断处理程序(interrupt
handler)或中断服务例程(interrupt service routine, ISR)。产生中断的每个设备都有一个相应的
中断处理程序。
在 Linux 中,中断处理程序看起来就是普普通通的 C 函数。只不过这些函数必须按照特定
的类型声明,以便内核能够以标准的方式传递处理程序的信息。中断处理程序与其他内核函
数的真正区别在于:中断处理程序是被内核调用来响应中断的,而它们运行于我们称之为中
断上下文的特殊上下文中。
中断可能随时发生,因此中断处理程序也就随时可能执行。所以必须保证中断处理程序能够
快速执行,这样才能保证尽可能快地恢复中断代码的执行。因此,尽管对硬件而言,迅速对
其中断进行服务非常重要,但对系统的其他部分而言,让中断处理程序在尽可能短的时间内
完成运行也同样重要。
即使是最精简版的中断服务程序,它也要与硬件进行交互,告诉该设备中断已被接收。我们
可以考虑一下网络设备的中断处理程序面临的挑战。该处理程序除了要对硬件应答,还要把
来自硬件的网络数据包拷贝到内存,对其进行处理后再交给合适的协议栈或应用程序。显而
易见,这种工作量不会太小,尤其对于如今的千兆比特和万兆比特以太网卡而言。
因此我们一般把中断处理切为两个部分或两半。中断处理程序是上半部 (top half)—接收到
一个中断,它就立即开始执行,但只做有严格时限的工作,例如对接收的中断进行应答或复
位硬件,这些工作都是在所有中断被禁止的情况下完成的。能够被允许稍后完成的工作会推
迟到下半部(bottom half)去。此后,在合适的时机,下半部会被开中断执行。
以网卡作为实例,当网卡接收流入网络的数据包时,需要通知内核数据包到了。网卡需要立
即完成这件事,从而优化网络的吞吐量和传输周期,以避免超时。因此,网卡立即发出中断:
嘀,内核,我这里有最新数据包了。内核通过执行网卡已注册的中断处理程序来做出应答。
中断开始执行,应答硬件,拷贝最新的网络数据包到内存,然后读取网卡更多的数据包。这
些都是重要、紧迫而又与硬件相关的工作。处理和操作数据包的其他工作在随后的下半部中
进行。
深入剖析 Linux 中断机制之二
--Linux 中断的组织形式
【摘要】本文详解了 Linux 内核的中断实现机制。首先介绍了中断的一些基本概念,然后分
析了面向对象的 Linux 中断的组织形式、三种主要数据结构及其之间的关系。随后介绍了
Linux 处理异常和中断的基本流程,在此基础上分析了中断处理的详细流程,包括保存现场、
中断处理、中断退出时的软中断执行及中断返回时的进程切换等问题。最后介绍了中断相关
的 API,包括中断注册和释放、中断关闭和使能、如何编写中断 ISR、共享中断、中断上下
文中断状态等。
【关键字】中断,异常,hw_interrupt_type,irq_desc_t,irqaction,asm_do_IRQ,软中断,
进程切换,中断注册释放 request_irq,free_irq,共享中断,可重入,中断上下文
1 Linux中断的组织形式
1.1 IRQ 描述符 irq_desc
对于每个 IRQ 中断线,Linux 都用一个 irq_desc_t 数据结构来描述,我们把它叫做 IRQ 描述
符,NR_IRQS 个 IRQ 形成一个全局数组 irq_desc[],其定义在/include/linux/irq.h 中:
struct irq_desc – 中断描述符
148struct irq_desc {
149 irq_flow_handler_t handle_irq;
150 struct irq_chip *chip;
151 void *handler_data;
152 void *chip_data;
153 struct irqaction *action; /* IRQ action list */
154 unsigned int status; /* IRQ status */
155
156 unsigned int depth; /* nested irq disables */
157 unsigned int wake_depth; /* nested wake enables */
158 unsigned int irq_count; /* For detecting broken IRQs */
159 unsigned int irqs_unhandled;
160 spinlock_t lock;
161#ifdef CONFIG_SMP
162 cpumask_t affinity;
163 unsigned int cpu;
164#endif
171 const char *name;
172} ____cacheline_aligned;
173
174extern struct irq_desc irq_desc[NR_IRQS];
handle_irq:上层的通用中断处理函数指针,如果未设置则默认为__do_IRQ()。通常针对电
平触发或者边沿触发有不同的处理函数。每个中断线可分别设置;
chip:底层中断的各种控制访问方法集合,各个 CPU 实现的都不同,这属于面向对象的中
断处理方式中最底层的一部分;
handler_data:附加参数,用于 handle_irq;
chip_data:平台相关的附加参数,用于 chip;
action:指向一个单向链表的指针,这个链表就是对中断服务例程进行描述的 irqaction 结构;
status:中断当前的状态;
depth:中断关闭打开的层数。如果启用这条 IRQ 中断线,depth 则为 0,如果禁用这条 IRQ
中断线不止一次,则为一个正数。如果 depth 等于 0,每当调用一次 disable_irq( ),该函数
就对这个域的值加 1,同时该函数就禁用这条 IRQ 中断线。相反,每当调用 enable_irq( )函
数时,该函数就对这个域的值减 1;如果 depth 变为 0,该函数就启用这条 IRQ 中断线。
Lock:此中断描述符为全局共享暑假,对于 SMP 需要互斥访问
Dir: /proc/irq/ 入口
Name: /proc/interrupts 中显示的中断名称
“____cacheline_aligned”表示这个数据结构的存放按 32 字节(高速缓存行的大小)进行对
齐,以便于将来存放在高速缓存并容易存取
linux+v2.6.19/arch/arm/kernel/irq.c
157void __init init_IRQ(void)
158{
159 int irq;
160
161 for (irq = 0; irq < NR_IRQS; irq++)
162 irq_desc[irq].status |= IRQ_NOREQUEST | IRQ_DELAYED_DISABLE
163 IRQ_NOPROBE;
164
165#ifdef CONFIG_SMP
166 bad_irq_desc.affinity = CPU_MASK_ALL;
167 bad_irq_desc.cpu = smp_processor_id();
168#endif
169 init_arch_irq();
170
}
1.2 中断控制器描述符 irq_chip
由于 CPU 不同,故每个处理器对于中断的处理方式不一样。Linux 为了实现统一的中断处
理,提供了底层的中断处理抽象接口,对于每个平台都需要实现底层的接口函数。这样对于
上层的中断通用处理程序就无需任何改动。
struct irq_chip –片级的中断描述符
94struct irq_chip {
95 const char *name;
96 unsigned int (*startup)(unsigned int irq);
97 void (*shutdown)(unsigned int irq);
98 void (*enable)(unsigned int irq);
99 void (*disable)(unsigned int irq);
剩余48页未读,继续阅读
资源评论
panqihe
- 粉丝: 30
- 资源: 57
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
最新资源
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功