linux 中断 异常详细分析 --- 基于linux 2.6.28

 

 

v
一 基础背景知识
1 中断(广义)会改变处理器执行指令的顺序,通常与CPU芯片内部或外部硬件电路产生的电信号相对应
Ø 中断—— 异步的:
由硬件随机产生,在程序执行的任何时候可能出现
Ø 异常—— 同步的:
在(特殊的或出错的)指令执行时由CPU控制单元产生
我们用中断信号来通称这两种类型的中断
断上下文不同于进程上下文
Ø 中断或异常处理程序执行的代码不是一个进程
Ø 它是一个内核控制路径,代表了中断发生时正在运行的进程执行
Ø 作为一个进程的内核控制路径,中断处理程序比一个进程要(中断上下文只包含了很有限的几个寄存器,建立和终止这个上下文所需要的时间很少)
中断分类:

 

v 可屏蔽中断(Maskable interrupt
Ø I/O设备发出的所有中断请求(IRQ)都可以产生可屏蔽中断。
Ø 可屏蔽中断可以处于两种状态:屏蔽的(masked)和非屏蔽的(unmasked)
v 非屏蔽中断(Nonmaskable interrupt
Ø 只有几个特定的危急事件才引起非屏蔽中断。如硬件故障或 是掉电
4 异常分类  
v 处理器探测异常
Ø CPU执行指令时探测到一个反常条件时产生,如溢出、除0错等
v 编程异常
Ø 由编程者发出的特定请求产生,通常由int类指令触发
Ø 通常叫做软中断
Ø
 
v 对于处理器探测异常,根据异常时保存在内核堆栈中eip的值可以进一步分为:
Ø 故障(fault)eip=引起故障的指令的地址
l 通常可以纠正,处理完异常时,该指令被重新执行
l 例如缺页异常
Ø 陷阱(trap)eip=随后要执行的指令的地址。
Ø 异常中止(abort)eip=???
l
 
5 中断向量
每个中断和异常由0~255之间的一个数(8位)来标识Intel称其为中断向量
Ø 非屏蔽中断的向量和异常的向量是固定的
Ø
6 中断控制器
(1)监视IRQ线,对引发信号检查(编号小者优先)
(2)如果一个引发信号出现在IRQ线上
a,把此信号转换成对应的中断向量
b,把这个向量存放在中断控制器的一个I/O端口,从而允许CPU通过数据总线读这个向量
c,把引发信号发送到处理器的INTR引脚,即产生一个中断
d,等待,直到CPU应答这个信号;收到应答后,清INTR引脚
(3)返回到第1
7 IRQ号和中断向量号
中断控制器对输入的IRQ线从0开始顺序编号
Ø IRQ0IRQ1
v Intel给中断控制器分配的中断向量号从32开始,上述IRQ线对应的中断向量依次是
Ø 32+032+1
v 可以对中断控制器编程
Ø 修改起始中断向量的值,或
Ø 有选择的屏蔽/激活每条IRQ线
8 异常
可屏蔽中断的向量可以通过对中断控制器的编程来改变
发生严重的错误。eip值无效,只有强制终止受影响的进程
例如系统调用
 
v X86处理器发布了大约20种不同的异常。
Ø 某些异常通过硬件出错码说明跟异常相关的信息
Ø 出错码会在陷入异常处理时,由硬件压入内核栈
v
10 中断描述附表(IDT)
 
v 中断描述符表是一个系统表,它与每一个中断或者异 常向量相联系
Ø 每个向量在表中有相应的中断或者异常处理程序的入口地址
Ø 每个描述符8个字节,共256项,占用空间2KB
Ø 内核在允许中断发生前,必须适当的初始化IDT
v
11 中断或异常的硬件处理
假定:内核已经初始化,CPU在保护模式下运行
v CPU的正常运行: 当执行了一条指令后,cseip这对寄存器包含了下一条将要执行的指令的逻辑地址。 在执行这条指令之前,CPU控制单元会检查在运行前一条指令时是否发生了一个中断或者异常。 如果发生了一个中断或异常,那么CPU 控制单元执行下列操作:
 
(1) 确定 与中断或者异常关联的 向量 i 0~255
(2)idtr寄存器指向的IDT表中的第i
(3)gdtr寄存器获得GDT的基地址,并在GDT中查找,以读IDT表项中的段选择符所标识的段描述符
(4)确定中断是由授权的发生源发出的。
Ø 中断:中断处理程序的特权不能低于引起中断的程序的特权(对GDT表项中的DPL vs CS寄存器中的CPL
Ø
(5)检查是否发生了特权级的变化,一般指是否由用户态陷入了内核态。
如果是由用户态陷入了内核态,控制单元必须开始使用与新的特权级相关的堆栈
a,读tr寄存器,访问运行进程的tss
b用与新特权级相关的栈段和栈指针装载ssesp寄存器。些值可以在进程的tss段中找到
c,在新的栈中保存ssesp以前的值,这些值指明了与旧特权级相关的栈的逻辑地址
(6)若发生的是故障,用引起异常的指令地址修改cseip寄存器的值,以使得这条指令在异常处理结束后能被再次执行
7)在栈中保存eflagscseip的内容
8)如果异常产生一个硬件出错码,则将它保存在栈中
9)装载cseip寄存器,其值分别是IDT表中第i项门描述符的段选择符和偏移量字段。这对寄存器值给出中断 或者异常处理程序的第一条指定的逻辑地址
12  从中断/异常返回
中断/异常处理完后,相应的处理程序会执行一条iret编指令,这条汇编指令让CPU控制单元做如下事情:
1)用保存在栈中的值装载cseipeflags寄存器。如果一个硬件出错码曾被压入栈中,那么弹出这个硬件出错码
2)检查处理程序的特权级是否等于cs中最低两位的值(这意味着进程在被中断的时候是运行在内核态还是用户态)。若是,iret终止执行;否则,转入3
3)从栈中装载ssesp寄存器。这步意味着返回到与旧特权级相关的栈
4)检查dsesfsgs段寄存器的内容,如果其中一个寄存器包含的选择符是一个段描述符,并且特权级比当前特权级高,则清除相应的寄存器。这么做是防止怀有恶意的用户程序利用这些寄存器访问内核空间
以上部分即中断和异常部分的基础知识,我们将在下面的文章中详细介绍中断和异常与代码相关的部分,主要讲解相关的
数据结构以及重要的代码。
编程异常:还需比较CPL与对应IDT表项中的DPL
CPUidtr寄存器指向IDT表的物理基地址
内核为每个异常提供了一个专门的异常处理程序
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值