Linux操作系统分析

上传人:cn****1 文档编号:568588823 上传时间:2024-07-25 格式:PPT 页数:96 大小:1.25MB
返回 下载 相关 举报
Linux操作系统分析_第1页
第1页 / 共96页
Linux操作系统分析_第2页
第2页 / 共96页
Linux操作系统分析_第3页
第3页 / 共96页
Linux操作系统分析_第4页
第4页 / 共96页
Linux操作系统分析_第5页
第5页 / 共96页
点击查看更多>>
资源描述

《Linux操作系统分析》由会员分享,可在线阅读,更多相关《Linux操作系统分析(96页珍藏版)》请在金锄头文库上搜索。

1、Linux操作系统分析操作系统分析主讲:陈香兰助教:贾永泉、毛熠璐3606864-83(西区电三421)Autumn 2007l上次课l进程的创建l进程调度xlanchen2007.9.272Linux Operating System Analysis中断和异常中断和异常xlanchen2007.9.27为什么会有中断为什么会有中断l内核的一个主要功能就是处理硬件l处理器速度一般比外设快很多l内核必须处理其他任务,只有当外设真正完成了准备好了时CPU才转过来处理外设l也可以用轮询的方式来处理,但显然效率不高l中断机制就是满足上述条件的一种解决办法xlanchen2007.9.274Linux

2、 Operating System Analysis主要内容主要内容l中断信号的作用和中断信号处理的一般原则lI/O设备如何引起CPU中断lx86 CPU如何在硬件级处理中断信号lLinux内核中软件级中断处理及其数据结构xlanchen2007.9.275Linux Operating System Analysis中断和异常中断和异常l中断(广义)会改变处理器执行指令的顺序,通常与CPU芯片内部或外部硬件电路产生的电信号相对应l中断异步的:由硬件随机产生,在程序执行的任何时候可能出现l异常同步的:在(特殊的或出错的)指令执行时由CPU控制单元产生我们用“中断信号”来通称这两种类型的中断xl

3、anchen2007.9.276Linux Operating System Analysis中断信号的作用中断信号的作用l中断信号提供了一种特殊的方式,使得CPU转去运行正常程序之外的代码l比如一个外设采集到一些数据,发出一个中断信号,CPU必须立刻响应这个信号,否则数据可能丢失l当一个中断信号到达时,CPU必须停止它当前正在做的事,并且切换到一个新的活动l为了做到这这一点,在进程的内核态堆栈保存程序计数器的当前值(即eip和cs寄存器),并把与中断信号相关的一个地址放入进程序计数器xlanchen2007.9.277Linux Operating System Analysis中断信号的处

4、理原则中断信号的处理原则l快!l当内核正在做一些别的事情的时候,中断会随时到来。无辜的正在运行的代码被打断l中断处理程序在run的时候可能禁止了同级中断l中断处理程序对硬件操作,一般硬件对时间也是非常敏感的l内核的目标就是让中断尽可能快的处理完,尽其所能把更多的处理向后推迟l上半部分(top bottom)和下半部分(half bottom)xlanchen2007.9.278Linux Operating System Analysisl允许不同类型中断的嵌套发生,这样能使更多的I/O设备处于忙状态l尽管内核在处理一个中断时可以接受一个新的中断,但在内核代码中还在存在一些临界区,在临界区中,

5、中断必须被禁止xlanchen2007.9.279Linux Operating System Analysis中断上下文中断上下文l中断上下文不同于进程上下文l中断或异常处理程序执行的代码不是一个进程l它是一个内核控制路径,代表了中断发生时正在运行的进程执行l作为一个进程的内核控制路径,中断处理程序比一个进程要“轻”(中断上下文只包含了很有限的几个寄存器,建立和终止这个上下文所需要的时间很少)xlanchen2007.9.2710Linux Operating System Analysis中断上下文举例中断上下文举例l分析A,B,C,D在互相抢占上的关系 假设: 2个interrupt c

6、ontext,记为A和B 2个process,记为C和D 1, 假设某个时刻C占用CPU运行,此时A中断发生,C被A抢占,A得以在CPU上执行。 由于Linux不为中断处理程序设置process context,A只能使用 C的kernel stack作为自己的运行栈xlanchen2007.9.2711Linux Operating System Analysis2 ,无论如何,Linux的interrupt context A绝对不会被某个进程C或者D抢占!这是由于所有已经启动的interrupt contexts,不管是interrupt contexts之间切换,还是在某个interr

7、upt context中执行代码的过程,决不可能插入scheduler调度例程的调用。除非interrupt context主动或者被动阻塞进入睡眠,唤起scheduler,但这是必须避免的,危险性见第3点说明。 xlanchen2007.9.2712Linux Operating System Analysis3 ,关于第2点的解释:首先,interrupt context 没有process context,如果被 某个进程抢占之后就没法恢复到原来的interrupt context下了,这即损害了A的利益也污染了C的kernel stack。其次,如果interrupt context

8、A由于阻塞或是其他原因睡眠,外界对系统的响应能力将变得不可忍受xlanchen2007.9.2713Linux Operating System Analysis4 ,那么interrupt context A和B的关系又如何呢?由于可能在interrupt context的某个步骤打开了CPU的IF flag标志,这使得在A过程中,B的irq line已经触发了PIC,进而触发了CPU IRQ pin,使得CPU执行中断B的interrupt context,这是中断上下文的嵌套过程。 5,通常Linux不对不同的interrupt contexts设置优先级,这种任意的嵌套是允许的当然可能

9、某个实时Linux的patch会不允许低优先级的interrupt context抢占高优先级的interrupt context xlanchen2007.9.2714Linux Operating System Analysis中断和异常的分类(中断和异常的分类(Intel文档)文档)中断分为:l可屏蔽中断(Maskable interrupt)lI/O设备发出的所有中断请求(IRQ)都可以产生可屏蔽中断。l可屏蔽中断可以处于两种状态:屏蔽的(masked)和非屏蔽的(unmasked)l非屏蔽中断(Nonmaskable interrupt)l只有几个特定的危急事件才引起非屏蔽中断。如硬

10、件故障或是掉电xlanchen2007.9.2715Linux Operating System Analysis异常分为:l处理器探测异常l由CPU执行指令时探测到一个反常条件时产生,如溢出、除0错等l编程异常l由编程者发出的特定请求产生,通常由int类指令触发l通常叫做“软中断”l例如系统调用xlanchen2007.9.2716Linux Operating System Analysisl对于处理器探测异常,根据异常时保存在内核堆栈中的eip的值可以进一步分为:l故障(fault):eip=引起故障的指令的地址l通常可以纠正,处理完异常时,该指令被重新执行l例如缺页异常l陷阱(trap

11、):eip=随后要执行的指令的地址。l异常中止(abort):eip=?l发生严重的错误。eip值无效,只有强制终止受影响的进程xlanchen2007.9.2717Linux Operating System Analysis中断向量中断向量l每个中断和异常由0255之间的一个数(8位)来标识,Intel称其为中断向量。l非屏蔽中断的向量和异常的向量是固定的l可屏蔽中断的向量可以通过对中断控制器的编程来改变xlanchen2007.9.2718Linux Operating System Analysis中断的产生中断的产生l每个能够发出中断请求的硬件设备控制器都有一条称为IRQ(Inter

12、rupt ReQuest)的输出线。l所有的IRQ线都与一个中断控制器的输入引脚相连l中断控制器与CPU的INTR引脚相连设备设备控制器中断控制器IRQCPUINTRxlanchen2007.9.2719Linux Operating System Analysis中断控制器中断控制器执行下列动作:执行下列动作:1,监视IRQ线,对引发信号检查2,如果一个引发信号出现在IRQ线上a,把此信号转换成对应的中断向量b,把这个向量存放在中断控制器的一个I/O端口,从而允许CPU通过数据总线读这个向量c,把引发信号发送到处理器的INTR引脚,即产生一个中断d,等待,直到CPU应答这个信号;收到应答后,

13、清INTR引脚3,返回到第一步xlanchen2007.9.2720Linux Operating System AnalysisIRQ号和中断向量号号和中断向量号l中断控制器对输入的IRQ线从0开始顺序编号lIRQ0,IRQ1,lIntel给中断控制器分配的中断向量号从32开始,上述IRQ线对应的中断向量依次是l32+0、32+1、l可以对中断控制器编程:l修改起始中断向量的值,或l有选择的屏蔽/激活每条IRQ线屏蔽丢失xlanchen2007.9.2721Linux Operating System Analysisl屏蔽的中断不会丢失l一旦被激活,中断控制器又会将它们发送到CPUl有选择

14、的屏蔽/激活IRQ线全局屏蔽/激活l前者通过对中断控制器编程实现l后者通过特定的指令操作CPU中的状态字xlanchen2007.9.2722Linux Operating System AnalysisI386:开中断和关中断开中断和关中断lCPU可以将屏蔽所有的可屏蔽终端lEflags中的IF标志:0=关中断;1=开中断。l关中断时,CPU不响应中断控制器发布的任何中断请求l内核中使用cli和sti指令分别清除和设置该标志xlanchen2007.9.2723Linux Operating System Analysis传统的中断控制器:传统的中断控制器:8259Al传统的中断控制器使用两

15、片8259A以“级联”的方式连接在一起l每个芯片可以处理最多8个不同的IRQ线l主从两片8259A的连接:l从主的IRQ2引脚l因此,一共可以处理最多15个不同的IRQ线xlanchen2007.9.2724Linux Operating System Analysis8259A:设置起始中断向量号:设置起始中断向量号xlanchen2007.9.2725Linux Operating System Analysis8259A:禁止:禁止/激活某个激活某个IRQ线线取变量的第x个字节xlanchen2007.9.2726Linux Operating System Analysis异常异常lX

16、86处理器发布了大约20种不同的异常。l某些异常通过硬件出错码说明跟异常相关的信息l内核为每个异常提供了一个专门的异常处理程序xlanchen2007.9.2727Linux Operating System Analysis故障非屏蔽中断陷阱,断点调试陷阱故障,缺页异常中止异常处理程序异常处理程序发出的信号xlanchen2007.9.2728Linux Operating System Analysis中断描述符表中断描述符表(Interrupt Descriptor Table,IDT)l中断描述符表是一个系统表,它与每一个中断或者异常向量相联系l每个向量在表中有相应的中断或者异常处理程

17、序的入口地址。l每个描述符8个字节,共256项,占用空间2KBl内核在允许中断发生前,必须适当的初始化IDTlCPU的idtr寄存器指向IDT表的物理基地址llidt指令xlanchen2007.9.2729Linux Operating System AnalysislIDT包含3种类型的描述符任务门:Linux没有使用任务门中断门:指定中断处理程序,进入中断门时,系统进入关中断状态陷阱门:与中断门类似,但进入陷阱门时,系统不会进入关中断状态xlanchen2007.9.2730Linux Operating System Analysis中断和异常的硬件处理中断和异常的硬件处理进入中断进入

18、中断/异常异常l假定:内核已经初始化,CPU在保护模式下运行lCPU的正常运行:l当执行了一条指令后,cs和eip这对寄存器包含了下一条将要执行的指令的逻辑地址。l在执行这条指令之前,CPU控制单元会检查在运行前一条指令时是否发生了一个中断或者异常。l如果发生了一个中断或异常,那么CPU控制单元执行下列操作:xlanchen2007.9.2731Linux Operating System Analysis1,确定与中断或者异常关联的向量i(0255)2,读idtr寄存器指向的IDT表中的第i项3,从gdtr寄存器获得GDT的基地址,并在GDT中查找,以读取IDT表项中的段选择符所标识的段描述

19、符。4,确定中断是由授权的发生源发出的。l中断:中断处理程序的特权不能低于引起中断的程序的特权(对应GDT表项中的DPL vs CS寄存器中的CPL)l编程异常:还需比较CPL与对应IDT表项中的DPL这个描述符指定中断或异常处理程序所在段的基地址只允许从低特权级“陷入”到高特权级,反之不可以禁止低特权级用户访问特殊的门xlanchen2007.9.2732Linux Operating System Analysis5,检查是否发生了特权级的变化,一般指是否由用户态陷入了内核态。如果是由用户态陷入了内核态,控制单元必须开始使用与新的特权级相关的堆栈a,读tr寄存器,访问运行进程的tss段b,

20、用与新特权级相关的栈段和栈指针装载ss和esp寄存器。这些值可以在进程的tss段中找到c,在新的栈中保存ss和esp以前的值,这些值指明了与旧特权级相关的栈的逻辑地址xlanchen2007.9.2733Linux Operating System Analysis6,若发生的是故障,用引起异常的指令地址修改cs和eip寄存器的值,以使得这条指令在异常处理结束后能被再次执行7,在栈中保存eflags、cs和eip的内容8,如果异常产生一个硬件出错码,则将它保存在栈中9,装载cs和eip寄存器,其值分别是IDT表中第i项门描述符的段选择符和偏移量字段。这对寄存器值给出中断或者异常处理程序的第一条

21、指定的逻辑地址xlanchen2007.9.2734Linux Operating System Analysisl此时的进程内核态堆栈(注意此进程可以是任意一个进程,中断处理程序不关心这个)ssespeflagscseip8KB unionesp进程描述符用户态进程上下文和前次中断保存ss,esp,eflags,cs和eipeflagscseip进程描述符esp从内核态进入中断/异常从用户态进入中断/异常Error codeespxlanchen2007.9.2735Linux Operating System Analysis从中断从中断/异常返回异常返回l中断/异常处理完后,相应的处理程

22、序会执行一条iret汇编指令,这条汇编指令让CPU控制单元做如下事情:1,用保存在栈中的值装载cs、eip和eflags寄存器。如果一个硬件出错码曾被压入栈中,那么弹出这个硬件出错码2,检查处理程序的特权级是否等于cs中最低两位的值(这意味着进程在被中断的时候是运行在内核态还是用户态)。若是,iret终止执行;否则,转入3xlanchen2007.9.2736Linux Operating System Analysis3,从栈中装载ss和esp寄存器。这步意味着返回到与旧特权级相关的栈4,检查ds、es、fs和gs段寄存器的内容,如果其中一个寄存器包含的选择符是一个段描述符,并且特权级比当前

23、特权级高,则清除相应的寄存器。这么做是防止怀有恶意的用户程序利用这些寄存器访问内核空间xlanchen2007.9.2737Linux Operating System Analysis中断和异常处理程序的嵌套执行中断和异常处理程序的嵌套执行l当内核处理一个中断或异常时,就开始了一个新的内核控制路径l当CPU正在执行一个与中断相关的内核控制路径时,linux不允许进程切换。不过,一个中断处理程序可以被另外一个中断处理程序中断,这就是中断的嵌套执行xlanchen2007.9.2738Linux Operating System Analysisl抢占原则l普通进程可以被中断或异常处理程序打断l

24、异常处理程序可以被中断程序打断l中断程序只可能被其他的中断程序打断lLinux允许中断嵌套的原因l提高可编程中断控制器和设备控制器的吞吐量l实现了一种没有优先级的中断模型xlanchen2007.9.2739Linux Operating System Analysis初始化中断描述符表初始化中断描述符表l内核启动中断前,必须初始化IDT,然后把IDT的基地址装载到idtr寄存器中lint指令允许用户进程发出一个中断信号,其值可以是0255的任意一个向量。所以,为了防止用户用int指令非法模拟中断和异常,IDT的初始化时要很小心的设置特权级l然而用户进程有时必须要能发出一个编程异常。为了做到这

25、一点,只要把相应的中断或陷阱门描述符的特权级设置成3xlanchen2007.9.2740Linux Operating System Analysis初始化中断描述符表初始化中断描述符表lLinux中的中断门、陷阱门和系统门定义l中断门l用户态的进程不能访问的一个Intel中断门(特权级为0),所有的中断都通过中断门激活,并全部在内核态l系统门l用户态的进程可以访问的一个Intel陷阱门(特权级为3),通过系统门来激活4个linux异常处理程序,它们的向量是3,4,5和128。因此,在用户态下可以发布int3,into,bound和int $0x80四条汇编指令l陷阱门l用户态的进程不能访问

26、的一个Intel陷阱门(特权级为0),大部分linux异常处理程序通过陷阱门激活xlanchen2007.9.2741Linux Operating System Analysis初始化中断描述符表初始化中断描述符表l下列体系结构相关的函数用来在IDT中设置门不同的是系统门中特权级对应的位DPL被置成3。三个函数都把相应的门中的段描述符设置成内核代码段的选择符,偏移字段设置成addr。xlanchen2007.9.2742Linux Operating System Analysisxlanchen2007.9.2743Linux Operating System AnalysisIDT的初步

27、初始化(的初步初始化(head.S)l用ignore_int()函数填充256个idt_table表项xlanchen2007.9.2744Linux Operating System Analysisxlanchen2007.9.2745Linux Operating System AnalysisStart_kernel中的中的IDT表初始化表初始化xlanchen2007.9.2746Linux Operating System AnalysisTrap_init系统调用20个异常源文件xlanchen2007.9.2747Linux Operating System AnalysisI

28、nit_IRQ中断源文件xlanchen2007.9.2748Linux Operating System Analysis异常处理异常处理lCPU产生的大部分异常都由linux解释为出错条件。当一个异常发生时,内核就向引起异常的进程发送一个信号通知它发生了一个反常条件l异常处理有一个标准的结构,由三部分组成1.在内核态堆栈中保存大多数寄存器的内容2.调用C语言的函数3.通过ret_from_exception()从异常处理程序退出l观察entry.S,并找到C语言函数的定义之处xlanchen2007.9.2749Linux Operating System Analysis此处,去调用相应

29、的C语言编写的处理函数pt_regs指针出错码xlanchen2007.9.2750Linux Operating System Analysisl此时的内核态堆栈ssespeflagcseiporig_eax:0esdseaxebpediesiedxecxebxerror_codePointer返回地址硬件自动保存error_code代码手工压入esp高地址低地址进程描述符pt_regs指针Errorc_ode拷贝完后,被设为-1用于传递Errorc_odexlanchen2007.9.2751Linux Operating System Analysispt_regs结构结构(恢复现场所需

30、的上恢复现场所需的上下文)下文)栈底(高地址)栈顶(低地址)xlanchen2007.9.2752Linux Operating System Analysis异常处理异常处理l当C函数终止时,根据堆栈中的返回地址,CPU从call *%edi这条指令的下一条指令开始继续执行,即:addl $8,%espjmp ret_from_exceptionaddl $8,%esp的意思是堆栈指针+8,即弹出了pointer和error_code,此时堆栈中内容为ssespeflagcseiporgi_eax(-1)esdseaxebpediesiedxecxebxerror_codePointer返回

31、地址硬件自动保存将由iret指令负责弹出前面的汇编手工压入,将由restore_all负责弹出esp进程描述符xlanchen2007.9.2753Linux Operating System Analysis中断处理中断处理l中断跟异常不同,它并不是表示程序出错,而是硬件设备有所动作,所以不是简单地往当前进程发送一个信号就OK的l主要有三种类型的中断:lI/O设备发出中断请求l时钟中断l处理器间中断(在SMP, Symmetric Multiprocessor上才会有这种中断)xlanchen2007.9.2754Linux Operating System AnalysisI/O中断处理中

32、断处理lI/O中断处理程序必须足够灵活以给多个设备同时提供服务l比如几个设备可以共享同一个IRQ线(2个8359级联也只能提供15根IRQ线,所以外设共享IRQ线是很正常的)这就意味着仅仅中断向量解决不了全部问题xlanchen2007.9.2755Linux Operating System Analysisl灵活性以两种不同的方式达到lIRQ共享:中断处理程序执行多个中断服务例程(interrupt service routines, ISRs)。每个ISR是一个与单独设备(共享IRQ线)相关的函数lIRQ动态分配:一条IRQ线在可能的最后时刻才与一个设备相关联xlanchen2007.9

33、.2756Linux Operating System Analysisl为了保证系统对外部的响应,一个中断处理程序必须被尽快的完成。因此,把所有的操作都放在中断处理程序中并不合适lLinux中把紧随中断要执行的操作分为三类l紧急的(critical)一般关中断运行。诸如对PIC应答中断,对PIC或是硬件控制器重新编程,或者修改由设备和处理器同时访问的数据xlanchen2007.9.2757Linux Operating System Analysisl非紧急的(noncritical)如修改那些只有处理器才会访问的数据结构(例如按下一个键后读扫描码),这些也要很快完成,因此由中断处理程序立

34、即执行,不过一般在开中断的情况下xlanchen2007.9.2758Linux Operating System Analysisl非紧急可延迟的(noncritical deferrable)如把缓冲区内容拷贝到某个进程的地址空间(例如把键盘缓冲区内容发送到终端处理程序进程)。这些操作可以被延迟较长的时间间隔而不影响内核操作,有兴趣的进程将会等待数据。内核用下半部分这样一个机制来在一个更为合适的时机用独立的函数来执行这些操作xlanchen2007.9.2759Linux Operating System Analysis不管引起中断的设备是什么,所有的I/O中断处理程序都执行四个相同的基

35、本操作1,在内核态堆栈保存IRQ的值和寄存器的内容2,为正在给IRQ线服务的PIC发送一个应答,这将允许PIC进一步发出中断3,执行共享这个IRQ的所有设备的中断服务例程4,跳到ret_from_intr()的地址xlanchen2007.9.2760Linux Operating System Analysis中断处理示意图中断处理示意图xlanchen2007.9.2761Linux Operating System AnalysisLinux中的中断向量分配表中的中断向量分配表xlanchen2007.9.2762Linux Operating System AnalysisLinux中

36、的设备中断中的设备中断IRQ号与I/O设备之间的对应关系是在初始化每个设备驱动程序时建立的xlanchen2007.9.2763Linux Operating System Analysis中断处理中断处理l系统初始化时,调用init_IRQ()函数用新的中断门替换临时中断门来更新IDT这段代码在interrupt数组中找到用于建立中断门的中断处理程序地址。xlanchen2007.9.2764Linux Operating System AnalysisInterrupt数组数组的定义的定义lLinux中Interrupt数组的定义比较隐晦源文件xlanchen2007.9.2765Linu

37、x Operating System Analysis每个中断程序入口的定义每个中断程序入口的定义源文件源文件xlanchen2007.9.2766Linux Operating System Analysisl因此,每个中断程序入口操作为:l将中断向量入栈l保存所有其他寄存器l调用do_IRQl跳转到ret_from_intrxlanchen2007.9.2767Linux Operating System Analysisdo_IRQldo_IRQ使用的数据结构(体系结构无关):lirq_desc数组包含了NR_IRQS(通常为224)个irq_desc_t描述符xlanchen2007.

38、9.2768Linux Operating System Analysisirq_desc_t和和irq_desc每一个中断号具有一个描述符,使用action链表连接共享同一个中断号的多个设备和中断中断控制器处理例程xlanchen2007.9.2769Linux Operating System Analysisirqaction数据结构数据结构l用来实现IRQ的共享,维护共享irq的特定设备和特定中断,所有共享一个irq的链接在一个action表中,由中断描述符中的action指针指向链表中断处理程序xlanchen2007.9.2770Linux Operating System Ana

39、lysisl设置irqaction的函数xlanchen2007.9.2771Linux Operating System Analysishw_interrupt_type数据结构数据结构l为特定PIC编写的低级I/O例程xlanchen2007.9.2772Linux Operating System Analysis8259A的的hw_interrupt_typel8259A的中断控制操作l所有连接到8259A的外设中断都要设置xlanchen2007.9.2773Linux Operating System Analysisl例如:xlanchen2007.9.2774Linux Op

40、erating System Analysis中断处理过程中断处理过程l在调用do_IRQ之前,要为中断处理程序保存寄存器l在interrupt数组中定义的中断处理程序中l每个入口地址转换成汇编码是如下的一些指令IRQn_interrupt:pushl $n-256jmp common_interrupt这里对所有的中断处理程序都执行相同的代码common_interrupt:SAVE_ALLcall do_IRQjmp $ret_from_intrxlanchen2007.9.2775Linux Operating System Analysisssespeflagcseip$n-256es

41、dseaxebpediesiedxecxebx返回地址Pointer硬件自动保存SAVE_ALLesp进程描述符do_IRQ执行时内核态的堆栈do_IRQ()的函数声明从do_IRQ返回后要执行的指令地址ret_from_intrxlanchen2007.9.2776Linux Operating System Analysis中断处理中断处理ldo_IRQ()函数的等价代码:int irq=regs.orig_eax & 0xff;/1irq_descirq.handler-ack(irq);/2handle_IRQ_event(irq,®s,irq_descirq.action);/

42、3irq_descirq.handler-end(irq);/4处理下半部分/51句将$n-255转换成n,取得对应的中断向量2句应答PIC的中断,并禁用这条IRQ线。(为串行处理同类型中断)3句调用handle_IRQ_event()执行中断服务例程4句通知PIC重新激活这条IRQ线,允许处理同类型中断xlanchen2007.9.2777Linux Operating System Analysis中断服务例程中断服务例程l一个中断服务例程实现一种特定设备的操作, handle_IRQ_evnet()函数依次调用这些设备例程l这个函数本质上执行了如下核心代码:doaction-handle

43、r(irq,action-dev_id,regs);action = action-next;while (action)xlanchen2007.9.2778Linux Operating System Analysis软中断、软中断、tasklet以及下半部分以及下半部分l对内核来讲,可延迟中断不是很紧急,可以将它们从中断处理例程中抽取出来,保证较短的中断响应时间lLinux2.4提供了三种方法l软中断、tasklet以及下半部分lTasklet在软中断之上实现l下半部分通过tasklet实现l一般原则:在同一个CPU上软中断/tasklet/下半部分不嵌套l软中断和下半部分由内核静态分配

44、(编译时确定)lTasklet可以在运行时分配和初始化(例如装入一个内核模块时)xlanchen2007.9.2779Linux Operating System Analysisl一般而言,可延迟函数上可以执行4种操作l初始化:定义一个新的可延迟函数,通常在内核初始化时进行l激活:设置可延迟函数在下一轮处理中执行l屏蔽:有选择的屏蔽一个可延迟函数,这样即使被激活也不会被运行l执行:在特定的时间执行可延迟函数xlanchen2007.9.2780Linux Operating System Analysis软中断软中断lLinux2.4使用有限个软中断,目前只有4个l在softirq_vec中

45、定义优先级0:处理高优先级的tasklet和下半部分优先级1:把数据包传送到网卡优先级2:从网卡接受数据包优先级3:处理tasklet优先级对应于softirq_vec的下标软中断函数及其参数xlanchen2007.9.2781Linux Operating System Analysis软中断的初始化软中断的初始化l初始化软中断函数l分别在softirq_init和net_dev_init中初始化xlanchen2007.9.2782Linux Operating System Analysis内核中用来控制软中断的数据结内核中用来控制软中断的数据结构构irq_statlirq_stat数

46、组用来描述各个CPU的irq处理状态l对于单CPU而言,数组长度为1哪些软中断被挂起禁止软中断?哪个进程执行可延迟函数?对这个数据的调控,用来激活一个软中断:_cpu_raise_softirqcpu_raise_softirq还可能唤醒这个进程ksoftirqdxlanchen2007.9.2783Linux Operating System Analysis软中断的检查软中断的检查l在某些特定的时机,会检查是否有软中断被挂起l调用local_bh_enable重新激活软中断时l当do_IRQ完成了I/O中断的处理时l当那个特定的进程ksoftirqd被唤醒时ll这种时机,称为检查点xlan

47、chen2007.9.2784Linux Operating System Analysis在每个检查点在每个检查点l若有软中断被挂起,就调用do_softirql判断是否可以执行软中断l若可以,就执行软中断l执行后,若发现又有新的软中断被激活,就唤醒ksoftirqd进程,来触发do_softirq的另一次执行xlanchen2007.9.2785Linux Operating System AnalysisTaskletlTasklet是I/O驱动程序中实现可延迟函数的首选方法l建立在HI_SOFTIRQ和TASKLET_SOFTIRQ的软中断之上lTasklet和高优先级的tasklet

48、l分别存放在tasklet_vec和tasklet_hi_vec数组中l数组的每一项针对一个CPU,代表这个CPU上的tasklet列表l分别由tasklet_action和tasklet_hi_action处理l找到CPU对应的那个项,遍历执行xlanchen2007.9.2786Linux Operating System AnalysisTasklet描述符同一个CPU上链表中的nextTasklet函数和参数xlanchen2007.9.2787Linux Operating System AnalysisTasklet的使用的使用l当需要使用tasklet时,可以按照如下方法进行l1

49、、分配一个tasklet的数据结构,并初始化=相当于声明(定义)一个taskletl2、可以禁止/允许这个tasklet=相当于定义了一个是否允许使用tasklet的窗口l3、可以激活这个tasklet=这个tasklet被插入task_vec或者task_hi_vec的相应CPU的链表上,将在合适的时机得到处理xlanchen2007.9.2788Linux Operating System Analysis激活激活tasklet的方法的方法l即将tasklet插入到合适的链表中lTasklet_schedulelTasklet_hi_schedulexlanchen2007.9.2789L

50、inux Operating System Analysis下半部分下半部分l下半部分本质上是一个高优先级的taskletlLinux利用一个bh_base表把所有的下半部分组织在一起Linux中的下半部分定时器周期性任务队列立即任务队列硬件相关的其它下半部分xlanchen2007.9.2790Linux Operating System Analysisl系统初始化的时候,使用init_bh初始化下半部分l下半部分处理函数为bh_action,在softirq_init中初始化xlanchen2007.9.2791Linux Operating System Analysisl下半部分使用

51、mark_bh()激活xlanchen2007.9.2792Linux Operating System Analysis软中断、软中断、tasklet、下半部分小结、下半部分小结软中断初始化激活屏蔽执行tasklettasklet_hitasklettasklettasklet下半部分激活导致一个相应的tasklet插入xlanchen2007.9.2793Linux Operating System Analysis从中断和异常返回从中断和异常返回l中断和异常的终止目的很清楚,即恢复某个程序的执行,但是还有几个问题要考虑l内核控制路径是否嵌套l如果仅仅只有一条内核控制路径,那CPU必须切换到用户态l挂起进程的切换请求l如果有任何请求,必须调度;否则,当前进程得以运行l挂起的信号l如果一个信号发送到进程,那必须处理它xlanchen2007.9.2794Linux Operating System Analysis阅读阅读Entry.S中从中断和异常返回中从中断和异常返回的代码的代码xlanchen2007.9.2795Linux Operating System Analysis从中断和异常返回从中断和异常返回xlanchen2007.9.2796Linux Operating System Analysis

展开阅读全文
相关资源
正为您匹配相似的精品文档
相关搜索

最新文档


当前位置:首页 > 办公文档 > 工作计划

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号