cancel
Showing results for 
Search instead for 
Did you mean: 

Custom linker file for bootloader stm32f429

SGasp.1
Senior

Hi amazing community..

I have developed a custom linker file for stm32f429. 

Here there is my costum linker file  

 

/*
******************************************************************************
**
** @file        : LinkerScript.ld
**
** @author      : Auto-generated by STM32CubeIDE
**
** @brief       : Linker script for STM32F429ZITx Device from STM32F4 series
**                      2048Kbytes FLASH
**                      64Kbytes CCMRAM
**                      192Kbytes RAM
**
**                Set heap size, stack size and stack location according
**                to application requirements.
**
**                Set memory bank area and size if external memory is used
**
**  Target      : STMicroelectronics STM32
**
**  Distribution: The file is distributed as is, without any warranty
**                of any kind.
**
******************************************************************************
** @attention
**
** Copyright (c) 2023 STMicroelectronics.
** All rights reserved.
**
** This software is licensed under terms that can be found in the LICENSE file
** in the root directory of this software component.
** If no LICENSE file comes with this software, it is provided AS-IS.
**
******************************************************************************
*/

/* Entry Point */
ENTRY(Reset_Handler)

/* Highest address of the user mode stack */
_estack = ORIGIN(RAM) + LENGTH(RAM); /* end of "RAM" Ram type memory */

_Min_Heap_Size = 0x400; /* required amount of heap */
_Min_Stack_Size = 0x800; /* required amount of stack */

_BOOTLDR_OFFSET = 0x00000000;
_APP_START_OFFSET = 0x00010000;
_APP_HEADER_OFFSET = 0x00010000; 

/* Memories definition */
MEMORY
{
  CCMRAM    (xrw)    : ORIGIN = 0x10000000,   LENGTH = 64K
  RAM    (xrw)    : ORIGIN = 0x20000000,   LENGTH = 192K-4
  FLASH    (rx)    : ORIGIN = 0x8000000,   LENGTH = 2048K
}

/* Sections */
SECTIONS
{
  /* The bootloader code into "FLASH" Rom type memory */
  .bootloader_section :
  {
    . = ALIGN(4);
    _bl_fw_start = .;
    KEEP(*(.bootloader_section)) /* Bootloader */
    . = ALIGN(4);
  } > FLASH

  /* The startup code into "FLASH" Rom type memory */
  .isr_vector :
  {
    . = _bl_fw_start + _APP_START_OFFSET;
    _app_fw_start = .;
    KEEP(*(.isr_vector)) /* Startup code */
    . = ALIGN(4);
  } > FLASH

  .app_header :
  {
    . = _bl_fw_start + _APP_START_OFFSET + _APP_HEADER_OFFSET;
    KEEP(*(.app_header)) /* Bootloader Header */
    . = ALIGN(4);
  } > FLASH

  /* The program code and other data into "FLASH" Rom type memory */
  .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

  /* Constant data into "FLASH" Rom type memory */
  .rodata :
  {
    . = ALIGN(4);
    *(.rodata)         /* .rodata sections (constants, strings, etc.) */
    *(.rodata*)        /* .rodata* sections (constants, strings, etc.) */
    . = ALIGN(4);
  } >FLASH

  .ARM.extab   : {
    . = ALIGN(4);
    *(.ARM.extab* .gnu.linkonce.armextab.*)
    . = ALIGN(4);
  } >FLASH

  .ARM : {
    . = ALIGN(4);
    __exidx_start = .;
    *(.ARM.exidx*)
    __exidx_end = .;
    . = ALIGN(4);
  } >FLASH

  .preinit_array     :
  {
    . = ALIGN(4);
    PROVIDE_HIDDEN (__preinit_array_start = .);
    KEEP (*(.preinit_array*))
    PROVIDE_HIDDEN (__preinit_array_end = .);
    . = ALIGN(4);
  } >FLASH

  .init_array :
  {
    . = ALIGN(4);
    PROVIDE_HIDDEN (__init_array_start = .);
    KEEP (*(SORT(.init_array.*)))
    KEEP (*(.init_array*))
    PROVIDE_HIDDEN (__init_array_end = .);
    . = ALIGN(4);
  } >FLASH

  .fini_array :
  {
    . = ALIGN(4);
    PROVIDE_HIDDEN (__fini_array_start = .);
    KEEP (*(SORT(.fini_array.*)))
    KEEP (*(.fini_array*))
    PROVIDE_HIDDEN (__fini_array_end = .);
    . = ALIGN(4);
  } >FLASH

  /* Used by the startup to initialize data */
  _sidata = LOADADDR(.data);

  /* Initialized data sections into "RAM" Ram type memory */
  .data :
  {
    . = ALIGN(4);
    _sdata = .;        /* create a global symbol at data start */
    *(.data)           /* .data sections */
    *(.data*)          /* .data* sections */
    *(.RamFunc)        /* .RamFunc sections */
    *(.RamFunc*)       /* .RamFunc* sections */

    . = ALIGN(4);
    _edata = .;        /* define a global symbol at data end */

  } >RAM AT> FLASH

  _siccmram = LOADADDR(.ccmram);

  /* CCM-RAM section
  *
  * IMPORTANT NOTE!
  * If initialized variables will be placed in this section,
  * the startup code needs to be modified to copy the init-values.
  */
  .ccmram :
  {
    . = ALIGN(4);
    _sccmram = .;       /* create a global symbol at ccmram start */
    *(.ccmram)
    *(.ccmram*)

    . = ALIGN(4);
    _eccmram = .;       /* create a global symbol at ccmram end */
  } >CCMRAM AT> FLASH

  /* Uninitialized data section into "RAM" Ram type memory */
  . = ALIGN(4);
  .bss :
  {
    /* This is used by the startup in order to initialize the .bss section */
    _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" Ram  type memory left */
  ._user_heap_stack :
  {
    . = ALIGN(8);
    PROVIDE ( end = . );
    PROVIDE ( _end = . );
    . = . + _Min_Heap_Size;
    . = . + _Min_Stack_Size;
    . = ALIGN(8);
  } >RAM
  
.app_trailer :
{
    . = ALIGN(16);
    _app_trailer = .;
    KEEP(*(.app_trailer)) /* Application Trailer */
    . = ALIGN(4);
    _app_fw_end = .;
} >FLASH

_app_fw_size = _app_fw_end - _app_fw_start;


  /* Remove information from the compiler libraries */
  /DISCARD/ :
  {
    libc.a ( * )
    libm.a ( * )
    libgcc.a ( * )
  }

  .ARM.attributes 0 : { *(.ARM.attributes) }
}

 

When i debug the application the code is running but the ISR are not working. 

Here there is the memory map 

SGasp1_0-1715950755530.png

 

The idea is to have 64kb for the botloader and the rest for the application. 

The starting point of the application it  should be at address 0x08010000

 

as usual in the main function i do this .. 

 

SGasp1_1-1715950903795.png

Can you please tell me if you see something strange on the setting of the ISR table ? 

 

Thanks a lot

 

18 REPLIES 18
Radosław
Senior II

Create new memory region for bootloader

whe talking about booloder sctript? what regions? for what?

 

I,m assume that you wanna in booloader read some info from  aplication ?

Radosław
Senior II

Correct me,   bootloader  need some information about  from aplication?

SGasp.1
Senior

@Radosław  yes it needs info from application

Radosław
Senior II

I do this,  let me explain, i hope you will understand this,

 

In aplication, a have always created  section "after_interrupts"  if bootloader need  get info from aplication start this info with "magic word"

 

this will be more universal.

 

in other hand you  can increase Isr section to specyfic size  or align begining or info section  this size.

 

strongly recomended is to have isr section before any others

 

SGasp.1
Senior

Hi @Radosław 

Also in my case it is after interrupt.. 

But I don't understand why the interrupts are not working 

 

  .isr_vector :
  {
    . = _bl_fw_start + _APP_START_OFFSET;
    _app_fw_start = .;
    KEEP(*(.isr_vector)) /* Startup code */
    . = ALIGN(4);
  } > FLASH

  .app_header :
  {
    . = _bl_fw_start + _APP_START_OFFSET + _APP_HEADER_OFFSET;
    KEEP(*(.app_header)) /* Bootloader Header */
    . = ALIGN(4);
  } > FLASH

However i will try to not touch the isr_vector by modfing the starting address in flash i will remove the bootloader_section and maybe it should work ? 

Bootlader section is before ISR? do not mix linker sctripts, Now we talking about aplication linker nor bootloader,

 

Booloader need standard linker stript, as i;m notice earlier

 

Bootloader always need info about whare aplication is start it is enough, from this info you can to everything, that why booloader need standard linker script, (or only for claryfication aplication memory region).

You need to STOP with this approach of attempting to advance the current address pointer.

. = _bl_fw_start + _APP_START_OFFSET;

You're fighting the linker, use distinct MEMORY regions to partition/sub-divide memory visible to the linker. The memory visible to the LOADER and APP are typically different and distinct. One is not fishing around in the memory of the other, at least from the linkers perspective.

 

  .isr_vector :
  {
    _app_fw_start = .;
    KEEP(*(.isr_vector)) /* Startup code */
    . = ALIGN(4);
  } >VECTORS

  .app_header :
  {
    KEEP(*(.app_header)) /* Bootloader Header */
    . = ALIGN(4);
  } >HEADER

 

The WHY you're doing this also needs to be questioned.

You can use POINTERs in the application code to access these areas

The interrupts won't work if you're not constructing the table correctly, or not pointing SCB->VTOR at it properly. Needs to be set in SystemInit() typically.

The MCU starts with the presumption that the table is at ZERO / 0x08000000, the STM32 shadows the ROM/FLASH at zero based on the BOOTx pins.

Your APP code should point SCB->VTOR at 0x08010000 once it starts after the LOADER has transferred control.

A better place to bury pointers and image size are table entries immediately after the Vector table, or within unused vectors.

Configuration data or EEPROM emulation can use 16KB sectors, say 0x08008000 / 0x0800C000

 

uint32_r *p = (uint32_r *)0x0x8004000; // set a pointer to an address, can be used for structure pointers..

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..

Hi @Radosław and @Tesla DeLorean  I have changed the linker in the following way but still isr routine are not working 

 

/*
******************************************************************************
**
** @file        : LinkerScript.ld
**
** @author      : Auto-generated by STM32CubeIDE
**
** @brief       : Linker script for STM32F429ZITx Device from STM32F4 series
**                      2048Kbytes FLASH
**                      64Kbytes CCMRAM
**                      192Kbytes RAM
**
**                Set heap size, stack size and stack location according
**                to application requirements.
**
**                Set memory bank area and size if external memory is used
**
**  Target      : STMicroelectronics STM32
**
**  Distribution: The file is distributed as is, without any warranty
**                of any kind.
**
******************************************************************************
** @attention
**
** Copyright (c) 2023 STMicroelectronics.
** All rights reserved.
**
** This software is licensed under terms that can be found in the LICENSE file
** in the root directory of this software component.
** If no LICENSE file comes with this software, it is provided AS-IS.
**
******************************************************************************
*/

/* Entry Point */
ENTRY(Reset_Handler)

/* Highest address of the user mode stack */
_estack = ORIGIN(RAM) + LENGTH(RAM); /* end of "RAM" Ram type memory */

_Min_Heap_Size = 0x400; /* required amount of heap */
_Min_Stack_Size = 0x800; /* required amount of stack */

_BOOTLDR_OFFSET = 0x00000000;
_APP_START_OFFSET = 0x00010000;
_APP_HEADER_OFFSET = 0x00010000;
_APP_FW_START = 0x8010000;  

/* Memories definition */
MEMORY
{
  CCMRAM    (xrw)    : ORIGIN = 0x10000000,   LENGTH = 64K
  RAM    (xrw)    : ORIGIN = 0x20000000,   LENGTH = 192K-4
  FLASH    (rx)    : ORIGIN = 0x8010000,   LENGTH = 2048K-64K
}

/* Sections */
SECTIONS
{
  /* The startup code into "FLASH" Rom type memory */
  .isr_vector :
  {
    . = ALIGN(4);
    KEEP(*(.isr_vector)) /* Startup code */
    . = ALIGN(4);
  } >FLASH

  .app_header :
  {
    . =  _APP_HEADER_OFFSET;
    KEEP(*(.app_header)) /* Bootloader Header */
    . = ALIGN(4);
  } > FLASH

  /* The program code and other data into "FLASH" Rom type memory */
  .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

  /* Constant data into "FLASH" Rom type memory */
  .rodata :
  {
    . = ALIGN(4);
    *(.rodata)         /* .rodata sections (constants, strings, etc.) */
    *(.rodata*)        /* .rodata* sections (constants, strings, etc.) */
    . = ALIGN(4);
  } >FLASH

  .ARM.extab   : {
    . = ALIGN(4);
    *(.ARM.extab* .gnu.linkonce.armextab.*)
    . = ALIGN(4);
  } >FLASH

  .ARM : {
    . = ALIGN(4);
    __exidx_start = .;
    *(.ARM.exidx*)
    __exidx_end = .;
    . = ALIGN(4);
  } >FLASH

  .preinit_array     :
  {
    . = ALIGN(4);
    PROVIDE_HIDDEN (__preinit_array_start = .);
    KEEP (*(.preinit_array*))
    PROVIDE_HIDDEN (__preinit_array_end = .);
    . = ALIGN(4);
  } >FLASH

  .init_array :
  {
    . = ALIGN(4);
    PROVIDE_HIDDEN (__init_array_start = .);
    KEEP (*(SORT(.init_array.*)))
    KEEP (*(.init_array*))
    PROVIDE_HIDDEN (__init_array_end = .);
    . = ALIGN(4);
  } >FLASH

  .fini_array :
  {
    . = ALIGN(4);
    PROVIDE_HIDDEN (__fini_array_start = .);
    KEEP (*(SORT(.fini_array.*)))
    KEEP (*(.fini_array*))
    PROVIDE_HIDDEN (__fini_array_end = .);
    . = ALIGN(4);
  } >FLASH

  /* Used by the startup to initialize data */
  _sidata = LOADADDR(.data);

  /* Initialized data sections into "RAM" Ram type memory */
  .data :
  {
    . = ALIGN(4);
    _sdata = .;        /* create a global symbol at data start */
    *(.data)           /* .data sections */
    *(.data*)          /* .data* sections */
    *(.RamFunc)        /* .RamFunc sections */
    *(.RamFunc*)       /* .RamFunc* sections */

    . = ALIGN(4);
    _edata = .;        /* define a global symbol at data end */

  } >RAM AT> FLASH

  _siccmram = LOADADDR(.ccmram);

  /* CCM-RAM section
  *
  * IMPORTANT NOTE!
  * If initialized variables will be placed in this section,
  * the startup code needs to be modified to copy the init-values.
  */
  .ccmram :
  {
    . = ALIGN(4);
    _sccmram = .;       /* create a global symbol at ccmram start */
    *(.ccmram)
    *(.ccmram*)

    . = ALIGN(4);
    _eccmram = .;       /* create a global symbol at ccmram end */
  } >CCMRAM AT> FLASH

  /* Uninitialized data section into "RAM" Ram type memory */
  . = ALIGN(4);
  .bss :
  {
    /* This is used by the startup in order to initialize the .bss section */
    _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" Ram  type memory left */
  ._user_heap_stack :
  {
    . = ALIGN(8);
    PROVIDE ( end = . );
    PROVIDE ( _end = . );
    . = . + _Min_Heap_Size;
    . = . + _Min_Stack_Size;
    . = ALIGN(8);
  } >RAM
  
.app_trailer :
{
    . = ALIGN(16);
    _app_trailer = .;
    KEEP(*(.app_trailer)) /* Application Trailer */
    . = ALIGN(4);
    _app_fw_end = .;
} >FLASH

_app_fw_size = _app_fw_end - _APP_FW_START;

  /* Remove information from the compiler libraries */
  /DISCARD/ :
  {
    libc.a ( * )
    libm.a ( * )
    libgcc.a ( * )
  }

  .ARM.attributes 0 : { *(.ARM.attributes) }
}

 

Can you help me whta i am doing wrong now ? 

 

SGasp1_0-1716188701047.png

 

 

Thanks 

 

  .app_header :
  {
    . =  _APP_HEADER_OFFSET;
    KEEP(*(.app_header)) /* Bootloader Header */
    . = ALIGN(4);
  } > FLASH

 

this looks wrong. 

 

 

did you relocate isr vector in boorloder before you start app?