(四)中断与异常

本文详细介绍了中断控制的优势、中断和异常的定义、中断向量与中断处理程序的概念,以及中断处理的硬件机制。重点讨论了中断描述符表IDTR的初始化过程和中断上下文的切换。还提到了中断服务例程和中断处理程序的差异,并阐述了进程上下文和中断上下文的特点。最后,解释了中断上下部分的划分以及小任务和工作队列的使用场景和区别。
摘要由CSDN通过智能技术生成

1、 中断控制的主要优点:
CPU只有在I/O需要服务时才响应

2、什么是外部中断、内部中断、中断向量、异常?
外部中断:外部设备所发出的I/O请求
内部中断:也称之为“异常”,是为解决机器运行时所出现的某些随机事件及编程方便而出现的
中断向量 :中断源的编号,每个中断源都被分配一个8位无符号整数作为类型码
异常又叫同步中断,是当指令执行时由cpu控制单元产生的
中断又叫异步中断,是由其他硬件设备依照cpu时钟信号随机产生的

3、与中断相关的汇编指令及其作用
• 调用过程指令CALL :
– CALL 过程名
– 说明:在取出CALL指令之后及执行CALL指令之前,使指令指针寄存器EIP指向紧接CALL指令的下一条指令。CALL指令先将EIP值压入栈内,再进行控制转移。当遇到RET指令时,栈内信息可使控制权直接回到CALL的下一条指令
• 调用中断过程的指令INT
– INT 中断向量
– 说明:EFLAG、CS及EIP寄存器被压入栈内。控制权被转移到由中断向量指定的中断处理程序。在中断处理程序结束时,IRET指令又把控制权送回到刚才执行被中断的地方。

4、 IDTR寄存器的作用,中断描述符表的初始化过程
作用:CPU中增设了一个中断描述符表寄存器IDTR,用来存放中断描述符表在内存的起始地址。
• 初始化过程:初始化可编程控制器8259A;将中断描述符表的起始地址装入IDTR寄存器,并初始化表中的每一项,
 中断门或陷阱门DPL=0,CPL=3,通用保护异常
 中断门或陷阱门DPL=3,CPL=3,允许进入内核态
• 当计算机运行在实模式时,中断描述符表被初始化,并由BIOS使用 。
• 真正进入了Linux内核,中断描述符表就被移到内存的另一个区域,并为进入保护模式进行预初始化
• 用汇编指令LIDT对中断向量表寄存器IDTR进行初始化,即把IDTR置为0。把中断描述符表IDT的起始地址装入IDTR
 用setup_idt()函数填充中断描述表中的256个表项。在对这个表进行填充时,使用了一个空的中断处理程序。因为现在处于初始化阶段,还没有任何中断处理程序,因此,用这个空的中断处理程序填充每个表项。
 在对中断描述符表进行预初始化后, 内核将在启用分页功能后对IDT进行第二遍初始化,也就是说,用实际的陷阱和中断处理程序替换这个空的处理程序。一旦这个过程完成,对于每个异常,IDT都由一个专门的陷阱门或系统门,而对每个外部中断,IDT都包含专门的中断门。

5、中断执行的过程
• 中断和异常的硬件处理 :
– 从硬件的角度看CPU如何处理中断和异常
• 中断请求队列的建立:
– 方便外设共享中断线
• 中断处理程序的执行
• 从中断返回:
– 调用恢复中断现场的宏RESTORE_ALL,彻底从中断返回

6、中断和异常处理时涉及的堆栈切换,如何判断是否要切换(不出大题)

在这里插入图片描述
7、什么是中断服务例程、中断处理程序
• 中断服务例程(Interrupt Service Routine ):每个中断请求都有自己单独的中断服务例程
• 中断处理程序:共享同一条中断线的所有中断请求有一个总的中断处理程序
• 在Linux中,15条中断线对应15个中断处理程序

8、进程上下文和中断上下文的概念
• 进程上下文
• 进程上文:其是指进程由用户态切换到内核态是需要保存用户态时cpu寄存器中的值,进程状态以及堆栈上的内容,即保存当前进程的进程上下文,以便再次执行该进程时,能够恢复切换时的状态,继续执行
• 进程下文:其是指切换到内核态后执行的程序,即进程运行在内核空间的部分
• 中断上下文
• 中断上文:硬件通过中断触发信号,导致内核调用中断处理程序,进入内核空间。这个过程中,硬件的一些变量和参数也要传递给内核,内核通过这些参数进行中断处理。中断上文可以看作就是硬件传递过来的这些参数和内核需要保存的一些其他环境(主要是当前被中断的进程环境。)
• 中断下文:执行在内核空间的中断服务程序。
进程上下文和中断上下文比较:
• 进程上下文是一种内核所处的操作模式,此时内核代表进程执行
– 执行系统调用
– 运行内核线程
– 进程是以进程上下文的形式连接到内核中的,可以睡眠,也可以调用调度程序
• 中断上下文和进程上下文没有关系
– 没有后备进程,所以不可以睡眠
– 如果一个函数会睡眠,就不能在中断处理程序中使用
中断上下文代码的注意事项:
• 运行于进程上下文的内核代码是可抢占的,但中断上下文则会一直运行至结束,不会被抢占。所以中断处理程序代码要受到一些限制,在中断代码中不能出现实现下面功能的代码:
• (1)睡眠或者放弃CPU。
因为内核在进入中断之前会关闭进程调度,一旦睡眠或者放弃CPU,这时内核无法调度别的进程来执行,系统就会死掉。牢记:中断服务子程序一定不能睡眠(或者阻塞)
• (2)尝试获得信号量
如果获得不到信号量,代码就会睡眠,导致(1)中的结果。
• (3)执行耗时的任务
中断处理应该尽可能快,因为如果一个处理程序是IRQF_DISABLED类型,他执行的时候会禁止所有本地中断线,而内核要响应大量服务和请求,中断上下文占用CPU时间太长会严重影响系统功能。中断处理程序的任务尽可能放在中断下半部执行。
• (4)访问用户空间的虚拟地址
因为中断运行在内核空间。

9、为什么要将中断分为上半部与下半部?
上半部:完成尽可能少的比较紧急的功能,它往往只是简单的读取寄存器中的中断状态并清除中断标志后就进行“登记中断”(也就是将底半部处理程序挂在到设备的底半部执行队列中的工作)
特点:响应速度快
下半部:中断处理的大部分工作都在底半部,它几乎做中断处理程序的所有事情。
特点:处理相对来说不是非常紧急的事件

10、什么是小任务、什么是工作队列?它们有何区别,在使用时如何选择?
• 小任务是指对要推迟执行的函数进行组织的一种方式。其数据结构为tasklet_struct,每个结构代表一个独立的小任务。
• 小任务既可以静态地创建,也可以动态地创建
• 工作队列是另外一种将工作推后执行的形式。
• 工作队列可以把工作推后,交由一个内核线程执行,即这个下半部分可以在进程上下文执行。
• 最重要的是工作队列允许被重新调度甚至睡眠。
• 如果推后执行的任务需要睡眠,就选择工作队列。
若推后执行的任务不需睡眠,就选择小任务。
• 若需要用一个可以重新调度的实体来执行下半部的处理,也应使用工作队列。它是唯一能在进程上下文运行下半部实现的机制,也只有它可以睡眠。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值