4

I'm writing a customized linker script for a bare-metal ARM application. The application is stored in a flash memory, at the moment I have a bootup code copying the whole application in SDRAM, and continuing execution in SDRAM for speed purpose. I want to modify this script to run the whole code from flash directly, but I have problems understanding certain elements.

In the linker script below, the .ram_data section has an execution address in RAM and a load address in ROM (both sections in SDRAM). From what I understand the execution address is used by the linker to do the symbol resolution of all elements which are not PC relative, but what about the load address? In the context of a bare-metal ARM there is no such thing as a program loader, and there is no way the linker can have any influence on where I write the program in flash, so what is it actually used for?

In the same way, how can the linker have any influence on the SDRAM being (rx) or (rw) at run-time? Does it actually change anything when I modify those options in the memory regions?

MEMORY
{
  RAM(rw) : ORIGIN = 0x00001000, LENGTH = 12M-4K
  ROM(rx) : ORIGIN = 0x007f1000, LENGTH = 60K
}              

SECTIONS                                                                
{    
   .startup : 
   { ... } > VECTOR                

   .rom_text :   
   { ... } > ROM 

   .ram_data : 
   {   
      _data_start = .;                                                                 
      *(.data*)        
      _data_end = .;       
   } > RAM AT>ROM 

   .ram_bss :
   { ... } > RAM
}
artless noise
  • 21,212
  • 6
  • 68
  • 105
Étienne
  • 4,773
  • 2
  • 33
  • 58

2 Answers2

1

From what I understand the execution address is used by the linker to do the symbol resolution of all elements which are not PC relative, but what about the load address? In the context of a bare-metal ARM there is no such thing as a program loader, and there is no way the linker can have any influence on where I write the program in flash, so what is it actually used for?

That information is stored in the ELF executable, and is used by tools like objcopy to determine how the binary file (e.g, .bin or .hex) is laid out. Ultimately, it ends up telling your programmer where to put the program.

In the same way, how can the linker have any influence on the SDRAM being (rx) or (rw) at run-time? Does it actually change anything when I modify those options in the memory regions?

In this particular use case, I believe those flags are informational only. They're primarily used for dynamic-loaded programs.

  • Okay, thank you for the answer! In that particular case I use a hand-written programmer which doesn't read the binary information, but good to know it is used for that purpose. – Étienne Apr 09 '13 at 21:04
1

Given your example linker script, these two questions are related.

From what I understand the execution address is used by the linker to do the symbol resolution of all elements which are not PC relative, but what about the load address?

In the same way, how can the linker have any influence on the SDRAM being (rx) or (rw) at run-time? Does it actually change anything when I modify those options in the memory regions?

The LOAD address is useful as everything must be programmed to FLASH. This is why .ram_data should have AT>ROM. It is telling the linker that the data will LOAD from the ROM/Flash. You have to make some assembler boot code that will copy it from flash to SDRAM in this case.

The 2nd question can be answered by putting >ROM for the .ram_data section. If you do this, the linker will complain that a write-able section is being placed in read-only memory. It is good to mark the MEMORY sections with read/write information as it can help to make sure you have the sections in the correct places. Ie, it is a cross check on the information you give the linker.

A mistake where >RAM AT>ROM is instead just >ROM makes the concepts/questions similar.

Community
  • 1
  • 1
artless noise
  • 21,212
  • 6
  • 68
  • 105
  • Okay, thank you! In my case, the name is a bit misleading, "ROM" is actually in SDRAM, the content from flash is copied to the section "ROM" in sdram, and executed in the section "RAM" in sdram. So the linker doesn't know about the flash address (0xffff0000 in my case), and the boot-up code doing the copy is written with PC relative instructions. – Étienne Apr 10 '13 at 19:00
  • @Étienne I see. Well, you can actually execute from **NOR** flash in some situations (it is probably slower for you with SDRAM). In this case, the `.text` stays in *flash* and the `.data` is copied to SDRAM from *flash*. You could make your boot loader code non-PC relative by defining a **FLASH** memory region and list the boot loader objects in that section. However, if both your **ROM** and **RAM** are in SDRAM, the using `AT` is not needed and wastes memory. – artless noise Apr 10 '13 at 19:48