【发布时间】:2021-11-17 06:02:40
【问题描述】:
我正在使用xpack qemu arm,它是qemu 的一个分支,支持STM32 板。
我正在尝试运行一个简单的程序来让自己开始。
我有我的链接器脚本
ENTRY(Reset_Handler)
MEMORY
{
FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 0x08000000
RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 0x20000000
}
SECTIONS
{
. = ORIGIN(FLASH);
.text :
{
LONG(ORIGIN(RAM) + LENGTH(RAM)) /* set the SP initial value */
LONG(Reset_Handler) /* set the PC initial value */
*(.text)
}
}
我的汇编文件
.section .text
.global Reset_Handler
Reset_Handler:
BL main
BL .
还有一个 c 函数,main
void main () {
return;
}
当我汇编、编译和链接时,生成的内存内容是
00000000 <main-0x8>:
0: 40000000 .word 0x40000000
4: 00000020 .word 0x00000020
00000008 <main>:
void main () {
8: e52db004 push {fp} ; (str fp, [sp, #-4]!)
c: e28db000 add fp, sp, #0
return;
10: e1a00000 nop ; (mov r0, r0)
14: e24bd000 sub sp, fp, #0
18: e49db004 pop {fp} ; (ldr fp, [sp], #4)
1c: e12fff1e bx lr
00000020 <Reset_Handler>:
.section .text
.global Reset_Handler
Reset_Handler:
BL main
20: ebfffff8 bl 8 <main>
BL .
24: ebfffffe bl 24 <Reset_Handler+0x4>
我正在使用STM32F407VG MCU,文档指出
在这个启动延迟结束后,CPU 从地址中获取栈顶值 0x0000 0000,然后从 0x0000 0004 开始从引导存储器开始执行代码。
因此,我将堆栈指针0x40000000的初始值存储在内存位置0x00000000中,并将程序计数器的初始值存储在内存位置0x00000004中
我是这样启动qemu的
qemu-system-gnuarmeclipse -mcu STM32F407VG -machine STM32F4-Discovery -image myfile.elf -nographic --verbose --verbose -no-reboot -S
我可以看到 SP 和 PC 寄存器(分别为 R13 和 R15)设置为预期值:
R00=00000000 R01=00000000 R02=00000000 R03=00000000
R04=00000000 R05=00000000 R06=00000000 R07=00000000
R08=00000000 R09=00000000 R10=00000000 R11=00000000
R12=00000000 R13=40000000 R14=00000000 R15=00000020
PSR=40000153 -Z-- A svc32
FPSCR: 00000000
所以,在内存映射输出之后,程序应该是这样的:
- PC 设置为
0x20,运行BL 8 <main> - 这分支到内存位置
0x8,这是main函数的开始,它还将返回地址保存在LR中 - 此函数应执行无操作,将
FP推入/弹出堆栈 - 函数应该返回
LR的地址(之前保存的) - 下一条指令应该永远循环 (
24: ebfffffe bl 24 <Reset_Handler+0x4>)
但是,我运行它,我得到以下错误:
(qemu) Bad ram pointer 0x4
我对这个错误的含义有点迷茫。我的设置中是否缺少某些内容?
【问题讨论】:
-
你不能单步查看具体哪里出了问题吗?