【发布时间】:2013-03-04 05:22:03
【问题描述】:
我正在使用 JTAG 连接器和 gdb 在裸机 ARM(符合 v5TE)上运行程序。该程序以管理员模式从某个 SDRAM 运行,并且仅使用 arm 指令。
在某些时候会发生异常。使用 ctrl+C 停止 gdb 我可以看到 CPSR 指示未定义的异常模式,但是程序计数器指示软件中断异常 (0xffff0008)。根据ARM ARM,当发生未定义指令异常时,PC_und 应该是0xffff0004 或0x00000004。我的程序发生了什么,发生了 SWI 还是未定义的指令异常?
编辑以使我的问题更清楚:
我的程序目的是测试定制板的硬件。当出现硬件问题时,RAM 中的程序可能会损坏(如下所示),这是产生异常的原因。当硬件正常时,测试软件运行没有问题。我的 RAM 地址范围从 0 到 0x40000000,程序加载在 0x1000 和 0x2000 之间。监督模式堆栈指针设置为 0xff0。中断向量只包含断点。
(gdb) c
Continuing.
^C^C
Program received signal SIGTRAP, Trace/breakpoint trap.
0xffff0008 in ?? ()
从未定义异常模式注册:
(gdb) i r
r0 0x52878 338040
r1 0x2020000 33685504
r2 0x2020000 33685504
r3 0x2020000 33685504
r4 0x2020000 33685504
r5 0x2020000 33685504
r6 0x2020000 33685504
r7 0x2020000 33685504
r8 0x2020000 33685504
r9 0x2020000 33685504
r10 0x2020000 33685504
r11 0x2020000 33685504
r12 0x2020000 33685504
sp 0x2020000 0x2020000
lr 0xffff0008 4294901768
pc 0xffff0008 0xffff0008
fps 0x0 0
cpsr 0x800000db 2147483867
从管理员模式注册:
(gdb) set $cpsr=0xd3
(gdb) i r
r0 0x52878 338040
r1 0x2020000 33685504
r2 0x2020000 33685504
r3 0x2020000 33685504
r4 0x2020000 33685504
r5 0x2020000 33685504
r6 0x2020000 33685504
r7 0x2020000 33685504
r8 0x2020000 33685504
r9 0x2020000 33685504
r10 0x2020000 33685504
r11 0x2020000 33685504
r12 0x2020000 33685504
sp 0xff3ffffe 0xff3ffffe
lr 0x1020 4128
pc 0xffff0008 0xffff0008
fps 0x0 0
cpsr 0xd3 211
这是 RAM 中的(损坏的)程序,位于主管链接寄存器指向的地址周围:
(gdb) x/5i 0x1020-8
0x1018 <_start+24>: bic r0, r0, #135168 ; 0x21000
0x101c <_start+28>: strbcs r0, [r0], #1025
0x1020 <_start+32>: mcr 15, 0, r0, cr1, cr0, {0}
0x1024 <_start+36>: ldr r1, [pc, #120] ; 0x10a4 <skip_intreg_reset+100>
0x1028 <_start+40>: ldr r2, [r1, #8]
(gdb) x/4w 0x1018
0x1018 <_start+24>: 0xe3c00a01
0x101C <_start+28>: 0xfec00401
0x1020 <_start+32>: 0xee010f10
0x1024 <_start+36>: 0xe59f1078
从程序目标文件中转储:
18: e3c00a01 bic r0, r0, #4096 ; 0x1000
1c: e3c00001 bic r0, r0, #1 ; 0x1
20: ee010f10 mcr 15, 0, r0, cr1, cr0, {0}
24: e59f1078 ldr r1, [pc, #120] ; a4 <skip_intreg_reset+0x64>
28: e5912000 ldr r2, [r1]
【问题讨论】:
-
swi 发生时是拇指模式还是手臂模式?
-
你能转储/发布发生异常的代码吗?
-
可能只是 GDB 故障。尝试在向量的分支目标上设置断点,而不是在向量本身上。
-
向量中的分支是什么意思?在中断向量中使用分支指令并在我分支的地方放置一个断点?
-
您已验证 mcr 是该内核上的协处理器的有效操作?也许用 nop 替换它。并且 ldr 在对齐的边界上? (如果是 0x2020000 就可以了)
标签: gdb arm jtag bare-metal