linker: correct linker script _flash_used calculation
Linker scripts contains a `.last_section` section that is placed in rom
region as NOLOAD for the purpose of retrieve the actual number of bytes
contained in the image. See d85efe0b10
However, a previous section may cause the location counter to be
incremented for alignment purposes. This can result in the size of the
image to be 0x10FA but location counter to be 0x1100 because it has been
aligned for next section placement.
Therefore, two new Kconfig settings are introduced.
Those settings request the linker to will write a pattern in
`.last_section`. Together with removing NOLOAD and writing a patten to
the section then we ensure that data is written after alignment of
location counter, and thereby forces the image size to be in sync with
the location counter.
The default pattern used will be 0xE015 (end of last section).
Some systems may fill up the flash completely, or simply write data at
the end of the flash, which in both cases can result in overflow.
Therefore, the new settings can be disabled.
Signed-off-by: Torsten Rasmussen <Torsten.Rasmussen@nordicsemi.no>
This commit is contained in:
parent
11e3344909
commit
c107827bb7
@ -266,6 +266,32 @@ config LINKER_GENERIC_SECTIONS_PRESENT_AT_BOOT
|
||||
|
||||
If unsure, say Y.
|
||||
|
||||
config LINKER_LAST_SECTION_ID
|
||||
bool "Last section identifier"
|
||||
default y
|
||||
depends on ARM || ARM64 || RISCV
|
||||
help
|
||||
If enabled, the last section will contain an identifier.
|
||||
This ensures that the '_flash_used' linker symbol will always be
|
||||
correctly calculated, even in cases where the location counter may
|
||||
have been incremented for alignment purposes but no data is placed
|
||||
after alignment.
|
||||
|
||||
Note: in cases where the flash is fully used, for example application
|
||||
specific data is written at the end of the flash area, then writing a
|
||||
last section identifier may cause rom region overflow.
|
||||
In such cases this setting should be disabled.
|
||||
|
||||
config LINKER_LAST_SECTION_ID_PATTERN
|
||||
hex "Last section identifier pattern"
|
||||
default "0xE015E015"
|
||||
depends on LINKER_LAST_SECTION_ID
|
||||
help
|
||||
Pattern to fill into last section as identifier.
|
||||
Default pattern is 0xE015 (end of last section), but any pattern can
|
||||
be used.
|
||||
The size of the pattern must not exceed 4 bytes.
|
||||
|
||||
endmenu # "Linker Sections"
|
||||
|
||||
endmenu
|
||||
|
||||
@ -385,12 +385,17 @@ GROUP_END(OCM)
|
||||
LINKER_DT_SECTIONS()
|
||||
|
||||
/* Must be last in romable region */
|
||||
SECTION_PROLOGUE(.last_section,(NOLOAD),)
|
||||
SECTION_PROLOGUE(.last_section,,)
|
||||
{
|
||||
#ifdef CONFIG_LINKER_LAST_SECTION_ID
|
||||
/* Fill last section with a word to ensure location counter and actual rom
|
||||
* region data usage match. */
|
||||
LONG(CONFIG_LINKER_LAST_SECTION_ID_PATTERN)
|
||||
#endif
|
||||
} GROUP_LINK_IN(ROMABLE_REGION)
|
||||
|
||||
/* To provide the image size as a const expression,
|
||||
* calculate this value here. */
|
||||
_flash_used = LOADADDR(.last_section) - __rom_region_start;
|
||||
_flash_used = LOADADDR(.last_section) + SIZEOF(.last_section) - __rom_region_start;
|
||||
|
||||
}
|
||||
|
||||
@ -440,12 +440,17 @@ GROUP_END(DTCM)
|
||||
LINKER_DT_SECTIONS()
|
||||
|
||||
/* Must be last in romable region */
|
||||
SECTION_PROLOGUE(.last_section,(NOLOAD),)
|
||||
SECTION_PROLOGUE(.last_section,,)
|
||||
{
|
||||
#ifdef CONFIG_LINKER_LAST_SECTION_ID
|
||||
/* Fill last section with a word to ensure location counter and actual rom
|
||||
* region data usage match. */
|
||||
LONG(CONFIG_LINKER_LAST_SECTION_ID_PATTERN)
|
||||
#endif
|
||||
} GROUP_LINK_IN(ROMABLE_REGION)
|
||||
|
||||
/* To provide the image size as a const expression,
|
||||
* calculate this value here. */
|
||||
_flash_used = LOADADDR(.last_section) - __rom_region_start;
|
||||
_flash_used = LOADADDR(.last_section) + SIZEOF(.last_section) - __rom_region_start;
|
||||
|
||||
}
|
||||
|
||||
@ -322,12 +322,17 @@ SECTIONS
|
||||
|
||||
|
||||
/* Must be last in romable region */
|
||||
SECTION_PROLOGUE(.last_section,(NOLOAD),)
|
||||
SECTION_PROLOGUE(.last_section,,)
|
||||
{
|
||||
#ifdef CONFIG_LINKER_LAST_SECTION_ID
|
||||
/* Fill last section with a word to ensure location counter and actual rom
|
||||
* region data usage match. */
|
||||
LONG(CONFIG_LINKER_LAST_SECTION_ID_PATTERN)
|
||||
#endif
|
||||
} GROUP_ROM_LINK_IN(RAMABLE_REGION, ROMABLE_REGION)
|
||||
|
||||
/* To provide the image size as a const expression,
|
||||
* calculate this value here. */
|
||||
_flash_used = LOADADDR(.last_section) - __rom_region_start;
|
||||
_flash_used = LOADADDR(.last_section) + SIZEOF(.last_section) - __rom_region_start;
|
||||
|
||||
}
|
||||
|
||||
@ -399,13 +399,18 @@ GROUP_END(DTCM)
|
||||
*/
|
||||
#ifdef CONFIG_XIP
|
||||
/* Must be last in romable region */
|
||||
SECTION_PROLOGUE(.last_section,(NOLOAD),)
|
||||
SECTION_PROLOGUE(.last_section,,)
|
||||
{
|
||||
#ifdef CONFIG_LINKER_LAST_SECTION_ID
|
||||
/* Fill last section with a word to ensure location counter and actual rom
|
||||
* region data usage match. */
|
||||
LONG(CONFIG_LINKER_LAST_SECTION_ID_PATTERN)
|
||||
#endif
|
||||
} GROUP_LINK_IN(ROMABLE_REGION)
|
||||
|
||||
/* To provide the image size as a const expression,
|
||||
* calculate this value here. */
|
||||
__rom_region_end = LOADADDR(.last_section);
|
||||
__rom_region_end = LOADADDR(.last_section) + SIZEOF(.last_section);
|
||||
__rom_region_size = __rom_region_end - __rom_region_start;
|
||||
#endif
|
||||
|
||||
|
||||
@ -360,13 +360,18 @@ GROUP_END(DTCM)
|
||||
}
|
||||
|
||||
/* Must be last in romable region */
|
||||
SECTION_PROLOGUE(.last_section,(NOLOAD),)
|
||||
SECTION_PROLOGUE(.last_section,,)
|
||||
{
|
||||
#ifdef CONFIG_LINKER_LAST_SECTION_ID
|
||||
/* Fill last section with a word to ensure location counter and actual rom
|
||||
* region data usage match. */
|
||||
LONG(CONFIG_LINKER_LAST_SECTION_ID_PATTERN)
|
||||
#endif
|
||||
} GROUP_LINK_IN(ROMABLE_REGION)
|
||||
|
||||
/* To provide the image size as a const expression,
|
||||
* calculate this value here. */
|
||||
__rom_region_end = LOADADDR(.last_section);
|
||||
__rom_region_end = LOADADDR(.last_section) + SIZEOF(.last_section);
|
||||
__rom_region_size = __rom_region_end - __rom_region_start;
|
||||
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user