为了账号安全,请及时绑定邮箱和手机立即绑定

结合中断上下文切换和进程上下文切换分析Linux内核的一般执行过程

标签:
测试

中断上下文的切换

进程上下文的切换

异常处理过程:

下面从逻辑上完整走一遍中断处理过程(结合中断上下文的切换,以定时器中断为例,假设从用户态进入中断):

1. 定时器连接在8259A可编程中断控制器(PIC,Programmable Interrupt Controller)的0号IRQ线上,0号IRQ线对应32+0=32号中断向量。中断控制器又与CPU的INTR引脚相连。当定时器产生中断时,中断控制器把对应的中断向量32放到一个I/O端口上,从而允许CPU通过数据总线读到这个向量。然后PIC就向CPU的中断引脚发送一个低电平,即产生一个中断。CPU对这个信号做应答,PIC收到应答后,清INTR引脚。

2. 硬件保存现场:SS、SP、eflags、cs、eip,保存到被中断进程的内核堆栈中(tr寄存器保存当前进程的tss段,而tss段里有最后一次访问内核栈的指针)。

3. 读idtr寄存器指向的中断描述符表(idt)的第30项,得到相应的中段描述符,并用中断描述符里的段选择符(还要根据gdtr寄存器指向的全局描述符表gdt获取段选择符对应的段描述符)和偏移量装载CPU的cs和eip寄存器。这样就进入到了中断处理程序的入口,CPU开始执行中断处理程序入口的代码ENTRY(interrupt)。

4. 而在系统初始化时,通过调用init_IRQ()函数用interrupt数组的每一项来初始化idt表,而interrupt数组的每一项都是一样的内容,都是interrupt。所无论发生哪一种中断,都会跳转到一段汇编代码ENTRY(interrupt)处,这就是每一个中断处理程序的入口。它首先在内核栈上push中断向量号,然后跳转到common_interrupt处。

https://img1.sycdn.imooc.com//5ee491c00001c85204940218.jpg

5. common_interrupt首先使用SAVE_ALL继续保存现场(按照pt_regs数据结构保存),然后无论哪一个中断都会调用do_IRQ函数,这个函数就一个参数即指向pt_regs数据结构的指针,使用%eax寄存器传递。

6. do_IRQ函数使用全局数组irq_desc,irq_desc既是数组名也是数组中每个元素的数据类型。每个中断号对应一个irq_desc,irq_desc里包含irqaction链表,我们将每个设备对应的中断服务例程打包成irqaction,并通过setup_irq函数将其加入相应的irqaction链表中。handle_IRQ_event()函数负责扫描action链表,依次执行,直到找到对应设备的中断服务例程,然后执行。

https://img1.sycdn.imooc.com//5ee491c10001080a13390930.jpg

7. 跳转到ret_from_intr。

所以在外部看来就是:定时器发生中断了,定时器中断服务例程执行。

点击查看更多内容
TA 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
  • 推荐
  • 评论
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消