中断、异常和系统调用

X86 CPU对中断的硬件支持

中断控制器的功能:把设备的中断信号,转换为CPU能够明白的中断向量。

中断(interrupt)、陷阱(trap)、异常(exception)

中断向量表中的项为门(gate),中断发生时,必须先通过这些门,才能进入相应的服务程序。

通过中断门进入中断服务时,会将CPU中断自动关闭(EFLAGS寄存器的IF标志位清0),以防嵌套中断的发生,而陷阱门不会。

中断中的优先级判断方式:根据中断向量找到对应的门,得到门描述符中的DPL,CPL必须大于等于该门的DPL(优先级必须大于等于门描述符的优先级,外部中断或异常则免去这一层检查),然后根据门描述符得到段描述符,CPL必须小于等于段描述符DPL(也就是说:中断时,只允许保存和提升CPU的运行级别)。

中断向量表由IDTR寄存器指向。

中断向量表IDT的初始化

Linux 内核中的中断机制的初始化函数:trap_init(用于系统保留的中断向量的初始化)、init_IRQ(外设中断的初始化)。

中断请求队列的初始化

中断向量表(IDT)中有两种表项,一种是为保留专用于CPU本身的中断门(缺页、除0、系统调用),另一种是外部中断。

通用中断可以有多个中断源,由中断请求队列描述(struct irq_desc irq_desc[NR_IRQS]描述)

驱动程序调用 request_irq函数,在中断请求队列中注册中断处理函数

中断的响应和服务

中断请求--》 CPU响应 --》 中断服务程序的调用与返回

CPU从中断控制器取得中断向量,然后通过中断向量从中断向量表IDT中找到相应的表项,得到一个中断门,通过中断门到达中断服务处理程序。

同一个中断通道上的中断处理必须串行化,也就是说:对于同一个CPU而言不允许同一个中断服务嵌套,而对于不同的CPU则不允许并发地进入同一个中断服务程序。

首先外设产生中断信号给中断控制器,中断控制器将其转换为中断向量发送给CPU,CPU通过查表(IDT)到达do_IRQ,然后将其转换为irq号,再从中断请求队列中(irq_desc)得到中断请求队列头,然后调用注册的中断处理程序(IRQ_PENDING用来串行化中断处理程序)

软中断

硬中断通常是外设对CPU的中断,软中断是硬件中断服务程序对内核的中断,而信号则是由内核对某个进程的中断。

软中断是一种机制,也是一种框架。在软中断的基础上又实现了tasklet,软中断允许不同CPU同时执行一个软中断处理函数(但是不允许在一个CPU上嵌套),而tasklet不允许。

时钟中断

内核在每次中断服务(以及系统调用和异常)完毕返回用户空间之前都要检查是否需要调度。

全局变量无符号整数jiffies记录着从开机以来时钟中断的次数。时钟中断的间隔与HZ有关。

tsc:时间戳计数器,用来提高时间上的精确度。

在时间中断处理函数中:会调用update_process_times,更新进程使用的时间。

Tips

当在系统调用中,执行copy_from_user函数时,用户填入一个不存在的地址时,处理过程如下:首先调用do_page_fault,然后调用find_vma,没有找到,然后才是异常表中找。而如果任其自然的话,则从异常返回以后,当前进程必然会接连不断的因执行同一条指令而产生新的异常,落入万劫不复的地步。

资料

Linux中断机制:硬件处理,初始化和中断处理

https://blog.csdn.net/jus3ve/article/details/81517907

posted @ 2020-04-30 16:42  r1ng0  阅读(272)  评论(0编辑  收藏  举报