免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 1149 | 回复: 3
打印 上一主题 下一主题

[内核入门] 穿过中断门之后。。 [复制链接]

论坛徽章:
13
15-16赛季CBA联赛之八一
日期:2016-07-08 21:00:1415-16赛季CBA联赛之同曦
日期:2017-02-15 14:26:1515-16赛季CBA联赛之佛山
日期:2017-02-20 14:19:2615-16赛季CBA联赛之青岛
日期:2017-05-07 16:49:1115-16赛季CBA联赛之广夏
日期:2017-07-30 09:13:1215-16赛季CBA联赛之广东
日期:2018-07-05 22:34:3615-16赛季CBA联赛之江苏
日期:2018-09-03 12:10:2115-16赛季CBA联赛之上海
日期:2018-09-25 03:49:2215-16赛季CBA联赛之广东
日期:2018-09-25 04:09:12
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2016-10-31 16:31 |只看该作者 |倒序浏览
本帖最后由 _nosay 于 2016-10-31 16:55 编辑

http://bbs.chinaunix.net/thread-4255522-1-1.html(续)

通过trap_init()、init_IRQ()函数可以看到内核对0~0x20、0x80以及其它224个门的初始化,接下来一起学习穿过这些门后的完整执行过程,取三个具有代表意义的门:
① set_trap_gate(14, &page_fault);
② set_system_gate(SYSCALL_VECTOR, &system_call);
③ set_intr_gate(vector, interrupt);  // i=3时,vector=0x20+3

  • set_intr_gate(vector, interrupt);
    i=3时,该函数将0x23号门设置为中断门,穿过这道门时,会执行到interrupt[3]指向的IRQ0x03_interrupt()函数:
  1. asmlinkage void IRQ0x03_interrupt();
  2. __asm__( \
  3. "\n" \
  4. "IRQ0x03_interrupt: \n\t" \
  5. "pushl $0x03-256 \n\t" \
  6. "jmp common_interrupt");
复制代码
   这段代码将中断号(与中断向量之间有0x20偏移,至于为什么减256,以后自然会知道)压入栈中,跳转到common_interrupt标号处执行:
   

    这是进入中断处理过程之前的"寄存器现场",用于中断完成之后恢复原来的"环境"执行:
   

    通过上述可以看到,底层语言一般能更精确的控制程序逻辑,到此,终于到了我们习以为常的环境了,即do_IRQ()函数中,这个函数主要是执行一串函数,找到当前产生中断的硬件真正需要执行的动作,以及考虑到多CPU、多硬件并发产生同一种中断,将中断响应过程“串行化”的过程:
    (开发过稍复杂的多进程或多线程软件后,肯定理解“可重入函数”、“进程/线程安全函数”这些概念:比如同一个函数在多进程或多线程中执行,并且函数中会读写某些全局资源,那么就要通过加锁等措施保证可重入,或者说进程/线程安全,而串行化是保证硬件驱动工程师注册的函数,不可能执行到途中被打断暂停,而又从头开始执行,为中断函数的编写减轻了负担)
   

  • ret_from_intr
  1. ENTRY(ret_from_intr)
  2. GET_CURRENT(%ebx)
  3. movl EFLAGS(%esp),%eax # mix EFLAGS and CS
  4. movb CS(%esp),%al
  5. testl $(VM_MASK | 3),%eax # return to VM86 mode or non-supervisor?
  6. jne ret_with_reschedule
  7. jmp restore_all
复制代码
   这里根据中断前EFLAGS寄存器、CS段寄存器判断恢复中断前现场前,是否需要进行一次进程调度(详见《Linux内核源代码情景分析》第四章);
    然后restore_all恢复中断前的所有寄存器值,包换cs、eip,即CPU恢复到中断前的状态继续执行。

  • set_trap_gate(14, &page_fault);
  • set_system_gate(SYSCALL_VECTOR, &system_call);
    穿过14、SYSCALL_VECTOR门的与穿过中断门过程基本一致:保存现场→执行中断处理函数→恢复现场。
    区别:
    ① 0~0x20是专用门,不用像进入中断门之后是“一串”函数,system_call()面对的是多种系统调用,通过寄存器传来的系统调用号区别,do_IRQ()面对的是多种硬件,通过产生中断硬件区别;
    ② 进入system_call()之前,orig_eax处传的是系统调用号,do_IRQ()之前,orig_eax处传的是中断号(-256);
    ③ 系统调用肯定是从用户态切换到内核态,需要将ss从用户栈切换到内核栈(一定要保证更改ss寄存器的时机,要保证在用户栈的值,在定要在修改ss之前压栈)

    好,到此暂且先忽略宽度,长度上又向前跨了一步,但还是没有到达终点。
    对于中断门,不是已经看到do_IRQ()从“一串”函数中找到相匹配的执行了么,不是到终点了么,不是胜利了么?
    穿越中断门时,CPU会自动将中断关闭,那么从中断门"出来"之前,该CPU就不响应中断了(其它CPU还是可以,否则do_IRQ()函数中就不需要IRQ_INPROGRESS、IRQ_PENDING标记了),造成中断丢失,所以特别对于单CPU系统,就希望关中断时间能尽量短一些(否则比如一个报文大老远传过来,结果由于网卡丢包严重,而导致网络中需要大量重传,是多么的不和谐),从而do_IRQ()找到的最终函数,可能只是最终任务最关键的部分,然后很快就返回了,而剩余要执行的部分称为“bottom half”,不需要访问公共资源,即不需要考虑可重入,可以在开中断时"不慌不忙"的执行。就如同很忙的时候脑筋比较乱,当想起一件事时就先记下来,有空了再去做一样。
    关于“bottom half”及其扩展,下次再一起学习

论坛徽章:
13
15-16赛季CBA联赛之八一
日期:2016-07-08 21:00:1415-16赛季CBA联赛之同曦
日期:2017-02-15 14:26:1515-16赛季CBA联赛之佛山
日期:2017-02-20 14:19:2615-16赛季CBA联赛之青岛
日期:2017-05-07 16:49:1115-16赛季CBA联赛之广夏
日期:2017-07-30 09:13:1215-16赛季CBA联赛之广东
日期:2018-07-05 22:34:3615-16赛季CBA联赛之江苏
日期:2018-09-03 12:10:2115-16赛季CBA联赛之上海
日期:2018-09-25 03:49:2215-16赛季CBA联赛之广东
日期:2018-09-25 04:09:12
2 [报告]
发表于 2016-11-01 12:31 |只看该作者
回复 1# _nosay

理解错误:并不是可重入的中断处理过程,才用bottom half机制在开中断时执行,后面专门总结bottom half

论坛徽章:
20
程序设计版块每日发帖之星
日期:2015-08-17 06:20:00程序设计版块每日发帖之星
日期:2016-07-16 06:20:00程序设计版块每日发帖之星
日期:2016-07-18 06:20:00每日论坛发贴之星
日期:2016-07-18 06:20:00黑曼巴
日期:2016-12-26 16:00:3215-16赛季CBA联赛之江苏
日期:2017-06-26 11:05:5615-16赛季CBA联赛之上海
日期:2017-07-21 18:12:5015-16赛季CBA联赛之青岛
日期:2017-09-04 17:32:0515-16赛季CBA联赛之吉林
日期:2018-03-26 10:02:16程序设计版块每日发帖之星
日期:2016-07-15 06:20:0015-16赛季CBA联赛之江苏
日期:2016-07-07 18:37:512015亚冠之萨济拖拉机
日期:2015-08-17 12:21:08
3 [报告]
发表于 2016-11-05 11:29 |只看该作者
赞~

挑个小问题,kstat.irq[cpus][irq]++跟ifconfig之间的对应关系有些牵强,不如换成cat/proc/interrupts的输出。

论坛徽章:
13
15-16赛季CBA联赛之八一
日期:2016-07-08 21:00:1415-16赛季CBA联赛之同曦
日期:2017-02-15 14:26:1515-16赛季CBA联赛之佛山
日期:2017-02-20 14:19:2615-16赛季CBA联赛之青岛
日期:2017-05-07 16:49:1115-16赛季CBA联赛之广夏
日期:2017-07-30 09:13:1215-16赛季CBA联赛之广东
日期:2018-07-05 22:34:3615-16赛季CBA联赛之江苏
日期:2018-09-03 12:10:2115-16赛季CBA联赛之上海
日期:2018-09-25 03:49:2215-16赛季CBA联赛之广东
日期:2018-09-25 04:09:12
4 [报告]
发表于 2016-11-05 13:34 |只看该作者
回复 3# nswcfd

您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP