无法访问超过4k的ARM Cortex M3 SRAM

问题描述 投票:0回答:1

我是一名新手,试图在 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 之后内存无法访问或者我哪里搞砸了?

linker arm boot cortex-m
1个回答
0
投票

您已设置

-M stm32vldiscovery
。 该板配备了 STM32F100xB,其 RAM 为 8K,从 0x20000000 开始。

模拟器正确报告 0x20002000 不是该设备上的有效地址。 事实上,它实际上是 RAM 末尾之后的第一个字节。

要使用所有 RAM,您需要指定

ORIGIN = 0x20000000, LENGTH = 8K

要仅使用上半部分,从 4K 开始,请使用

ORIGIN = 0x20001000, LENGTH = 4K

© www.soinside.com 2019 - 2024. All rights reserved.