设为首页 收藏本站
查看: 685|回复: 0

[经验分享] 基于linux-3.3内核的ARM异常处理之概述

[复制链接]

尚未签到

发表于 2015-12-9 16:03:17 | 显示全部楼层 |阅读模式
ARM处理器有7种工作模式 :

USR 模式
    正常用户模式,程序正常执行模式

FIQ 模式(Fast Interrupt Request)
处理快速中断,支持高速数据传送或通道处理

IRQ 模式
    处理普通中断
   
SVC 模式(Supervisor)
    操作系统保护模式,处理软件中断swi  reset

ABT 中止(Abort mode){数据、指令}
    处理存储器故障、实现虚拟存储器和存储器保护

UND 未定义(Undefined)
   处理未定义的指令陷阱,支持硬件协处理器的软件仿真

SYS 系统模式(基本上=USR)(System)
   运行特权操作系统任务

这7种模式,除了用户模式之外的其他6种处理器模式称为特权模式

特权模式下,程序可以访问所有的系统资源,也可以任意地进行处理器模式的切换。

特权模式中,除系统模式外,其他5种模式又称为异常模式。

下面就来讨论一下发生异常时,linux的处理过程

首先引入中断异常向量表。
中断异常向量表就是一张函数表格,里面放置了一组函数,存放在一个固定位置,当发生异常时,处理器被强制从这个位置取出
函数执行。

中断异常向量表在启动之前存在于地址0x00000000,这是uboot的中断异常向量表,
u-boot\arch\arm\cpu\arm920t\start.S 40行
.globl _start
_start:bstart_code                      // 0x00
ldrpc, _undefined_instruction          // 0x04     未定义指令异常
ldrpc, _software_interrupt             // 0x08     软件中断异常
ldrpc, _prefetch_abort                 // 0x0c     指令预取中止异常
ldrpc, _data_abort                     // 0x10     数据访问中止异常
ldrpc, _not_used                       // 0x14     保留
ldrpc, _irq                            // 0x18     外部中断请求异常
ldrpc, _fiq                            // 0x1c     快速中断请求异常
所以刚开始中断向量表的地址是0x00~0x1c

0x00地址放的跳转指令就是跳转到执行uboot的引导启动代码

在引导了kernel后,中断异常向量表会存在于地址0xffff0000,追踪代码如下:
start_kernel
    setup_arch(&command_line);
        early_trap_init();
            #if defined(CONFIG_CPU_USE_DOMAINS)
                unsigned long vectors = CONFIG_VECTORS_BASE;
            #else
                unsigned long vectors = (unsigned long)vectors_page;
            #endif
            ...
            memcpy((void *)vectors, __vectors_start, __vectors_end - __vectors_start);  //这三条指令就是搬移中断异常向量表指令
            memcpy((void *)vectors + 0x200, __stubs_start, __stubs_end - __stubs_start);
            memcpy((void *)vectors + 0x1000 - kuser_sz, __kuser_helper_start, kuser_sz);

为什么会被拷到0xffff0000?
从上面的代码看CONFIG_CPU_USE_DOMAINS有没有被设置,我们去内核目录的.config文件查看,它被设置了,所以
vectors = CONFIG_VECTORS_BASE,而在.config文件中CONFIG_VECTORS_BASE=0xffff0000

中断异常向量表被拷贝到0xffff0000地址,中断异常处理函数也拷贝到0xffff0000 + 0x200的地址上去

考察汇编的时候到了,被虐的体无完肤啊,建议看之前恶补一下

在哪里拷贝呢?
从上面的代码看出,异常向量表从__vectors_start拷贝,中断异常处理函数从__stubs_start拷贝,这段代代码在
linux-3.3\arch\arm\kernel\entry-armv.S 1132行
__vectors_start:
  ARM(swiSYS_ERROR0)
  THUMB(svc#0)                          // 0x00
  THUMB(nop)                            // 0x02
    W(b)vector_und + stubs_offset            // 0x04
    W(ldr)pc, .LCvswi + stubs_offset         // 0x08
    W(b)vector_pabt + stubs_offset           // 0x0c
    W(b)vector_dabt + stubs_offset           // 0x10
    W(b)vector_addrexcptn + stubs_offset     // 0x14
    W(b)vector_irq + stubs_offset            // 0x18
    W(b)vector_fiq + stubs_offset            // 0x1c

.globl__vectors_end
__vectors_end:

以上是介绍了异常向量表,当发生异常的时候,处理器会跳转到到这些地方来执行,不同的异常对应不同的入口地址。发生具体的异常会怎么处理,请见下面的博文

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-148890-1-1.html 上篇帖子: SIdView 嵌入式Linux集成开发环境 下篇帖子: 基于linux-3.3内核的ARM异常处理之irq异常处理
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表