Load Address (LMA) for a ld link script when using non volatile memory (NVRAM)

490 Views Asked by At

I am working on baremetal application for an MSP430 MCU from TI. This MCU uses FRAM, a non volatile memory. The following script for SRAM works well:

SECTIONS {
  __data_load_start = .;
  .data : AT ( __data_load_start )
  {
    . = ALIGN(2);
    __data_start = .;   
    *(.data*)
    __data_end = .;
  } >RAM
}

__data_load_start gets the load memory address in flash (implicitly?), and reserves some space in RAM.

Now, I want to use it for non volatile memory. This memory zone, under certain circumstances will be re-initialized to their initial value, so the Load Address (LMA) and Virtual Address (VMA) will be different, as explained in the ld documentation.

SECTIONS {
   __nvdata_load_start  = .;
  .NVdata : AT ( __nvdata_load_start ) { 
    . = ALIGN(2);
    __nvdata_start = .; 
    *(.nvdata*)
    __nvdata_end = .;
  } >FRAM

However, it doesn't work. A look to the .map output file shows that the load address has been set out of any memory section :/

.NVdata         0x0000000000004400        0x4 load address 0x0000000000010000

I would like to specify explicitly the location of the initial value of this memory region. Do anyone can help?

EDIT:

I have tried to update the script not to have any implicit rule:

SECTIONS {
  .NVdata : AT ( __nvdata_load_start ) { 
    . = ALIGN(2);
    __nvdata_start = .; 
    *(.nvdata*)
    __nvdata_end = .;
  } >FRAM

  .NVdataInit : {
     . = ALIGN(2);
     __nvdata_load_start = .;
      /* reserve space for non volatile data init value */
     . += SIZEOF(.NVdata);
  } >FRAM
}

But in this case, each section that is declared after gets an offset between the VMA and LMA. For instance, the section that just follows gives (.map file):

.textInit       0x0000000000004408      0x416 load address 0x000000000000440c

But both adresses should be same :/

1

There are 1 best solutions below

0
On

I found a workaround. When I have declared the section .NVdata and .NVdataInit (just above), there was an offset between the LMA and VMA and the binary code was incorrect.

In the section that just follows, I have forced LMA and VMA to be the same:

SECTIONS {
    /* we make sure that both 
     * - VMA (virtual memory address) and 
     * - LMA (load memory address) 
     * are the same */
  .textInit __nvdata_load_end : AT(__nvdata_load_end) {
    KEEP(*(.init)) /* start here after reset */
  } > FRAM
}

It now works perfectly, even if I don't understand why this offset has appeared :/