如何理解为啥会发生 ARM 异常?
Posted
技术标签:
【中文标题】如何理解为啥会发生 ARM 异常?【英文标题】:How to understand why an ARM exception happens?如何理解为什么会发生 ARM 异常? 【发布时间】:2018-10-14 16:05:37 【问题描述】:我正在尝试了解我遇到的 ARM 异常的原因。 它在系统启动期间随机发生,并且可能以几种不同的方式出现。
一个最简单的方法如下:
0x8004e810 in ti_sysbios_family_arm_a8_intcps_Hwi_vectors ()
#0 0x8004e810 in ti_sysbios_family_arm_a8_intcps_Hwi_vectors ()
#1 0x80002f04 in ti_sysbios_family_arm_exc_Exception_excHandlerDataAsm(int0_t) ()
at /home/rnd_share/sysbios/bios_6_51_00_15/packages/ti/sysbios/family/arm/exc/Exception_asm_gnu.asm:103
Backtrace stopped: previous frame identical to this frame (corrupt stack?)
r0 0x20000197 536871319
r1 0x20000197 536871319
r2 0x20000197 536871319
r3 0x20000197 536871319
r4 0x20000197 536871319
r5 0x6 6
r6 0x80000024 2147483684
r7 0x80007a0c 2147514892
r8 0x8004f0a8 2147807400
r9 0x80041340 2147750720
r10 0x80040a3c 2147748412
r11 0xffffffff 4294967295
r12 0x20000197 536871319
sp 0x7fffff88 0x7fffff88
lr 0x80002f04 2147495684
pc 0x8004e810 0x8004e810 <ti_sysbios_family_arm_a8_intcps_Hwi_vectors+16>
cpsr 0x20000197 536871319
PC = 8004E810, CPSR = 20000197 (ABORT mode, ARM IRQ dis.)
R0 = 20000197, R1 = 20000197, R2 = 20000197, R3 = 20000197
R4 = 20000197, R5 = 00000006, R6 = 80000024, R7 = 80007A0C
USR: R8 =8004F0A8, R9 =80041340, R10=80040A3C, R11 =FFFFFFFF, R12 =20000197
R13=80212590, R14=80040A3C
FIQ: R8 =AEE1D6FA, R9 =C07BA930, R10=1B0B137A, R11 =7EC3F1DF, R12 =2000019F
R13=80065CF8, R14=00000000, SPSR=00000000
SVC: R13=4030CB20, R14=00022071, SPSR=00000000
ABT: R13=7FFFFF88, R14=80002F04, SPSR=20000197
IRQ: R13=F4ADFD8A, R14=80041020, SPSR=8000011F
UND: R13=80085CF8, R14=ED0F7EF1, SPSR=00000000
(gdb) frame
#0 0x8004e810 in ti_sysbios_family_arm_a8_intcps_Hwi_vectors ()
(gdb) frame 1
#1 0x80002f04 in ti_sysbios_family_arm_exc_Exception_excHandlerDataAsm(int0_t) ()
at /home/rnd_share/sysbios/bios_6_51_00_15/packages/ti/sysbios/family/arm/exc/Exception_asm_gnu.asm:103
103 mrc p15, #0, r12, c5, c0, #0 @ read DFSR into r12
(gdb) list
98 .func ti_sysbios_family_arm_exc_Exception_excHandlerDataAsm__I
99
100 ti_sysbios_family_arm_exc_Exception_excHandlerDataAsm__I:
101 stmfd sp!, r0-r12 @ save r4-r12 while we're at it
102
103 mrc p15, #0, r12, c5, c0, #0 @ read DFSR into r12
104 stmfd sp!, r12 @ save DFSR
105 mrc p15, #0, r12, c5, c0, #1 @ read IFSR into r12
106 stmfd sp!, r12 @ save DFSR
107 mrc p15, #0, r12, c6, c0, #0 @ read DFAR into r12
(gdb) monitor cp15 6 0 0 0
Reading CP15 register (6,0,0,0 = 0x7FFFFF54)
我的理解是,存在一些持续的异常,可以在第 1 帧中看到。 它尝试将寄存器保存到堆栈中:
101 stmfd sp!, r0-r12 @ 保存 r4-r12 而我们正在处理它
但是,堆栈指针在以下位置不正确:
ABT:R13=7FFFFF88
两个都不懂:
-
在 ABT 和 IRQ 上下文中,SP 如此值的原因可能是什么?
第 0 帧实际上是什么?换句话说,Cortex 在已经处于异常处理程序中时如何对数据中止做出反应?
此设备通常启动正常,这种情况每 10 次启动会发生 3 次。从调试器启动时不会发生这种情况,只有发布并且仅从引导加载程序启动时才会发生。
【问题讨论】:
你的记忆混乱了。我怀疑导致不同内存访问模式的野指针。 R14_SVC (0x22071) 是有效代码吗?您应该尝试initcall_debug
和其他 kconfig 值来检查内存问题。
【参考方案1】:
两周后...
启动过程如下:
第二阶段引导加载程序将应用程序加载到内存
第二阶段引导加载程序跳转到应用程序启动。
进入应用主函数。
事实证明,有时应用程序的静态初始化值在启动 1 步后具有正确的值,但在 3 步后它们被损坏。我的意思是应用程序映像已损坏。
在第 1 步和第 2 步之间没有正确刷新缓存。
在第二阶段引导加载程序中禁用缓存完全解决了问题。 现在需要正确修复它。
【讨论】:
您的引导加载程序是否设置了 MMU 转换表?您可以在正确的时间点刷新内存,而不是禁用缓存。 @harper,是的,但是没有地址转换,但转换表中有条目(我的意思是地址转换总是 x 到 x)。禁用缓存只是某种概念证明。现在我在映像复制过程结束时刷新引导加载程序中的缓存。看来问题已经完全解决了。 当您在 CP15 中设置 MMU 表地址时,该表从 SDRAM 中读取。如果缓存在那个时间点没有被刷新,你可能会得到无效的表条目。以上是关于如何理解为啥会发生 ARM 异常?的主要内容,如果未能解决你的问题,请参考以下文章