"); //-->
作者:下家山(请尊重原创,转载请注明) 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
专栏文章内容及配图由作者撰写发布,仅供工程师学习之用,如有侵权或者其他违规问题,请联系本站处理。 联系我们
相关推荐
非对称作战中的护卫手段与装备技术
可控硅变颇同步启动器中的光敏二傲霄线路
药片自动数片机用光敏线路
消息称 AMD RX 9000 系列显卡价格“非常犀利”,猛攻英伟达
英特尔开发板部署 YOLOv5:完成透明物体目标检测
俄即将发射新型导航卫星
DeepSeek 全系模型上线讯飞开放平台:首发精调,限时免费
存储器的混乱
电容降压式经济灯电路
简易照度测量仪电路
诺基亚总裁兼首席执行官换帅,4 月 1 日起 Justin Hotard 接任
光控全自动发米机电路
系统分析员备考之系统工程篇(系统工程基础
常用ARM指令
自己动手写操作系统
新的系统级设计语言
easyarm2210web服务器
(2025.2.10)半导体春节期间要闻
Altera器件选型指南
使用 OpenVINO™ 条件编译功能,压缩 Windows 应用体积
多拦截器——弹道导弹防御的新锐
移动IP的多层次位置管理及路由优化
WCDMA 系统及其关键技术探讨
谷歌DeepMind CEO称DeepSeek是“中国最好作品”
特斯拉 2025 年开局不佳,全球多地销量下滑
Intro to TechTalk
准单向收费全国已无悬念
如何在 Raspberry Pi 5 上运行 DeepSeek R1
QUARTUS II 中文教程
英特尔开发板试用:图像检测算法在RFID生产中产品缺陷检测的应用