arm - 无法在 qemu 中运行无操作功能
问题描述
我正在使用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 .
和交流功能,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设置为
0x2
0,运行BL 8 <main>
- 这分支到内存位置
0x8
,这是main
函数的开始,它还将返回地址保存在LR
- 这个函数应该执行一个无操作,
FP
向/从堆栈推入和弹出 - 该函数应该返回
LR
(之前保存的)的地址 - 下一条指令应该永远循环(
24: ebfffffe bl 24 <Reset_Handler+0x4>
)
但是,我运行它,我收到以下错误:
(qemu) Bad ram pointer 0x4
我对这个错误的含义有点迷茫。我的设置中缺少什么吗?
解决方案
ORIGIN = 0x00000000
内存被硬件别名为0但实际地址不为零,
您的链接描述文件必须使用正确的 FLASH 地址而不是引导时间别名。
0x8000000
我建议使用 stm 提供的链接器脚本,因为您并不完全了解芯片的文档。
推荐阅读
- php - WooCommerce 基于工作日和时间的有条件交货通知
- macos - 如何将 Sikuli4Net 或 SikuliSharp 与 Visual Studio for Mac 结合使用,在 MacOS 上测试 .NET Core 跨平台应用程序?
- r - 更新 bs4dash 版本 2.00 Shiny 中的控制栏
- java - 使用流 api 更新现有函数
- android - App Inventor 2 打开具有特定 URL 的浏览器(Firefox 和 Edge)
- ocaml - 如何加快读取文件并返回其内容的函数?
- vue.js - 登录数据用户丢失后
- java - 在 ElasticSearch 中搜索时删除连字符
- c# - Azure CDN 不接受 C# 中 Imageresizer 插件的查询字符串参数
- python - Python:列表中对值的总和