【发布时间】:2015-01-24 15:48:15
【问题描述】:
我使用 GNU gcc (4.8.1429) 为 ARM(ATsam4LC4B:cortexM4 内核,256K 闪存)构建了一个简单的应用程序:
- 在 0x3F000(链接器选项 -Ttext=0x3F000)加载并初始化,
- 在 0 处复制自身(镜像)
- 使用程序集跳转到镜像Reset_Handler()(接近0)
- 镜像应用程序开始按预期运行
问题在到达镜像 main() 调用的闪存位置(闪存位置 0x532)时引发:
instruction ldr [pc, #32] 在那里加载 r3 0x3F565(因此调用 original main()),而不是预期的 0x565 (以便按预期调用 mirror main())。
即使包含 0x3F... 的所有寄存器在 ldr 指令之前被清零,也会发生这种情况。
调试器按预期报告 PC 寄存器为 0x534,并符合执行步进内的闪存区域。
谁能给我解释一下这是怎么回事?
提前谢谢你。
程序使用 [-mthumb -nostdlib -nostartfiles -ffreestanding -msingle-pic-base -mno-pic-data-is-text-relative -mlong-calls -mpoke-function-name] 标志编译并与[-Wl,--gc-sections -mcpu=cortex-m4 -Ttext=0x3f000 -nostdlib -nostartfiles -ffreestanding -Wl,-dead-strip -Wl,-static -Wl,--entry=Reset_Handler -Wl,- -cref -mthumb] 标志。链接描述文件定义了 rom start=0。
生成的 .lss 文件中的感兴趣区域包含(省略的行标记为...):
...
void Reset_Handler(void)
{
...
/* Initialize the relocate segment */
...
/* Clear the zero segment */
...
/* Set the vector table base address */
/* Initialize the C library */
// __libc_init_array();
/* Branch to main function */
main();
3f532: 4b08 ldr r3, [pc, #32] ; (3f554 <Reset_Handler+0x5c>)
3f534: 4798 blx r3
3f536: e7fe b.n 3f536 <Reset_Handler+0x3e>
3f538: 20000000 .word 0x20000000
3f53c: 0003f59c .word 0x0003f59c
3f540: 20000004 .word 0x20000004
3f544: 20000004 .word 0x20000004
3f548: 20000008 .word 0x20000008
3f54c: e000ed00 .word 0xe000ed00
3f550: 0003f000 .word 0x0003f000
3f554: 0003f565 .word 0x0003f565
3f558: 6e69616d .word 0x6e69616d
3f55c: 00 .byte 0x00
3f55d: 00 .byte 0x00
3f55e: bf00 nop
3f560: ff000008 .word 0xff000008
0003f564 <main>:
int main (void)
{
3f564: b510 push {r4, lr}
...
asm("bx %0"::"r"(*(unsigned*)0x3F004 - 0x3F000));
3f580: 4b05 ldr r3, [pc, #20] ; (3f598 <main+0x34>)
3f582: 681b ldr r3, [r3, #0]
3f584: f5a3 337c sub.w r3, r3, #258048 ; 0x3f000
3f588: 4718 bx r3
}
return 0;
}
3f58a: 2000 movs r0, #0
3f58c: bd10 pop {r4, pc}
3f58e: bf00 nop
3f590: e0001000 .word 0xe0001000
3f594: 0003f329 .word 0x0003f329
3f598: 0003f004 .word 0x0003f004
...
【问题讨论】:
-
那么,什么值实际存储在地址0x3f554/0x554?这就是您要加载到 r3 中的内容,但您还没有显示它。如果它是在链接时计算的符号地址,那么显然您将不得不将其作为重定位的一部分进行修复。
-
0x0003f565 存储在地址 0x3f554/0x554。谢谢。
-
可能有类似的问题。 stackoverflow.com/questions/2102921/…