GNU link script use

Keywords: Attribute Makefile

The main function of link script is to describe how the section of input file is mapped to the memory layout of output file. The popular way is to compile each obj file and place it in the bin address according to which order; at the same time, associate the run-time variable symbol with VMA.
It mainly refers to the following Blogs:
1. attribute of link script
2. Analysis of gnu-ld link script

Use cases

1. Store variables or functions in user-defined areas

The main purpose is to link variables or functions to user-defined areas at runtime, such as SRAM. Some CPU s run faster than FLASH (not necessarily STM32. FLASH on chip is on the ICODE bus. The instruction prefetch function enables to realize operations similar to multi-level pipeline. SRAM is no longer on ICODE and cannot be accelerated by "fetch, decode and execute".
The main syntax of link script is as follows:
The MEMORY command defines the storage area, and explicitly limits the section to the specific storage area by outputting > region described in the section. As follows: the last area is stm32f746ng and the last 64k, which is used to store the test variables.

MEMORY
{
RAM (xrw)      : ORIGIN = 0x20000000, LENGTH = 320K
FLASH (rx)      : ORIGIN = 0x8000000, LENGTH = 960K
USER_AREA(rx)   : ORIGIN = 0x80F0000, LENGTH = 64K
}

Add the following description to the SECTIONS section of the linked script:

  _siusrdata = LOADADDR(.usrdata); /* LOADADDR This paper describes the LMA of the. usrdata segment, which can be declared in the program: extern char ﹣ siusrdata; only the address of ﹣ siusrdata can be used: char * SRC = &﹣ siusrdata; SRC is actually equal to 0x80F0000*/

  .usrdata :
  {
    . = ALIGN(4);
    _susrdata = .;        /* create a global symbol at usrdata start;VMA address*/
    *(.usrdata)           /* .usrdata sections */
    *(.usrdata*)          /* .usrdata* sections */

    . = ALIGN(4);
    _eusrdata = .;        /* define a global symbol at usrdata end */
  } >RAM AT> USER_AREA

In the main program, the attribute is used to declare the section in the declaration, and the variables in the link script are declared with extern:

int data_usrarea __attribute__((section(".usrdata"))) = 6666 ;
extern char _siusrdata,_susrdata,_eusrdata;

When used:

printf("usrarea LMA = %X, VMA = %X\r\n", &_siusrdata, &_susrdata);
printf(usrdata addr = %X, value=%d\r\n", &data_usrarea,data_usrarea);

The printing results are as follows:

usrarea LMA = 80F0000, VMA = 20000070
usrdata addr = 20000070, value=-536140031

The address is right, but how is the value wrong? Actually, the reason is that our custom region does not load the data to the correct VMA address. The default. Data area of the system is loaded when the system starts. Different project implementation methods are different. For example, this is done in the makefile project generated by stm32 cubumx

Reset_Handler:  
  ldr   sp, =_estack      /* set stack pointer */

/* Copy the data segment initializers from flash to SRAM */  
  movs  r1, #0
  b  LoopCopyDataInit

CopyDataInit:
  ldr  r3, =_sidata
  ldr  r3, [r3, r1]
  str  r3, [r0, r1]
  adds  r1, r1, #4
    
LoopCopyDataInit:
  ldr  r0, =_sdata
  ldr  r3, =_edata
  adds  r2, r0, r1
  cmp  r2, r3
  bcc  CopyDataInit
  ldr  r2, =_sbss
  b  LoopFillZerobss

The purpose of this assembly is to load the. data area into SRAM, the initialized global variable area. We can also add our own code in the assembly, but it is better to implement it in the main function without destroying the integrity of the original file.

  char *srcdata_ptr = &_siusrdata;
  char *dstdata_ptr = &_susrdata;
  while(dstdata_ptr < &_eusrdata)
  {
    *dstdata_ptr++ = *srcdata_ptr++;
  }

Add the above code to complete. The usrdata area is loaded from LMA to VMA, and then it can run happily. The print information is as follows.

usrarea LMA = 80F0000, VMA = 20000070
usrdata addr = 20000070, value=6666

Thinking, with this function, in fact, we can update the program in sections, such as defining some configuration parameters to store in a specific area, and then directly update this area when updating. More flexible online upgrade.

Posted by jcavard on Wed, 27 Nov 2019 01:54:04 -0800