0

I am attempting to move sections of memory around using a linker script for an STM32F446ZE micro controller. My original setup consisted of this:

MEMORY
{
RAM (xrw)      : ORIGIN = 0x20000000, LENGTH = 128K
FLASH (rx)      : ORIGIN = 0x8000000, LENGTH = 512K - 128k
DATA (rwx)      : ORIGIN = 0x08060000, LENGTH = 5120
}

SECTIONS
{
  .user_data :
  {
    . = ALIGN(4);
    KEEP(*(.user_data))
    . = ALIGN(4);
  } >DATA
  .isr_vector :
  {
    . = ALIGN(4);
    KEEP(*(.isr_vector)) /* Startup code */
    . = ALIGN(4);
  } >FLASH

  .text :
  {
    . = ALIGN(4);
    *(.text)           /* .text sections (code) */
    *(.text*)          /* .text* sections (code) */
    *(.glue_7)         /* glue arm to thumb code */
    *(.glue_7t)        /* glue thumb to arm code */
    *(.eh_frame)
    KEEP (*(.init))
    KEEP (*(.fini))
    . = ALIGN(4);
    _etext = .;        /* define a global symbols at end of code */
  } >FLASH

  .rodata :
  {
    . = ALIGN(4);
    *(.rodata)         /* .rodata sections (constants, strings, etc.) */
    *(.rodata*)        /* .rodata* sections (constants, strings, etc.) */
    . = ALIGN(4);
  } >FLASH

  .data : 
  {
    . = ALIGN(4);
    _sdata = .;        /* create a global symbol at data start */
    *(.data)           /* .data sections */
    *(.data*)          /* .data* sections */
    . = ALIGN(4);
    _edata = .;        /* define a global symbol at data end */
  } >RAM AT> FLASH

  . = ALIGN(4);
  .bss :
  {
    /* This is used by the startup in order to initialize the .bss secion */
    _sbss = .;         /* define a global symbol at bss start */
    __bss_start__ = _sbss;
    *(.bss)
    *(.bss*)
    *(COMMON)
    . = ALIGN(4);
    _ebss = .;         /* define a global symbol at bss end */
    __bss_end__ = _ebss;
  } >RAM

  /* User_heap_stack section, used to check that there is enough RAM left */
  ._user_heap_stack :
  {
    . = ALIGN(4);
    PROVIDE ( end = . );
    PROVIDE ( _end = . );
    . = . + _Min_Heap_Size;
    . = . + _Min_Stack_Size;
    . = ALIGN(4);
  } >RAM

What I want to do is move the DATA to start at 0x08000000 (where flash is currently starting) and start FLASH at 0x08040000 (after DATA). I can change that in the memory section easy enough, but my program wont start. I believe some of the code in the SECTIONS block may have to be changed, but I'm not sure how. Question is: how can I move flash (where the program code is) to a later memory address.

Austin
  • 318
  • 1
  • 3
  • 16
  • Does this answer your question? [How can I change the start address on flash?](https://stackoverflow.com/questions/56896375/how-can-i-change-the-start-address-on-flash) – Anton Stafeyev Feb 22 '20 at 01:54

3 Answers3

1

It is not possible as your STM32 uC starts from the address 0x8000000 when booting from flash.

Question is: how can I move flash (where the program code is) to a later memory address.

The answer: it is not possible. The vector table has to start at 0x8000000 when booting from the FLASH memory

0___________
  • 60,014
  • 4
  • 34
  • 74
  • well u kinda can with BOOT option bytes, tot ell you microcontroller which adress is used for boot. so u can boot it at the actuall 0x0 which is DTCM RAM, if another device have placed vector table there it will boot fetch stack pointer and reset handler just like it did at 0x08000000 – Anton Stafeyev Feb 22 '20 at 00:23
  • you clearly did not read the datasheet :) but there is a stackoverflow question here https://stackoverflow.com/questions/56896375/how-can-i-change-the-start-address-on-flash – Anton Stafeyev Feb 22 '20 at 01:52
  • Oh i am sorry, stm32f4 doesnt have this feature. my bad, just checked the datasheet – Anton Stafeyev Feb 22 '20 at 02:05
  • @AntonStafeyev is is time to delete those wrong, unrelevant comments – 0___________ Feb 22 '20 at 09:14
1

As P__J__ mentioned you can not move whole data region to the address 0x0800 0000 because MCU expects the interrupt vector to start there. When the MCU is booted from the flash memory the address 0x0800 0000 is mapped to the address 0x0000 0000. What you can do instead is to create another region for the length of vector table and move the other parts of your sections as you please.

MEMORY
{
RAM (xrw)       : ORIGIN = 0x20000000, LENGTH = 128K
VECTORS (rx)    : ORIGIN = 0x08000000, LENGTH = 0xB8
FLASH (rx)      : ORIGIN = 0x080000B8, LENGTH = 512K - 128k - 0xB8
DATA (rwx)      : ORIGIN = 0x08060000, LENGTH = 5120
}

  .isr_vector :
  {
    KEEP(*(.isr_vector))
  } > VECTORS

Teivaz
  • 5,462
  • 4
  • 37
  • 75
0

How can I change the start address on flash? This would apply if you had stmf7, sadly you do not have a feature of booting from any address you like. There is a fixed number of options you have.

Take a look at data sheet, 7.1.2 Reset: The RESET service routine vector is fixed at address 0x0000_0004 in the memory map. which means that the second 4 bytes in your flash are the address of reset handler.

However, you can change a place where you boot from by using BOOT pin, again consult a datasheet at 2.4 STM32F4xx microcontrollers implement a special mechanism to be able to boot from other memories (like the internal SRAM).

So your only option is to change type of memory is used for booting. But in your case it wont help at all.

marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
Anton Stafeyev
  • 761
  • 1
  • 7
  • 20