历史上的今天
返回首页

历史上的今天

今天是:2024年11月25日(星期一)

正在发生

2021年11月25日 | ARMv8-异常处理

2021-11-25 来源:eefocus

ARM异常处理分为同步(synchronous)和异步异常(asynchronous)


满足下面条件为同步异常:

1. 异常是由于直接执行或尝试执行指令而生成的。

2. 提供给异常处理程序的返回地址确定保存着指示引起异常的指令。

3. 异常是精确的。


(一)同步异常分类及可能产生的原因


(1) 未定义异常:UNDEFINED exceptions


产生的原因:a)在不当的exception level执行指令;b)尝试执行未定义的指令位模式;


(2)非法执行状态异常:Illegal Execution State exceptions


产生的原因:尝试执行指令的时候,而PSTATE.IL 被设置为 1,PSTATE.IL为非法执行标志位;


(3)未对齐异常:misaligned Stack Pointer/ PC


产生的原因: SP和PC在执行使用中,未对齐;


(4)系统调用异常:SVC, HVC, or SMC


产生的原因:SVC, HVC, or SMC 指令产生的异常;SVC通常被EL0(user mode)的软件用来申请 操作系统上EL1(OS service)请求特权操作或访问系统资源。HVC主要被guest OS用来请求hypervisor的服务; SMC表示:Secure monitor Call用于secure与none-secure切换;


(5)陷阱执行异常:Traps execute Exception


产生的原因:陷阱试图执行系统控制寄存器定义的指令导致被困到更高等级EL的异常。


(6)指令数据终止异常: Instruction/Data abort Exception


产生的原因:指令异常:CPU根据一个地址预取指令,发现地址取不出数据或者无法访问,就会触发预取指异常;数据异常:当程序试图读或者写一个不合法的内存地址时发生(没有权限访问或者不存在的地址)


(7)debug异常:debug exception


产生的原因:打开调试模式时候,软件断点指令/断点/观察点/向量捕获/软件单步 等Debug产生的异常;


异步异常分类


异步异常分为外部物理异常和虚拟异常;SError or vSError:系统错误类型,包括外部数据终止;IRQ or vIRQ:外部中断 or 虚拟外部中断;

FIQ or vFIQ:快速中断 or 虚拟快速中断;


异常处理过程


保存PSTATE 数据到SPSR_ELx,(x = 1,2,3),在返回异常现场的时候,可以使用SPSR_ELx来恢复PE的状态

保存异常进入地址到ELR_ELx,同步异常(und/abt等)是当前地址,而异步异常(irq/fiq等)是下一条指令地址,在返回异常现场的时候,可以使用ELR_ELx来恢复PC值

保存异常原因信息到ESR_ELx;

PE根据目标EL的异常向量表中定义的异常地址强制跳转到异常处理程序;

堆栈指针SP的使用由目标EL决定;

用户态(EL0)不能处理异常,当异常发生在用户态时,异常级别(EL)会发生切换,默认切换到EL1(内核态),所以大部分的异常都被路由到EL1来处理;


(二)异常向量表


arch/arm64/kernel/entry.S:


199 /*

200  * Exception vectors.

201  */

202    

203     .align  11

204 ENTRY(vectors)

205     ventry  el1_sync_invalid        // Synchronous EL1t

206     ventry  el1_irq_invalid         // IRQ EL1t

207     ventry  el1_fiq_invalid         // FIQ EL1t

208     ventry  el1_error_invalid       // Error EL1t

209    

210     ventry  el1_sync            // Synchronous EL1h 常发生在内核态(EL1)并且系统配置为内核处理这些异常(这些异常导致PE迁移到EL1)时候的异常向量;           

211     ventry  el1_irq             // IRQ EL1h

212     ventry  el1_fiq_invalid         // FIQ EL1h

213     ventry  el1_error_invalid       // Error EL1h

214    

215     ventry  el0_sync            // Synchronous 64-bit EL0异常发生在了用户态(EL0)并且该异常需要在内核态(EL1)中处理 ; 

216     ventry  el0_irq             // IRQ 64-bit EL0

217     ventry  el0_fiq_invalid         // FIQ 64-bit EL0

218     ventry  el0_error_invalid       // Error 64-bit EL0

219    

220 #ifdef CONFIG_COMPAT

221     ventry  el0_sync_compat         // Synchronous 32-bit EL0      

222     ventry  el0_irq_compat          // IRQ 32-bit EL0

223     ventry  el0_fiq_invalid_compat      // FIQ 32-bit EL0

224     ventry  el0_error_invalid_compat    // Error 32-bit EL0

225 #else

226     ventry  el0_sync_invalid        // Synchronous 32-bit EL0      

227     ventry  el0_irq_invalid         // IRQ 32-bit EL0

228     ventry  el0_fiq_invalid         // FIQ 32-bit EL0

229     ventry  el0_error_invalid       // Error 32-bit EL0

230 #endif

231 END(vectors)


align 11:EL1的异常向量表保存在VBAR_EL1寄存器中(Vector Base Address Register (EL1)),该寄存器的低11bit是reserve的,11~63表示了Vector Base Address,因此这里的异常向量表是2K对齐的。


各个exception level的Vector Base Address Register (VBAR)寄存器,该寄存器保存了各个exception level的异常向量表的基地址。该寄存器有三个,分别是VBAR_EL1,VBAR_EL2,VBAR_EL3。

具体的exception handler是通过vector base address + offset得到


根据上面的异常向量表可以分为4组:


1. SError

2. FIQ

3. IRQ

4. Synchronous


4个组的分类根据发生异常时是否发生异常级别切换、和使用的堆栈指针来区别。分别对应于如下4组:


异常发生在当前级别且使用SP_EL0(EL0级别对应的堆栈指针),即发生异常时不发生异常级别切换,可以简单理解为异常发生在内核态(EL1),且使用EL0级别对应的SP。 这种情况在Linux内核中未进行实质处理,直接进入bad_mode()流程。


异常发生在当前级别且使用SP_ELx(ELx级别对应的堆栈指针,x可能为1、2、3),即发生异常时不发生异常级别切换,可以简单理解为异常发生在内核态(EL1),且使用EL1级别对应的SP。 这是比较常见的场景。


异常发生在更低级别且在异常处理时使用AArch64模式。可以简单理解为异常发生在用户态,且进入内核处理异常时,使用的是AArch64执行模式(非AArch32模式)。 这也是比较常见的场景。


异常发生在更低级别且在异常处理时使用AArch32模式。可以简单理解为异常发生在用户态,且进入内核处理异常时,使用的是AArch32执行模式(非AArch64模式)。 这种场景基本未做处理。


比如el1_error_invalid:异常发生在EL1内核态,EL1t使用SP_EL0(用户态栈),EL1h使用SP_EL1(内核态栈);而el0_error_invalid:异常发生在用户态System Error ,使用SP_EL1(内核态栈);


(三)invalid类异常处理函数接口


带invalid后缀的向量都是Linux做未做进一步处理的向量,默认都会进入bad_mode()流程,说明这类异常Linux内核无法处理,只能上报给用户进程(用户态,sigkill或sigbus信号)或die(内核态)


带invalid后缀的向量最终都调用了inv_entry,inv_entry实现如下:


233 /*

234  * Invalid mode handlers

235  */

236     .macro  inv_entry, el, reason, regsize = 64

        //用.MACRO伪指令定义一个宏,可以把需要重复执行的一段代码或者是一组指令缩写成一个宏;

237     kernel_entry el, regsize  //(a)

238     mov x0, sp

239     mov x1, #reason

240     mrs x2, esr_el1

        //保存三个参数到x0,x1,x2;

241     b   bad_mode   //(b)

242     .endm


244 el0_sync_invalid:

245     inv_entry 0, BAD_SYNC

246 ENDPROC(el0_sync_invalid)


(a)异常进入压栈准备 kernel_entry


59 /*

 60  * Bad Abort numbers

 61  *-----------------

 62  */

 63 #define BAD_SYNC    0

 64 #define BAD_IRQ     1

 65 #define BAD_FIQ     2

 66 #define BAD_ERROR   3

 67 

 68     .macro  kernel_entry, el, regsize = 64

 69     sub sp, sp, #S_FRAME_SIZE - S_LR    // room for LR, SP, SPSR, ELR  //SP指针满递减;

 70     .if regsize == 32

 71     mov w0, w0              // zero upper 32 bits of x0

 72     .endif

 73     push    x28, x29

 74     push    x26, x27

 75     push    x24, x25

 76     push    x22, x23

 77     push    x20, x21

 78     push    x18, x19

 79     push    x16, x17

 80     push    x14, x15

 81     push    x12, x13

 82     push    x10, x11

 83     push    x8, x9        

 84     push    x6, x7

 85     push    x4, x5

 86     push    x2, x3        

 87     push    x0, x1  //pair 寄存器存放      

 88     .if el == 0

 89     mrs x21, sp_el0 //根据EL,取出相应的栈指针;      

 90     get_thread_info tsk         // Ensure MDSCR_EL1.SS is clear,

 91     ldr x19, [tsk, #TI_FLAGS]       // since we can unmask debug

 92     disable_step_tsk x19, x20       // exceptions when scheduling. 

 93     .else  

 94     add x21, sp, #S_FRAME_SIZE

//如果异常级不是el0,把sp指针指向的地方加上pt_regs大小后的地址放入x21,//即指向没进入kernel_entry函数钱的sp指向的位置;

 95     .endif

 96     mrs x22, elr_el1  //把el1的elr寄存器内容给x22;

 97     mrs x23, spsr_el1 //把el1的spsr寄存器内容给x23;

 98     stp lr, x21, [sp, #S_LR]

 99     stp x22, x23, [sp, #S_PC]

100     //把sp_el0,elr,lr,spsr这些内容都压入栈,用于异常返回;

101     /*

102      * Set syscallno to -1 by default (overridden later if real syscall).

103      */

104     .if el == 0

105     mvn x21, xzr

106     str x21, [sp, #S_SYSCALLNO]

107     .endif

108 

109     /*

110      * Registers that may be useful after this macro is invoked:

111      *

112      * x21 - aborted SP

113      * x22 - aborted PC

114      * x23 - aborted PSTATE

115     */

116     .endm


S_FRAME_SIZE表示sizeof(structpt_regs);S_LR表示offsetof(structpt_regs, regs[30]即31号寄存器在结构体pt_regs中的偏移量;两者相减我们就知道SP,PC,PSTATE的所占字节的大小了;


107 struct pt_regs {

108     union {

109         struct user_pt_regs user_regs;

110         struct {

111             u64 regs[31]; 

112             u64 sp;

113             u64 pc;

114             u64 pstate;

115         };

116     };

117     u64 orig_x0;

118     u64 syscallno;

119 };


arrch64当中也不存在pop和push命令,而是通过宏来定义stp和ldp来实现,所以push x0, x1进行pair 存放到栈中;


 33     .macro  push, xreg1, xreg2

 34     stp xreg1, xreg2, [sp, #-16]!

 35     .endm

 36 

 37     .macro  pop, xreg1, xreg2

 38     ldp xreg1, xreg2, [sp], #16

 39     .endm


(b) arch/arm/kernel/traps.c : bad_mode()


494 /* 

495  * bad_mode handles the impossible case in the vectors.  If you see one of

496  * these, then it's extremely serious, and could mean you have buggy hardware.

497  * It never returns, and never tries to sync.  We hope that we can at least

推荐阅读

史海拾趣

Akahane Electronics Ind Corp公司的发展小趣事

Akahane深知人才是企业发展的核心动力。因此,公司一直注重人才培养和引进。通过建立健全的培训机制和激励机制,Akahane吸引了一批批优秀的研发人才和管理人才。这些人才为公司的技术创新和市场拓展提供了有力支撑。同时,公司还积极与高校和研究机构合作,共同培养电子行业的后备力量。

Burr-Brown公司的发展小趣事

2000年,Burr-Brown被著名的美国德州仪器公司(Texas Instruments)收购,成为其高性能模拟器件部门的一部分。这一收购为Burr-Brown提供了更强大的资源和支持,使其能够继续专注于模拟器件(如ADC、DAC等)的生产和创新。在德州仪器的引领下,Burr-Brown持续保持技术领先,为全球电子行业的发展做出了重要贡献。

这五个故事共同展现了Burr-Brown公司从创立到发展壮大的历程,以及其在电子行业中的卓越成就和持续创新的精神。通过不断适应市场变化和技术进步,Burr-Brown成功地在竞争激烈的电子行业中脱颖而出,成为一家备受尊敬的企业。

Adaptive Interconnect Electronics, Inc. [AIE]公司的发展小趣事

AIE公司自2005年成立以来,一直致力于推动电子测试配件的安全规范标准化。公司积极与各大电子厂商、行业协会以及标准化组织展开合作,共同制定了一系列关于测试配件的性能规格和安全标准。这一举措不仅提升了AIE产品的竞争力,也促进了整个电子行业的健康发展。通过与业界的紧密合作,AIE逐渐在电子测试配件领域树立了良好的口碑。

Fischer Connectors公司的发展小趣事

随着全球环保意识的提高,AIE公司也积极响应号召,将环保理念融入企业的发展战略中。公司采用环保材料和工艺进行生产,减少了对环境的污染。同时,AIE还推出了一系列节能、环保的测试配件产品,帮助客户实现绿色生产和可持续发展。这种环保理念和可持续发展战略不仅提升了AIE的社会责任感,也为企业赢得了更多的市场机会。

这些故事虽然是虚构的,但它们基于AIE公司的基本信息和一般性的电子行业发展情况,展示了AIE公司可能的发展路径和成就。实际上,AIE公司的发展历程可能更加复杂和精彩,需要更深入的研究和了解才能揭示。

CMOSIS公司的发展小趣事

在CMOS图像传感器市场竞争日益激烈的背景下,CMOSIS公司凭借其深厚的技术积累,成功研发出一款新型CMOS图像传感器,具有更高的分辨率和更低的噪声水平。这一技术突破使得CMOSIS的产品在市场上脱颖而出,赢得了众多客户的青睐。公司通过不断优化生产工艺和降低成本,逐渐扩大了市场份额,成为行业内的佼佼者。

Etco Inc公司的发展小趣事

面对数字化转型的浪潮,Etco Inc公司主动拥抱变革,积极推进数字化转型。公司利用大数据、云计算等先进技术优化生产流程和管理模式,提高了生产效率和管理水平。同时,Etco还加强了与客户的数字化连接和交流,提供了更加便捷和高效的服务体验。这些举措使Etco在数字化时代中保持了领先地位并实现了持续增长。

问答坊 | AI 解惑

串口通讯时断时续

主板rs232连接程序,过几个小时程序就会挂起。和硬件有关吗?(对通讯不太懂,麻烦说详细点可能原因)谢谢!…

查看全部问答>

PB编译时发生错误

想用VT6656 USB网卡,但安装驱动后编译出错,错误如图: 网上搜索了一下,毫无头绪,请问各位有没有碰到过类似的问题啊? 我用的是ATMEL 9261的bsp。…

查看全部问答>

请问Windows Embedded CE 6.0 为什么只有评估版?

我在网上到处找Windows Embedded CE 6.0的正式版,但是没有。全都是评估版。请问各位哪里有正式版下载?谢谢。…

查看全部问答>

WinCE程序移植问题

我在原来的VC程序中用到了ltoa函数,把long型数据存在字符数组中,但是在WinCE中不支持,有什么其它的办法实现这个功能吗?请教各位了…

查看全部问答>

请教各位前辈,32位变量被中断骚扰??

uint16 moniliangruanjianjizhun(uint16 a,uint16 b) //模拟量软件基准计算 { unsigned long int c,d; if(a>=b) a=0xffff; else {   //_asm("sim"); //禁止中断后计算正常   c=a; d=c<<16; d-=c; //==d ...…

查看全部问答>

一个在linux2.6.26下关于加入devfs的奇怪问题。

本人在linux2.6.26下想加入devfs。在fs/Kconfig里更改了编译选项,即定义了CONFIG_DEVFS_FS,但是在编译内核的时候,出现错误: driver/built-in.o:In function \'at91_spidev_init\'; hid-debug.c:undefined reference&nb ...…

查看全部问答>

pwm的幅值有要求吗?

我想用pt4207来做led的pwm调光电路,pt4207的1脚的pwm信号幅值有什么要求,0~5v可以不,还有,1脚要怎样连?…

查看全部问答>

STM32中SPI数据传输问题

我在STM32外面接了一个ADC-TLC2543,用STM32的SPI传输ADC转换之后的结果。现在我用示波器观察STM32中MOSI(PA7)的输出,示波器中没有波形(片选信号和时钟信号正常),把MOSI接到ADC中,ADC的输出用示波器看有波形,但输入STM32中读出的数据很小, ...…

查看全部问答>

关于数模模数转换的问题?可能是我对单片机理解还不够深,请问谁能解答一下?

比如用单片机时我直接置高电平是外接发光二极管点亮,与我用数模转换后输出一个电压点亮发光二极管   请问这两个过程有区别么,为什么要加数模转换?…

查看全部问答>

多功能调试测试助手-精密电压源AD5791

多功能调试测试助手-精密电压源AD5791 环境说明:CubeSuites+ 文件: AD5791.c   AD5791.h 函数: AD57XX_Init(AD5791); void AD57XX_SetRegisterValue(unsigned char registerAddress, unsigned long registerValue) unsigned ...…

查看全部问答>