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?
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
.