我是一名新手,试图在 qemu 上使用 gdb 和 arm-none-eabi 编译器来试验 ARM M3 启动序列。
我可以使用以下链接器和源文件运行代码
MEMORY
{
MEM : ORIGIN = 0x08000000, LENGTH = 0x400000
RAM : ORIGIN = 0x20000900, LENGTH = 0x3000
}
__stack_end = 0x20000800;
SECTIONS
{
.text : {
*(.vectors*)
*(.text*)
__text_end = .;
} > MEM
.data : {
__data_start__ = .;
*(.data)
__data_end__ = .;
} > RAM AT> MEM
.bss : {
__bss_start__ = .; /* Start of .bss section */
*(.bss)
__bss_end__ = .; /* End of .bss section */
} > RAM
/* Define the end of RAM for the _sbrk function */
. = ALIGN(4);
end = .; /* End symbol */
}
我的源代码是
#include<stdio.h>
extern char __stack_end;
extern char __data_start__;
extern char __data_end__;
extern char __text_end;
int global_var = 100;
void main(void);
__attribute__((section(".vectors"))) void (*vec[])(void) = {
(void (*) (void))&(__stack_end),
main
};
int foo(void) {
return 5;
}
void main(void) {
char *src = &__text_end;
char *dst = &__data_start__;
char *dst_end = &__data_end__;
while(dst != dst_end) {
*dst = *src;
dst++;
src++;
}
int a=10;
int b=20;
int c=a+foo()+global_var;
while(1);
}
但是,如果链接器按如下方式进行调整,则它不起作用,因为我收到“无法访问 0x20002000”,这是根据 M3 规范的有效内存。
MEMORY
{
MEM : ORIGIN = 0x08000000, LENGTH = 0x400000
RAM : ORIGIN = 0x20002000, LENGTH = 0x3000
}
__stack_end = 0x20001000;
loc src = 0x8000074 "d": 100 'd', dst = 0x20002000 <global_var> <error: Cannot access memory at address 0x20002000>: Cannot ac…, dst_end = 0x0: 0 '\000', a = 0, b = 0, c = 0
我访问 qemu 并将其附加到 gdb 使用
qemu-system-arm -S -M stm32vldiscovery -cpu cortex-m3 -nographic -kernel main.bin -gdb tcp::1234
gdb-multiarch -q main.elf -ex "target remote localhost:1234"
有什么原因导致 0x20001000 之后内存无法访问或者我哪里搞砸了?
您已设置
-M stm32vldiscovery
。 该板配备了 STM32F100xB,其 RAM 为 8K,从 0x20000000 开始。
模拟器正确报告 0x20002000 不是该设备上的有效地址。 事实上,它实际上是 RAM 末尾之后的第一个字节。
要使用所有 RAM,您需要指定
ORIGIN = 0x20000000, LENGTH = 8K
。
要仅使用上半部分,从 4K 开始,请使用
ORIGIN = 0x20001000, LENGTH = 4K
。