Linux硬件中断处理
今天看了0.11核的关于硬件中断处理的基本原理,下面作一下总结:
一、I386中断处理原理
I386体系结构CPU中有两种中断,硬中断和软中断,硬中断是外部硬件产生的,软中断是程序中的某条指令或者程序对标志寄存器中某个标志的设 置而产生的,与硬件电路无关。无论是硬件中断和软件中断都有各自的中断对应的处理程序,这些处理程序分布在内核中。那么系统是怎么根据不同的中断找到对应 的处理过程的呢?当发生一个中断时候,如果是硬件中断,则CPU会再执行两个周期从对应的硬件中取到中断号,如果是软中断,则直接从指令中取得中断 号,CPU再根据中断号在中断向量表中找到对应的中断处理程序的入口,并调用处理。在调用这些处理程序之前,会保护一些寄存器的值,这分为两种情况处理:
1)未发生特权级改变。这种情况下,当前进程是内核进程,由于中断处理程序也在内核中,所以程序的转移不会引起特权级变化。这个时候,CPU会将当前进程的EFLAGS、CS、IP压入堆栈,处理程序结束的时候,iret指令会从堆栈中恢复这些寄存器值。
2)特权级发生变化。这种情况下,当前进程是用户进程,由于中断处理程序在内核中,程序需要转移到内核的代码段和数据段,这个时候就会发生特权 级的转变:从用户态专项核心态。这个时候要在将当前进程的EFLAGS、CS、IP压入堆栈之前,把原进程的SS、ESP也压入堆栈,因为,特权级的转变 会引起堆栈的切换。处理程序结束的时候,iret指令会从堆栈中恢复这些寄存器的值。
二、Linux中断处理原理
CPU只是提供了发生中断时候,具体是怎么找到中断处理程序的而中断向量表的设置和中断处理过程需要操作系统提供。在Linux中,中断处理程序的描述如入口,也就是上面说的中断向量是中断门和陷阱门的形式,对应的中断向量表叫做中断描述符表IDT.
1)IDT的设置
IDT的设置是在main.c中初始化中调用trap_init()函数完成的,trap_init()在trap.c中定义,主要是调用 set_trap_gate和set_system_gate填充中断号对应在IDT中的中断门和陷阱门。这两个函数的具体定义和实现在system.c 中。
2)中断处理程序
Linux中的中断处理程序主要包括两个文件,asm.s和trap.c.asm.s用于实现大部分硬件异常所引起的中断的汇编处理过程。而 trap.c则实现了asm.s的中断处理过程中调用的C函数。还有几个中断处理程序的实现在system_call.s和page.s中。
A、asm.s
该程序的主要处理方式是调用trap.c中对应的C函数,显示出错位置和出错码,然后退出中断。其中的处理分为两种情况,带出错号的中断处理和不带出错号的处理。
对于不带出错号的处理过程是这样的,在各自的不带中断号的处理过程中,将对应的C函数指针入栈,然后跳到no_error_code处,no_error_code做到工作是:
交换eax和栈顶值,目的是保存eax的值同时将函数指针值放入eax;
保护原进程的通用寄存器:将ebx,ecx,edx,edi,esi,ebp,ds,es,fs入栈;
将错误码入栈(均为0);
指向中断返回地址eip的栈指针esp的值入栈;
重新设置ds、es、fs.使其指向内核段。
调用C函数;
退栈,恢复各个寄存器的值,最后iret.
带中断号的处理过程与不带中断号的处理过程的不同有三,一个地方是在各自带中断号的处理层过程中,跳到error_code而不是no_error_code.再一个地方是开始的地方要做两次交换,一次是错误码和eax交换,一次使函数地址和ebx的交换。另一个地方是错误码入栈的是对应实际的错误码,而不是0.
B、trap.c
此程序包括一些asm.s中调用的C函数的定义和实现,并显示错误位置和错误码。还有一个就是IDT的初始化:trap_init()的定义和实现。在0.11核中,很多函数中基本上都是空的。
①硬中断是由外部事件引起的因此具有随机性和突发性;软中断是执行中断指令产生的,无面外部施加中断请求信号,因此中断的发生不是随机的而是由程序安排好的。
②硬中断的中断响应周期,CPU需要发中断回合信号(NMI不需要),软中断的中断响应周期,CPU不需发中断回合信号。
③硬中断的中断号是由中断控制器提供的(NMI硬中断中断号系统指定为02H);软中断的中断号由指令直接给出,无需使用中断控制器。
④硬中断是可屏蔽的(NMI硬中断不可屏蔽),软中断不可屏蔽。
软中断是一种推后执行的机制,定时器,网卡的数据的处理是很典型的软中断,这个和中断向 量表里的中断是完全不一样的,以网络数据的处理为例,当网卡接到一个数据包后,其中断处理程序只是把数据复制到缓冲区,然后就告诉网卡,你可以再传数据给 我了,也就是中断返回,但在此之前,网卡的中断处理程序要置一个标志位,告诉操作系统有事要做,这个事就是软中断,但软中断只是很多中断返回时要做的事情 之一,操作系统每次中断返回时会检查着个标志位,看是否有事要做,如果有,就会去处理,象前面提到的网卡,这时候操作系统就回调用软中断的处理函数,网卡 的软中断程序就是做分析数据包啊,这个数据应该传给谁啊等这些工作。没有,就返回了,除了必须的部分
编写两个中断服务函数的区别
1.软中断发生的时间是由程序控制的,而硬中断发生的时间是随机的
2.软中断是由程序调用发生的,而硬中断是由外设引发的
3.硬件中断处理程序要确保它能快速地完成它的任务,这样程序执行时才不会等侍较长时间