精华内容
下载资源
问答
  • 中断和中断处理流程

    千次阅读 2020-12-20 04:41:20
    1. 中断概念中断是指由于接收到来自外围硬件(相对于中央处理器和内存)的异步信号或来自软件的同步信号,而进行相应的硬件/软件处理。发出这样的信号称为进行中断请求(interrupt request,IRQ)。硬件中断导致处理器...

    1. 中断概念

    中断是指由于接收到来自外围硬件(相对于中央处理器和内存)的异步信号或来自软件的同步信号,而进行相应的硬件/软件处理。发出这样的信号称为进行中断请求(interrupt request,IRQ)。硬件中断导致处理器通过一个上下文切换(context switch)来保存执行状态(以程序计数器和程序状态字等寄存器信息为主);软件中断则通常作为CPU指令集中的一个指令,以可编程的方式直接指示这种上下文切换,并将处理导向一段中断处理代码。中断在计算机多任务处理,尤其是实时系统中尤为有用。这样的系统,包括运行于其上的操作系统,也被称为“中断驱动的”(interrupt-driven)。

    中断是一种使CPU中止正在执行的程序而转去处理特殊事件的操作,这些引起中断的事件称为中断源,它们可能是来自外设的输入输出请求,也可能是计算机的一些异常事故或其它内部原因。

    中断:在运行一个程序的过程中,断续地以“插入”方式执行一些完成特定处理功能的程序段,这种处理方式称为中断。

    2. 中断的作用

    并行操作

    硬件故障报警与处理

    支持多道程序并发运行,提高计算机系统的运行效率

    支持实时处理功能

    3. 术语

    按中断源进行分类:发出中断请求的设备称为中断源。按中断源的不同,中断可分为

    内中断:即程序运行错误引起的中断

    外中断:即由外部设备、接口卡引起的中断

    软件中断:由写在程序中的语句引起的中断程序的执行,称为软件中断

    允许/禁止(开/关)中断: CPU通过指令限制某些设备发出中断请求,称为屏蔽中断。从CPU要不要接收中断即能不能限制某些中断发生的角度 ,中断可分为

    可屏蔽中断 :可被CPU通过指令限制某些设备发出中断请求的中断, 那是不是意味着进中断时disable整个中断,其实disable的都是可屏蔽中断?

    不可屏蔽中断:不允许屏蔽的中断如电源掉电

    中断允许触发器:在CPU内部设置一个中断允许触发器,只有该触发器置“1”,才允许中断;置“0”,不允许中断。

    指令系统中,开中断指令,使中断触发器置“1”

    关中断指令,使中断触发器置“0”

    中断优先级:为了管理众多的中断请求,需要按每个(类)中断处理的急迫程度,对中断进行分级管理,称其为中断优先级。在有多个中断请求时,总是响应与处理优先级高的设备的中断请求。

    中断嵌套:当CPU正在处理优先级较低的一个中断,又来了优先级更高的一个中断请求,则CPU先停止低优先级的中断处理过程,去响应优先级更高的中断请求,在优先级更高的中断处理完成之后,再继续处理低优先级的中断,这种情况称为中断嵌套。

    Intel的官方文档里将中断和异常理解为两种中断当前程序执行的不同机制。这是中断和异常的共同点。不同点在于:

    中断(interrupt)是异步的事件,典型的比如由I/O设备触发;异常(exception)是同步的事件,典型的比如处理器执行某条指令时发现出错了等等。

    中断又可以分为可屏蔽中断和非可屏蔽中断,异常又分为故障、陷阱和异常中止3种,它们的具体区别很多书籍和官方文档都解释的比较清楚这里不再赘述。

    关于它们的区别有两点是需要注意的:

    平常所说的屏蔽中断是不包括异常的,即异常不会因为CPU的IF位被清(关中断,指令:cli)而受影响,比如缺页异常,即使关了中断也会触发CPU的处理,回答了我上面红色部分疑问。

    通常说的int 80h这种系统调用使用的中断方式实际上硬件上是理解为异常处理的,因此也不会被屏蔽掉,这也很好理解,int 80h这种中断方式是程序里主动触发的,对于CPU来说属于同步事件,因此也就属于异常的范畴。

    4. 中断(异常)处理过程

    需要明确的一点是CPU对于中断和异常的具体处理机制本质上是完全一致的,即:

    当CPU收到中断或者异常的信号时,它会暂停执行当前的程序或任务,通过一定的机制跳转到负责处理这个信号的相关处理程序中,在完成对这个信号的处理后再跳回到刚才被打断的程序或任务中。这里只描述保护模式下的处理过程,搞清楚了保护模式下的处理过程(更复杂),实模式下的处理机制也就容易理解了。

    具体的处理过程如下:

    1)  中断响应的事前准备:

    系统要想能够应对各种不同的中断信号,总的来看就是需要知道每种信号应该由哪个中断服务程序负责以及这些中断服务程序具体是如何工作的。系统只有事前对这两件事都知道得很清楚,才能正确地响应各种中断信号和异常。

    系统将所有的中断信号统一进行了编号(一共256个:0~255),这个号称为中断向量,具体哪个中断向量表示哪种中断有的是规定好的,也有的是在给定范围内自行设定的。  中断向量和中断服务程序的对应关系主要是由IDT(中断向量表)负责。操作系统在IDT中设置好各种中断向量对应的中断描述符(一共有三类中断门描述符:任务门、中断门和陷阱门),留待CPU查询使用。而IDT本身的位置是由idtr保存的,当然这个地址也是由OS填充的。

    中断服务程序具体负责处理中断(异常)的代码是由软件,也就是操作系统实现的,这部分代码属于操作系统内核代码。也就是说从CPU检测中断信号到加载中断服务程序以及从中断服务程序中恢复执行被暂停的程序,这个流程基本上是硬件确定下来的,而具体的中断向量和服务程序的对应关系设置和中断服务程序的内容是由操作系统确定的。

    2) CPU检查是否有中断/异常信号

    CPU在执行完当前程序的每一条指令后,都会去确认在执行刚才的指令过程中中断控制器(如:8259A)是否发送中断请求过来,如果有那么CPU就会在相应的时钟脉冲到来时从总线上读取中断请求对应的中断向量[2]。

    对于异常和系统调用那样的软中断,因为中断向量是直接给出的,所以和通过IRQ(中断请求)线发送的硬件中断请求不同,不会再专门去取其对应的中断向量。

    3) 根据中断向量到IDT表中取得处理这个向量的中断程序的段选择符

    CPU根据得到的中断向量到IDT表里找到该向量对应的中断描述符,中断描述符里保存着中断服务程序的段选择符。

    4) 根据取得的段选择符到GDT中找相应的段描述符

    CPU使用IDT查到的中断服务程序的段选择符从GDT中取得相应的段描述符,段描述符里保存了中断服务程序的段基址和属性信息,此时CPU就得到了中断服务程序的起始地址。这里,CPU会根据当前cs寄存器里的CPL和GDT的段描述符的DPL,以确保中断服务程序是高于当前程序的,如果这次中断是编程异常(如:int 80h系统调用),那么还要检查CPL和IDT表中中断描述符的DPL,以保证当前程序有权限使用中断服务程序,这可以避免用户应用程序访问特殊的陷阱门和中断门[3]。

    5) CPU根据特权级的判断设定即将运行的中断服务程序要使用的栈的地址

    CPU会根据CPL和中断服务程序段描述符的DPL信息确认是否发生了特权级的转换,比如当前程序正运行在用户态,而中断程序是运行在内核态的,则意味着发生了特权级的转换,这时CPU会从当前程序的TSS信息(该信息在内存中的首地址存在TR寄存器中)里取得该程序的内核栈地址,即包括ss和esp的值,并立即将系统当前使用的栈切换成新的栈。这个栈就是即将运行的中断服务程序要使用的栈。紧接着就将当前程序使用的ss,esp压到新栈中保存起来。也就说比如当前在某个函数中,使用的栈,在中断发生时,需要切换新的栈。

    6) 保护当前程序的现场

    CPU开始利用栈保护被暂停执行的程序的现场:依次压入当前程序使用的eflags,cs,eip,errorCode(如果是有错误码的异常)信息。

    官方文档[1]给出的栈变化的示意图如下:

    7) 跳转到中断服务程序的第一条指令开始执行

    CPU利用中断服务程序的段描述符将其第一条指令的地址加载到cs和eip寄存器中,开始执行中断服务程序。这意味着先前的程序被暂停执行,中断服务程序正式开始工作。

    8) 中断服务程序处理完毕,恢复执行先前中断的程序

    在每个中断服务程序的最后,必须有中断完成返回先前程序的指令,这就是iret(或iretd)。程序执行这条返回指令时,会从栈里弹出先前保存的被暂停程序的现场信息,即eflags,cs,eip重新开始执行。

    展开全文
  • 缺页中断处理过程.ppt

    2020-12-20 04:41:16
    缺页中断处理过程3.5.3 存储保护与共享 1. 分页式存储中的存储保护与共享 . 在页式环境下,存储保护以页面为单位。在页表的每个表项里设置一个所谓的“保护位”,由该位的不同取值定义对应页是可读、可写或只可读等...

    缺页中断处理过程

    3.5.3 存储保护与共享 1. 分页式存储中的存储保护与共享 . 在页式环境下,存储保护以页面为单位。在页表的每个表项里设置一个所谓的“保护位”,由该位的不同取值定义对应页是可读、可写或只可读等。 . 被共享的程序文本不一定正好在一个或几个完整的页面中,有可能一个页面中既有允许共享的内容,又有不能共享的私有数据。因此,在分页环境下实现页面的共享比较困难,但也不是不可能。 3 3 11 . 若页面尺寸为50KB,文本编辑程序的代码是可重入的,需要3页,用户进程的数据段需要一页。那么每个用户进程的逻辑地址空间为4页。如图画出三个进程的逻辑地址空间和对应页表,它们的0~2页都划归给文本编辑程序使用(ed1,ed2,ed3),页表中的0~2表项都对应于块号3、4和6;各进程的数据页(即dataA、dataB、dataC)都位于自己空间的第3页,分别存放在内存的2、8和11块。 进程A的 逻辑地址空间 进程B的 逻辑地址空间 进程C的 逻辑地址空间 ed1 0 ed2 1 ed3 2 dataA 3 ed1 0 ed2 1 ed3 2 dataB 3 ed1 0 ed2 1 ed3 2 dataC 3 进程A的页表 0 3 1 4 2 6 3 2 0 3 1 4 2 6 3 2 0 3 1 4 2 6 3 2 页号 帧号 进程B的页表 页号 帧号 进程C的页表 页号 帧号 操作系统 0 1 2 3 4 5 6 7 8 9 10 11 12 dataA ed1 ed2 ed3 dataB dataC 内存 (a) 2. 分段式存储中的存储保护与共享 在分段环境下,段是有完整意义的逻辑信息单位,为实行存储保护,只需在段表表项里增加权限位,指出每段是可读的、可写的或只执行的等。每次进行地址映射时,都将这次访问的类型与权限位比较,若不符合就产生出错中断。 . . 在段式存储管理中很容易实现段的共享,只需在作业的段表中都增加一个表项,让该段的基址指向共享段在内存中的起始地址即可。 比如进程A和B要对文本编辑程序进行共享,那么可把文本编辑程序作为它们地址空间中的段0,如图所示。若文本编辑程序存放在内存43062起始的连续分区里,那么在所对应的各段表中,段号为0的表项的基址都是43062,从而可共享该文本编辑程序。 . 文本 编辑程序 段0 程序段 段1 数据段 段2 进程A的 逻辑地址空间 文本 编辑程序 段0 程序段 段1 数据段 段2 进程B的 逻辑地址空间 堆栈段 段3 0 25286 1 基址 2 43062 操作系统 内存 进程A的段表 段号 段长 0 25286 1 基址 2 43062 进程B的段表 段号 段长 3 A的数据段 文本 编辑程序 B的数据段 A的程序段 B的堆栈段 43062 B的程序段 (b) 4. 分段与分页的区别 (1) 页是信息的物理单位,段是信息的逻辑单位:系统根据帧的大小划分页,不考虑页中的信息是否完整。因此,一页对应的是信息的一个物理单位;段是基于用户程序结构提出的存储管理模式,用户知道自己的程序分多少段,每段在逻辑上都是相对完整的一组信息。所以,段是信息的逻辑单位。 (2) 页的尺寸由系统确定,段的尺寸因段而异。分页式存储管理中的页的尺寸是由系统确定的,它与内存块的大小相同。段的长度取决于用户编写的程序,不同的段有不同的长度。 (3) 页式地址空间是一维的,段式地址空间是二维的 :在分页式存储管理时,用户必须通过链接编辑程序,把各程序段链接成一个相对于0编址的一维线性空间,用户向系统提供的是一个一维的逻辑地址空间;在分段式存储管理时,用户不把各程序段连接成一个相对于0编址的一维线性空间,各程序段之间是通过[段号,段内位移]进行访问的。因此,用户向系统提供的是一个二维的逻辑地址空间。 虚拟存储器的引入 前面介绍的存储管理方案要求进程全部装入内存才可运行。但这会出现两种情况: ●有的作业因太大,内存装不下而无法运行。 ●系统中作业数太多,因系统容量有限只能让少数作业先运行。 3.6.1 虚拟存储的概念 1. 程序执行的“局部性”原理 由于程序执行具有“局部性”,因此实际运行时,没有必要把全部信息都放在内存里。只要合理组织,调度恰当,在发现所需访问的信息不在内存时,能够找到它,能够把它调入内存,那么不仅可以保证作业的正确执行,而且还提高了系统的资源利用率,使得系统具有更高的运行效率。 程序执行的“局部性”原理,是指程序在执行的某一

    展开全文
  • Linux中断处理

    2020-12-29 10:02:16
    4.中断处理流程。5.各类型中断的具体执行流程。中断的类型及具体的种类Linux0.11内核注释1.可屏蔽硬件中断。优先级较低,可以被忽略或者延后处理,通常有键盘,打印机。2.不可屏蔽硬件中断。CPU必须无条件响应,...

    简介

    1.基于Linux0.11代码进行分析。

    2.中断类型分类以及具体的中断。

    3.中断向量的注册。

    4.中断处理流程。

    5.各类型中断的具体执行流程。

    中断的类型及具体的种类

    Linux0.11内核注释

    1.可屏蔽硬件中断。优先级较低,可以被忽略或者延后处理,通常有键盘,打印机。

    2.不可屏蔽硬件中断。CPU必须无条件响应,优先级非常的高,通常有电源断电,内存校验错误。

    3.软件中断--错误。缺页异常?内存访问时产生缺页异常中断,在中断处理程序中实际分配内存,然后在缺页中断处理完成后,继续访问内存。

    4.软件中断--陷阱。常见的例子有系统调用,int 0x80,首先会调用中断处理程序,处理完成后,会继续执行后面的指令。

    5.软件中断--放弃。常见的例子有除零,该错误发生后,调用中断处理程序,中断处理程序中会产生SIGFPE信号,程序可通过注册对应的信号处理函数处理该信号。

    中断向量的注册

    1.源码在head.s这个文件中。

    2.0x20-0x2f是硬件中断,在head.s中初始化为ignore_int后,后续的硬件初始化过程中会初始化其中断处理函数。

    3.中断向量存储在全局的中断向量数组结构中,该数组长度256,每个元素8个字节,在head.s文件中定义。在system.h文件中,定义了设置该数组的接口。代码如下:

    // head.s

    .align 2

    .word 0

    idt_descr:

    .word 256*8-1 # idt contains 256 entries

    .long idt

    // system.h

    #define _set_gate(gate_addr,type,dpl,addr) \

    __asm__ ("movw %%dx,%%ax\n\t" \

    "movw %0,%%dx\n\t" \

    "movl %%eax,%1\n\t" \

    "movl %%edx,%2" \

    : \

    : "i" ((short) (0x8000+(dpl<<13)+(type<<8))), \

    "o" (*((char *) (gate_addr))), \

    "o" (*(4+(char *) (gate_addr))), \

    "d" ((char *) (addr)),"a" (0x00080000))

    #define set_intr_gate(n,addr) \

    _set_gate(&idt[n],14,0,addr)

    #define set_trap_gate(n,addr) \

    _set_gate(&idt[n],15,0,addr)

    #define set_system_gate(n,addr) \

    _set_gate(&idt[n],15,3,addr)

    4.在head.s中,调用startup_32函数过程中调用setup_idt函数将全局的中断描述符初始化为ignore_int。代码如下

    setup_idt:

    lea ignore_int,%edx

    movl $0x00080000,%eax

    movw %dx,%ax /* selector = 0x0008 = cs */

    movw $0x8E00,%dx /* interrupt gate - dpl=0, present */

    lea idt,%edi // edi寄存器指向idt数组的起始地址

    mov $256,%ecx // 循环256次

    rp_sidt:

    movl %eax,(%edi)

    movl %edx,4(%edi)

    addl $8,%edi // 下标递增

    dec %ecx

    jne rp_sidt

    lidt idt_descr

    ret

    5.在trap.c文件中,调用trap_init函数注册软件中断。在sched.c中调用sched_init注册2个调度相关的中断,0x20硬件时钟中断,0x80系统调用中断。其余的硬件中断在硬件初始化时注册。以下是部分代码:

    void sched_init(void)

    {

    set_intr_gate(0x20,&timer_interrupt);

    set_system_gate(0x80,&system_call);

    }

    void trap_init(void)

    {

    int i;

    // 设置除操作出错的中断向量值。

    set_trap_gate(0,&divide_error);

    set_trap_gate(1,&debug);

    set_trap_gate(2,&nmi);

    set_system_gate(3,&int3); /* int3-5 can be called from all */

    set_system_gate(4,&overflow);

    set_system_gate(5,&bounds);

    set_trap_gate(6,&invalid_op);

    set_trap_gate(7,&device_not_available);

    set_trap_gate(8,&double_fault);

    set_trap_gate(9,&coprocessor_segment_overrun);

    set_trap_gate(10,&invalid_TSS);

    set_trap_gate(11,&segment_not_present);

    set_trap_gate(12,&stack_segment);

    set_trap_gate(13,&general_protection);

    set_trap_gate(14,&page_fault);

    set_trap_gate(15,&reserved);

    set_trap_gate(16,&coprocessor_error);

    // 下面把int17-47的陷阱门先均设置为reserved,以后各硬件初始化时会重新设置自己的陷阱门。

    for (i=17;i<48;i++)

    set_trap_gate(i,&reserved);

    // 设置协处理器中断0x2d(45)陷阱门描述符,并允许其产生中断请求。设置并行口中断描述符。

    set_trap_gate(45,&irq13);

    outb_p(inb_p(0x21)&0xfb,0x21); // 允许8259A主芯片的IRQ2中断请求。

    outb(inb_p(0xA1)&0xdf,0xA1); // 允许8259A从芯片的IRQ3中断请求。

    set_trap_gate(39,&parallel_interrupt); // 设置并行口1的中断0x27陷阱门的描述符。

    }

    tips:如果想要知道中断处理函数在哪里注册,注册的函数是什么,可搜索system.h文件中的定义的_set_intr_gate, _set_trap_gate, _set_system_gate函数被调用的地方。

    中断的处理流程

    在分析和阅读源码前,先尝试思考通用的中断处理逻辑。

    1.硬件中断。硬件中断通常来自于外部硬件触发。此时进程可能在任意一个状态(用户态执行用户代码,或者在执行中断)。如果是在执行中断,那么就应该判断当前正在执行的中断和触发中断的优先级,然后确定是否要打断正在执行的中断。

    2.软件中断。软件中断来自用户代码主动调用产生,所以此时应该是在用户态执行用户代码。

    3.用户态下的中断应该有一样的通用流程,大致是,保存当前正在执行代码的上下文,切换到内核态调用中断处理函数,完成后回到用户态恢复上下文,然后继续执行。

    中断处理流程

    4.中断处理是在内核态下运行,因此使用的是内核的堆栈,如果中断时正在运行用户态的代码,那么在切到内核态后,将当时的上下文寄存器等信息存在内核中的堆栈中。示意图如下:

    中断时的堆栈

    5.当在中断情况下发生高优先级的中断时,会在中断过程中使用的堆栈的基础上再次保存中断的上下文,然后执行更高优先级的中断。堆栈示意图如下:

    高优先级中断打断当前的中断时的堆栈

    中断的具体执行

    1.源码主要在asm.s和trap.c这2个文件中。

    2.在调用具体的中断处理函数前,都会将段寄存器和ip寄存器入中断栈,这是中断打断的正在运行的进程的上下文。然后将实际要执行的用C实现的中断处理函数push入栈,再将普通的寄存器如eax,ebx等寄存器入栈,下一步将一些段寄存器入栈,最后将返回后执行的指令的栈地址入栈。

    Linux0.11完全注释中断堆栈图

    3.无返回值的中断以int 0x1,除0的中断举例,代码如下:

    divide_error:

    pushl $do_divide_error # 这里push实际要调用的函数,下一条指令又将其和eax寄存器的值交换。

    # 其目的是为了代码复用,其它中断可以直接调用no_error_code代码段

    # do_divide_error在traps.c中实现

    no_error_code: # 这里是五出错号处理的入口处。

    xchgl %eax,(%esp) # _do_divide_error的地址→eax,eax被交换入栈

    pushl %ebx #保存打断进程的寄存器上下文

    pushl %ecx

    pushl %edx

    pushl %edi

    pushl %esi

    pushl %ebp

    push %ds # !!16位的段寄存器入栈后也要占用4个字节。

    push %es

    push %fs

    pushl $0 # "error code" #将数值0作为出错码入栈

    lea 44(%esp),%edx # 取对堆栈中原调用返回地址处堆栈指针位置,并压入堆栈。

    pushl %edx

    movl $0x10,%edx # 初始化段寄存器ds、es和fs,加载内核数据段选择符 0x10是内核栈的段起始地址

    mov %dx,%ds

    mov %dx,%es

    mov %dx,%fs

    # 下行上的 * 号表示调用操作数指定地址处的函数,称为间接调用。这句的含义是调用引起本次

    # 异常的C处理函数,例如do_divide_error等。

    call *%eax

    addl $8,%esp

    pop %fs

    pop %es

    pop %ds

    popl %ebp

    popl %esi

    popl %edi

    popl %edx

    popl %ecx

    popl %ebx

    popl %eax # 弹出原来eax中的内容

    iret # 返回时会取出栈中保存的被打断进程的eip寄存器的值 继续执行后续的指令

    4.其它的类似的无返回值的中断处理函数如下:

    debug:

    pushl $do_int3 # _do_debug C函数指针入栈

    jmp no_error_code # 复用no_error_code代码段

    5.含error_code的中断和有error_code的中断类似,这里就不粘贴重复的代码了,可以参考源码中的asm.s文件。把握住中断处理的核心逻辑,保存上下文,处理中断,恢复上下文,以及参考源码中的system.h, asm.s, traps.c这几个文件。

    6.深究int 0x1除0中断的处理。

    void do_divide_error(long esp, long error_code)

    {

    die("divide error",esp,error_code);

    }

    static void die(char * str,long esp_ptr,long nr)

    {

    long * esp = (long *) esp_ptr;

    int i;

    printk("%s: %04x\n\r",str,nr&0xffff);

    // 下行打印语句显示当前调用进程的CS:EIP、EFLAGS和SS:ESP的值。

    // EIP:\t%04x:%p\n - esp[1]是段选择符(cs),esp[0]是eip.

    // EFLAGS:\t%p\n - esp[2]是eflags

    // ESP:\t%04x:%p\n - esp[4]是源ss,esp[3]是源esp

    printk("EIP:\t%04x:%p\nEFLAGS:\t%p\nESP:\t%04x:%p\n",

    esp[1],esp[0],esp[2],esp[4],esp[3]);

    printk("fs: %04x\n",_fs());

    printk("base: %p, limit: %p\n",get_base(current->ldt[1]),get_limit(0x17));

    if (esp[4] == 0x17) {

    printk("Stack: ");

    for (i=0;i<4;i++)

    printk("%p ",get_seg_long(0x17,i+(long *)esp[3]));

    printk("\n");

    }

    str(i); // 取当前运行任务的任务号

    printk("Pid: %d, process nr: %d\n\r",current->pid,0xffff & i);

    for(i=0;i<10;i++)

    printk("%02x ",0xff & get_seg_byte(esp[1],(i+(char *)esp[0])));

    printk("\n\r");

    // 前面都是打印调试信息 这里才是真正的处理逻辑 在这里是直接退出 错误码为11

    do_exit(11); /* play segment exception */

    }

    总结

    中断处理的分析到这里就告一段落了。首先要对中断进行分类,并且了解每种类型的中断具体有哪些类型。然后了解内核是如何处理中断的,中断处理函数使用的栈都是内核的内存空间,在执行具体的处理函数前,要先保存被中断的进程的上下文,然后再调用具体的处理函数,处理完成后再恢复被中断进程的上下文以继续运行。在这里要说明下,内核中的栈每次起始地址都是一样的,这是因为调用结束后,要么不会返回,要么返回后栈又变空了,所以内核栈是可以重复利用的。

    展开全文
  • 中断处理的详细过程

    2021-07-31 16:36:27
    经过中断判优,中断处理进入中断响应阶段,中断响应时,CPU向中断源发出中断响应信号,同时: 保护硬件现场 关中断 保存断点 获得中断服务程序的入口地址 4. 中断服务阶段 保护现场 开中断:即允许中断服务...

    0. 一些相关概念

    0.1 内中断

    • 因为CPU内部出错导致的中断。不需要中断请求。一般与当前指令执行有关。
    • 内中断也称为异常
    • 内中断分为两类
      • 自愿中断:指令中断,比如系统调用时的访管指令
      • 强迫中断:
        • 硬件故障(要与硬件中断做区分):如缺页
        • 软件中断:如整数除0
    • 内中断按照处理情况来分类
      • 陷入:有意而为之的中断,如系统调用
      • 故障:由错误条件引起的中断,可能被中断处理程序所修复,如缺页
      • 终止:不可修改的致命错误造成的中断。中断处理程序处理完后不在将控制返回给引发终止的应用程序。比如整数除0.
    • 内部中断不能被屏蔽,一旦出现就应该立即处理

    0.2 外中断

    • 会发生中断请求。一般是有外部事件而导致的中断。
    • 外部中断的分类
      • 外设请求(就是硬件中断):IO操作完成自动给CPU送中断信号
      • 人工干预:用户强行终止一个进程
    • 外部中断按是否可屏蔽进行分类
      • 不可屏蔽中断:即使关中断时(IF=0)也会被响应
      • 可屏蔽中断:关中断时不会被响应。要等到开中断之后才会被响应

    0.3 中断源

    • 外部中断源:
      • 中慢速外设:如打印机,键盘,鼠标
      • 数据通道:如磁盘、网络
      • 实时时钟:如定时器
      • 故障源:如电源掉电、外设故障
    • 内部中断源:
      • 阶上溢
      • 非法除法
      • 缺页
      • 等等
    • 中断源配有中断标志触发器屏蔽触发器
      • 中断标志触发器:置为1表示该中断源发出来中断请求
      • 屏蔽触发器:置为1则CPU在查询中断请求时即使这个中断源有中断请求也不会去处理,而是要等到屏蔽触发器置为0后才会去处理该中断源的中断请求。

    1. 中断请求阶段

    1.1 中断请求标记

    • 每个中断源向CPU发出中断的时机是随机的
    • 为了记录这些中断事件和区分不同的中断源,中断系统为每一个中断源设置了一个中断请求标志触发器。如果某个中断源发出了中断,就将相应的标志触发器置为1
    • 对于外中断,CPU统一在每条指令执行阶段结束前向中断控制器发出中断查询信号,去查询是否有中断请求要去处理。

    2. 中断判优阶段

    • 如果有多个中断源发出了中断请求。则需要根据中断优先级选择优先级高的中断请求先进行响应
    • 中断默认优先级是由一个硬件排队器来实现的
    • 但是中断屏蔽字可以动态改变中断优先级。

    2.1 中断优先级排序原则

    1. 硬件故障中断优先级最高,其次是软件中断
    2. 不可屏蔽中断优先级高于可屏蔽中断
    3. DMA请求优于IO设备的中断请求
    4. 高速设备优于低速设备
    5. 输入设备优于输出设备
    6. 实时设备优于普通设备

    3. 中断响应阶段(中断隐指令)

    3.1 CPU响应中断必须满足的三个条件

    • 中断源有中断请求
    • CPU允许中断:即开中断
    • 一条指令执行完毕,且没有更紧迫的任务

    经过中断判优,中断处理进入中断响应阶段,中断响应时,CPU向中断源发出中断响应信号,同时:

    • 关中断
    • 保存断点(pc寄存器)
    • 获得中断服务程序的入口地址:根据中断类型号,查找中断向量表,找到中断服务程序的首地址(即中断向量

    4. 中断服务阶段

    1. 保护现场:保存中断服务程序将要使用的所有寄存器的原始内容,以便于在退出中断服务程序之前进行恢复。(通用寄存器和状态寄存器和屏蔽字
    2. 开中断:即允许中断服务程序运行时能有更高级别的中断请求出现,实现中断嵌套
    3. 中断服务:中断处理过程,这里运行中断嵌套
    4. 关中断:保证恢复线程不被打断
    5. 恢复现场:恢复主程序的中断线程,通常是将保存在堆栈中的现场信息弹出回到原来的寄存器中
    6. 开中断
    7. 中断返回:返回到原程序的断点处,继续执行原程序

    5. 中断返回阶段

    • 返回到原来程序的断点处,恢复硬件现场,继续执行原程序

    6. 补充:中断源和异常源

    6.1 中断源

    • 外部(硬件产生)的中断
      • 外部中断通过处理器上两个引脚(INTR和NMI)接收。
      • 从引脚NMI接收到信号时,就代表产生了一个不可屏蔽硬件中断,他使用固定中断向量号2
      • 从引脚INTR接收到的信号是可屏蔽硬件中断,它可以使用中断向量号0~255,可以通过标志寄存器EFLAGS中的IF标志屏蔽此类可屏蔽中断
    • 软件产生的中断
      • 通过INT n指令产生的中断。中断向量号0~255都可取
      • 软件产生的中断指令不能够屏蔽
      • 如果是 INT 2 ,则会调用NMI的中断处理程序,但此时不会激活处理器NMI处理硬件

    6.2 异常源

    • 处理器检测到的程序错误异常
      • 在应用程序或操作系统执行期间,如果处理器检测到程序错误,就会产生一个或多个异常。
      • 处理器为其能检测到每一个异常都定义了一个向量,异常可以分为故障,陷阱和中止
    • 软件产生的异常
      • 指令INTO,INT 3 和BOUND指令可以用来从软件中产生异常。
    展开全文
  • 一个完整的中断处理过程应该包括

    千次阅读 2020-12-23 01:30:11
    一个完整的中断处理过程应该包括:中断请求、中断排队或中断判优、中断响应、中断处理和中断返回等环节,下面分别进行讨论。1.中断请求中断请求是由中断源向CPU发出中断请求信号。外部设备发出中断请求信号要具备...
  • UCOSII的中断过程简介系统接收到中断请求后,如果CPU处于开中断状态,系统就会中止正在运行的当前任务,而按中断向量的指向去运行中断服务子程序,当中断服务子程序运行完成后,系统会根据具体情况返回到被中止的...
  • 6. ARM中断处理过程

    2020-12-23 01:30:09
    1 前言2 中断处理的准备过程2.1 中断模式的stack准备1 前言本文主要以ARM体系结构下的中断处理为例,讲述整个中断处理过程中的硬件行为和软件动作。具体整个处理过程分成三个步骤来描述:1、第二章描述了中断处理的...
  • 中断处理的一般过程

    千次阅读 2021-07-03 22:00:18
    中断处理包括一下几个步骤: 1、中断请求 8088/8086CPU的NMI为边沿触发,INTR为电平触发。在中断请求被响应之前会一直发送中断请求。 2、中断源识别 当系统同时有多个中断源发出的中断请求时,系统往往只能相应...
  • 中断”与“轮询”“中断处理并非单片机控制系统所特有的现象,在我们的日常生活中“中断”的例子也随处可见。...图1:“中断处理示意图如果不用“中断处理等待方式的话,在看书的过程中...
  • 三 响应中断首先在分析源码之前,让我们了解一些原理性的东西,我们都知道在处理中断要保存当前现场状态,然后才能处理中断处理完之后还要把现场状态恢复过来才能返回到被中断的地方继续执行,这里要说明的是在指令...
  • 中断怎么发生,中断处理大概流程 1. 中断概念:  中断是指由于接收到来自外围硬件(相对于中央处理器和内存)的异步信号或来自软件的同步信号,而进行相应的硬件/软件处理。发出这样的信号称为进行中断请求...
  • ARM中断处理过程

    2021-05-17 17:36:15
    以s3c2440 ARM9核为例:一:s3c2440 ARM处理器特性:1、S3C2440支持60个中断源,含子中断源;2、ARM9采用五级流水线方式;3、支持外部中断和内部中断;二、s3c2440 支持的寄存器:2.1 外部中断寄存器24个外部中断占用...
  • 这个过程发生得相当快,以致于在使用体验上你不会感到任何变化或损害。 此外,键盘并不是导致中断的唯一组件。一般来说,有三种类型的事件会导致 CPU 发生中断:硬件中断、软件中断和异常。在具体介绍不同类型的...
  • 中断过程流程

    2021-11-23 16:37:51
    中断处理过程 中断隐指令 关中断 保存断点 引出中断服务程序 中断(处理)程序 保存现场和屏蔽字 中断服务程序 开中断 执行中断服务程序 关中断 恢复现场和屏蔽字 开中断 中断返回 ...
  • 当发生中断之后,linux系统在汇编阶段经过...linux驱动中断处理C程序部分,主要涉及linux中断系统数据结构的初始化和C程序的具体执行跳转。一、中断处理数据结构linux内核将所有的中断统一编号,使用一个irq_desc[N...
  • 中断服务程序流程

    千次阅读 2020-12-20 04:41:10
    引言输入/输出是微机系统与外部设备进行信息交换的过程。输入/输出设备称为外部设备,与存储器相比,外部设备有其本身的特点,存储器较为标准,而外部设备则比较复杂,性能的离散性比较大,不同的外部设备,其结构...
  • 中断处理原则: 1.不嵌套 2.越快越好 下半部的处理方式有soft_irq,tasklet,workqueue三种。 soft_irq用在对底半执行时间要求比较紧急或者非常重要的场合,在中断上下文执行。 tasklet是在中断上下文执行 workqueue...
  • 3、实训的内容: 导游词的创作、导游讲解的技巧、导游的服务、导游的姿态、突发事件的处理等。具体参见教案,在资料一栏下载查看。 4、实训感想和心得体会 5、不足之处有哪些 6、字体:宋体;字号:四号;标题不加粗; 7、...
  • 中断是当进程或事件需要立即引起注意时由硬件或软件发出的信号。它向处理器发出高优先级进程警报, 要求...因此, 在处理中断之后, 处理器可以继续处理i + 1。 在处理器处理中断时, 它必须通知设备其请求已被识别,
  • linux系统下驱动中,中断异常的处理过程,与裸机开发中断处理过程非常类似。通过简单的回顾裸机开发中断处理部分,来参考学习linux系统下中断处理流程。一、ARM裸机开发中断处理过程以S3C2440的裸机开发启动文件中,...
  • 本发明实施例涉及通信技术领域,尤其涉及一种PCIe中断方法和系统。...基于引脚的PCI中断也就是INTx中断,经常在几个设备间共享,内核必须调用与该中断相关的每一个中断处理函数,效率比较低。当...
  • GIC驱动分析2.GIC驱动流程分析第二部分 device node转化为platform_device第三部分:platform_device注册添加第四部分 GPIO控制器驱动第五部分 引用GPIO中断的节点的解析第六部分 GPIO中断处理流程 本文以AM5728 ...
  • arm中断处理流程

    2020-12-21 03:07:02
    计数器(PC)值设置成该异常中断的中断向量地址,从而跳转到相应的异常中断处理程序处执行。在接收到中断请求以后,ARM处理器内核会自动执行以上四步,程序计数器PC总是跳转到相应的固定地址。从异常中断处理程序中...
  • 1、异常与中断的处理流程(中断属于异常): 2、小节: 中断函数是怎么被调用的???? 当有中断信号被cpu检测到,cpu...2)、处理异常–》执行不同的中断处理函数(在这个函数里面,做的事情是:分辨中断源;调用对
  • GIC驱动程序对中断处理流程1. 一级中断控制器处理流程2. 多级中断控制器处理流程 参考资料: linux kernel的中断子系统之(七):GIC代码分析 使用逐步演进的方法才能形象地理解。 1. 一级中断控制器处理流程 ...
  • Linux中断和中断处理程序 由于处理器的速度与外设的速度相差很大,无法采取处理器向外设发出请求然后等待的方法。处理器与外设通信的方法: 轮询:处理器定期对设备的状态进行查询(缺点:在不需要通信的情况下,...
  • 0.1 复位(RESET)(优先级=1)当处理器复位引脚有效时,系统产生复位异常中断,程序跳转到复位异常中断处理程序处执行。复位异常中断通常用在下面几种情况:系统加电时;系统复位时;跳转到复位中断向量处执行成为软...
  • ARM有七种异常中断类型,优先级、工作...当中断产生后,除了复位中断立即中止当前指令外,其余情况都是处理器完成当前指令后,才去执行异常处理程序。(1)将CPSR的值保存到将要执行的异常中断对应的各自SPSR中,以...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 392,479
精华内容 156,991
关键字:

中断的处理过程是怎样的