3075|0

10

帖子

0

TA的资源

一粒金砂(初级)

楼主
 

Linux-2.6.21 S3c6400中断剖析<三>(原创)-上海嵌入式索漫科技培训教材 [复制链接]

作者:下家山(请尊重原创,转载请注明)  http://www.xiajiashan.com 

三:当中断发生时,kernel怎么知道的???

3.1  ARM体系中关于异常的定义

要解释这个问题,首先要明白ARM体系关于中断的一些规定。在ARM   体系结构中,定义了八种异常中断(注意这里的异常并非错误),他们分别是:

-复位

-未定义指令
-软件中断预取指令中断
-数据中断
-保留
-中断请求
-快速中断请求

这八个异常中断有八个固定的向量地址,当异常发生时,CPU就跳到相应的地址去执行。这个八个向量地址为:

 

 

0x00000000
0x00000004
0x00000008
0x0000000c
0x00000010
0x00000014
0x00000018
0x0000001c

有些系统映射(本人理解)到了高端地址,如:

0xffff0000
0xffff0004
0xffff0008
0xffff000c
0xffff0010
0xffff0014
0xffff0018
0xffff001c

这样,当CPU被复位时,系统就会跳到0x00000000(0xffff0000)处执行,以此类推,当irq中断发生时,系统就会跳到0x00000018处执行。

3.2 对entry-armv.s的理解

      好了,明白了这一点,接下来就要看linux  kernel是怎么来初始化这八个向量地址的。linux 对向量表的初始化在arch/arm/kernel/entry-armv.s中.关于这个文件的理解是很费解的,关于这个文件零碎的一些介绍网上很多,凑起来应该也能理解,下面这篇blog写的很好,值得参考

http://hi.baidu.com/wudx05/blog/item/5314935c834f4e41fbf2c0dc.html

『这里需要做点补充:在.macro irq_handler中有调用get_irqnr_preamble和get_irqnr_and_base,这两个tag也是一个macro,都定义在/include/asm/arch/entry-macro.s中』

 

       这样,当中断(irq)发生后,系统会跳到0xffff0018处执行,从而会跳到vector_irq + stubs_offset处执行,vector_irq是通过vector_stub irq, IRQ_MODE, 4 调用的,而vector_stub      irq, IRQ_MODE, 4是通过宏.macro    vector_stub, name, mode, correction=0展开的。最终会调用到bne    asm_do_IRQ。

3.3  asm_do_IRQ来自哪里呢?

       asm_do_IRQ是一个C函数,定义在/arch/arm/kernel/irq.c中。原型为:

/*

 * do_IRQ handles all hardware IRQ's.  Decoded IRQs should not

 * come via this function.  Instead, they should provide their

 * own 'handler'

 */

asmlinkage void asm_do_IRQ(unsigned int irq, struct pt_regs *regs)

{

       struct pt_regs *old_regs = set_irq_regs(regs);

       struct irq_desc *desc = irq_desc + irq;

 

       /*

        * Some hardware gives randomly wrong interrupts.  Rather

        * than crashing, do something sensible.

        */

       if (irq >= NR_IRQS)

              desc = &bad_irq_desc;

 

       irq_enter();

 

       desc_handle_irq(irq, desc);/*执行irq (中断号)对应的irq_desc结构体的回调函数handle_irq,desc_handle_irq 函数原型定义在/include/arm-arm/mach/irq.h中,而irq_desc->handle_irq最终会调用handle_level_irq函数,那么irq_desc->handle_irq是在哪里被初始化的呢?后面会讲到*/

 

       /* AT91 specific workaround */

       irq_finish(irq);/*做些收尾工作*/

 

       irq_exit();/*做些收尾工作*/

       set_irq_regs(old_regs); /*做些收尾工作*/

}

那么asm_do_IRQ里的参数来自哪里呢?这要看看汇编调用C函数时的参数传递规则了,而定义时asm_do_IRQ前面有asmlinkage 标志,这一标志指示asm_do_IRQ到堆栈里去取参数,故在/arch/arm/kernel/entry-armv.s   中r0 = irq number, r1 = struct pt_regs是被压栈的。

       到了这里中断已执行完毕,怎么还没有出现调用我们注册中断时的函数呢?

2009-2-13   下家山     写于上海.漕河泾

                                   有什么问题可以给我邮件ximenpiaoxue4016@sina.com或加我群198204885

点赞 关注

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

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/8 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表