博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

[OS]Exception and Interrupt

Posted on 2010-06-11 09:47  xuczhang  阅读(535)  评论(0编辑  收藏  举报

 

中断分为同步中断和异步中断。在Intel微处理手册中,同步中断称为异常(exception),异步中断称为中断(interrupt)。

同步中断(异常)是当指令执行时由CPU控制单元产生的,它只有在一条指令终止执行后CPU才会发出中断。

异步中断(中断)是由间隔定时器和I/O设备产生的。

中断分为可屏蔽和非屏蔽。

异常分为

1. 故障(fault)

重新执行当前指令,如Page Fault。

2. 陷阱(trap)

执行下一条指令,如Debugger

3. 异常中止(abort)

发生一个严重的错误,强制终止受影响的进程。

4. 编程异常(programmed exception)

由int或int3指令触发。也叫做软中断(software interrupt),有两种常用的用途:执行系统调用和给调试程序通报一个特定的事件。

 

处理中断时处理器清IF标志,从而关闭将来会发生的可屏蔽中断。而处理异常时,处理器不修改IF标志。

 

中断和异常处理程序的嵌套执行

 image

中断处理程序必须永不堵塞,也就是中断处理程序运行期间不能发生进程切换。而异常处理程序通常不会发生异常(异常一般由用户态程序引起),而这里有一个特例就是Page Fault异常(由内核引起),然而Page Fault从不进一步引起异常,所以与异常相关的至多有两个内核控制路径(第一个由系统调用引起,第二个由缺页引起)嵌套。

一个中断处理程序既可以抢占其他的中断处理程序,也可以抢占异常处理程序。相反,异常处理程序从不抢占中断处理程序。也就是说中断处理程序从不执行可以导致缺页的操作。

 

IDT初始化

在内核启用中断之前,IDT的初始地址必须装载到idtr寄存器,并初始化表中的每项。

由于int指令允许用户态进程发出一个中断信号,其值可以是0-255任意一个向量。因此,为了防止用户通过int指令模拟非法的中断和异常,IDT初始化时会把中断或陷阱门的DPL设置成0来实现。然而,在使用系统调用的时候,用户态进程就必须能发出一个编程异常,此时就要把它的DPL设置为3。如int 3。

IDT的两遍初始化,第一遍是在系统启动的时候给BIOS使用的,第二遍是操作系统初始化时Linux自己使用的。

 

异常处理

Double fault通过任务门来找到正确的上下文信息。

 

IRQ

image

 

 

 

中断处理

 

#ifdef CONFIG_CPU_SH2A
asmlinkage void do_divide_error(unsigned long r4, unsigned long r5,
                unsigned long r6, unsigned long r7,
                struct pt_regs __regs)
{
    siginfo_t info;
 
    switch (r4) {
    case TRAP_DIVZERO_ERROR:
        info.si_code = FPE_INTDIV;
        break;
    case TRAP_DIVOVF_ERROR:
        info.si_code = FPE_INTOVF;
        break;
    }
 
    force_sig_info(SIGFPE, &info, current);
}
#endif