LMA VS VMA
Consider that your application is stored in a Flash and you don’t want to execute it from the flash because flash is slow or you need to change/patch the application on the go. What do you do? You copy it to the RAM and execute from there. In this simple example LMA would be the address in the flash and VMA the address in the RAM. Having both enables you to copy the application easily because that gives you the where from and where to locations.
// .ld file syntax
.data :
{
*(.data*);
} > ram AT > rom /* "> ram" is the VMA, "> rom" is the LMA */TRANSCRIBE MEMORY MAP
0x0 +---------------------+
| |
| Bootloader |
| |
0x4000 +---------------------+
| |
| |
| Application |
| |
| |
0x30000 +---------------------+We can transcribe that memory into a linker script:
/* memory_map.ld */
MEMORY
{
bootrom (rx) : ORIGIN = 0x00000000, LENGTH = 0x00004000
approm (rx) : ORIGIN = 0x00004000, LENGTH = 0x0003C000
ram (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00008000
}
__bootrom_start__ = ORIGIN(bootrom);
__bootrom_size__ = LENGTH(bootrom);
__approm_start__ = ORIGIN(approm);
__approm_size__ = LENGTH(approm);The linker script above declares some variables. We’ll need those for our bootloader to know where to find the application. To make them accessible in C code, we declare them in a header file:
/* memory_map.h */
#pragma once
extern int __bootrom_start__;
extern int __bootrom_size__;
extern int __approm_start__;
extern int __approm_size__;https://interrupt.memfault.com/blog/how-to-write-linker-scripts-for-firmware
https://microcontrollerslab.com/bare-metal-embedded-systems-linker-script-file/