linkerarmbootcortex-m

Unable to access ARM Cortex M3 SRAM beyond 4k


I am a newbie trying to experiment with ARM M3 boot up sequence using gdb and arm-none-eabi compiler on qemu.

I am able to run the code with the below linker and source file

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 */
}

My source code is

#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);
}

However, if the linker is adapted as below, it does not work as I get "Cannot access 0x20002000" which is a valid memory as per M3 spec.

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

I access qemu and attach it to gdb using

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"

Any reason why the memory is not accessible after 0x20001000 or where am I screwing up?


Solution

  • You have set -M stm32vldiscovery. This board is fitted with an STM32F100xB, which has 8K of RAM starting at 0x20000000.

    The emulator is correctly reporting that 0x20002000 is not a valid address on this device. In fact it is actually the first byte after the end of RAM.

    To use all the RAM you need to specify ORIGIN = 0x20000000, LENGTH = 8K.

    To use only the top half, starting at 4K, use ORIGIN = 0x20001000, LENGTH = 4K.