Austin
Austin

Reputation: 396

GNU Linker Script - move flash memory to new region

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.

Upvotes: 0

Views: 1724

Answers (3)

Anton Stafeyev
Anton Stafeyev

Reputation: 831

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.

Upvotes: 0

Teivaz
Teivaz

Reputation: 5675

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

Upvotes: 1

0___________
0___________

Reputation: 67546

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

Upvotes: 1

Related Questions