Skip to content

Commit c107827

Browse files
tejlmandfabiobaltieri
authored andcommitted
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 d85efe0 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 <[email protected]>
1 parent 11e3344 commit c107827

File tree

6 files changed

+61
-10
lines changed

6 files changed

+61
-10
lines changed

Kconfig.zephyr

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -266,6 +266,32 @@ config LINKER_GENERIC_SECTIONS_PRESENT_AT_BOOT
266266

267267
If unsure, say Y.
268268

269+
config LINKER_LAST_SECTION_ID
270+
bool "Last section identifier"
271+
default y
272+
depends on ARM || ARM64 || RISCV
273+
help
274+
If enabled, the last section will contain an identifier.
275+
This ensures that the '_flash_used' linker symbol will always be
276+
correctly calculated, even in cases where the location counter may
277+
have been incremented for alignment purposes but no data is placed
278+
after alignment.
279+
280+
Note: in cases where the flash is fully used, for example application
281+
specific data is written at the end of the flash area, then writing a
282+
last section identifier may cause rom region overflow.
283+
In such cases this setting should be disabled.
284+
285+
config LINKER_LAST_SECTION_ID_PATTERN
286+
hex "Last section identifier pattern"
287+
default "0xE015E015"
288+
depends on LINKER_LAST_SECTION_ID
289+
help
290+
Pattern to fill into last section as identifier.
291+
Default pattern is 0xE015 (end of last section), but any pattern can
292+
be used.
293+
The size of the pattern must not exceed 4 bytes.
294+
269295
endmenu # "Linker Sections"
270296

271297
endmenu

include/zephyr/arch/arm/aarch32/cortex_a_r/scripts/linker.ld

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -385,12 +385,17 @@ GROUP_END(OCM)
385385
LINKER_DT_SECTIONS()
386386

387387
/* Must be last in romable region */
388-
SECTION_PROLOGUE(.last_section,(NOLOAD),)
388+
SECTION_PROLOGUE(.last_section,,)
389389
{
390+
#ifdef CONFIG_LINKER_LAST_SECTION_ID
391+
/* Fill last section with a word to ensure location counter and actual rom
392+
* region data usage match. */
393+
LONG(CONFIG_LINKER_LAST_SECTION_ID_PATTERN)
394+
#endif
390395
} GROUP_LINK_IN(ROMABLE_REGION)
391396

392397
/* To provide the image size as a const expression,
393398
* calculate this value here. */
394-
_flash_used = LOADADDR(.last_section) - __rom_region_start;
399+
_flash_used = LOADADDR(.last_section) + SIZEOF(.last_section) - __rom_region_start;
395400

396401
}

include/zephyr/arch/arm/aarch32/cortex_m/scripts/linker.ld

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -440,12 +440,17 @@ GROUP_END(DTCM)
440440
LINKER_DT_SECTIONS()
441441

442442
/* Must be last in romable region */
443-
SECTION_PROLOGUE(.last_section,(NOLOAD),)
443+
SECTION_PROLOGUE(.last_section,,)
444444
{
445+
#ifdef CONFIG_LINKER_LAST_SECTION_ID
446+
/* Fill last section with a word to ensure location counter and actual rom
447+
* region data usage match. */
448+
LONG(CONFIG_LINKER_LAST_SECTION_ID_PATTERN)
449+
#endif
445450
} GROUP_LINK_IN(ROMABLE_REGION)
446451

447452
/* To provide the image size as a const expression,
448453
* calculate this value here. */
449-
_flash_used = LOADADDR(.last_section) - __rom_region_start;
454+
_flash_used = LOADADDR(.last_section) + SIZEOF(.last_section) - __rom_region_start;
450455

451456
}

include/zephyr/arch/arm64/scripts/linker.ld

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -322,12 +322,17 @@ SECTIONS
322322

323323

324324
/* Must be last in romable region */
325-
SECTION_PROLOGUE(.last_section,(NOLOAD),)
325+
SECTION_PROLOGUE(.last_section,,)
326326
{
327+
#ifdef CONFIG_LINKER_LAST_SECTION_ID
328+
/* Fill last section with a word to ensure location counter and actual rom
329+
* region data usage match. */
330+
LONG(CONFIG_LINKER_LAST_SECTION_ID_PATTERN)
331+
#endif
327332
} GROUP_ROM_LINK_IN(RAMABLE_REGION, ROMABLE_REGION)
328333

329334
/* To provide the image size as a const expression,
330335
* calculate this value here. */
331-
_flash_used = LOADADDR(.last_section) - __rom_region_start;
336+
_flash_used = LOADADDR(.last_section) + SIZEOF(.last_section) - __rom_region_start;
332337

333338
}

include/zephyr/arch/riscv/common/linker.ld

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -399,13 +399,18 @@ GROUP_END(DTCM)
399399
*/
400400
#ifdef CONFIG_XIP
401401
/* Must be last in romable region */
402-
SECTION_PROLOGUE(.last_section,(NOLOAD),)
402+
SECTION_PROLOGUE(.last_section,,)
403403
{
404+
#ifdef CONFIG_LINKER_LAST_SECTION_ID
405+
/* Fill last section with a word to ensure location counter and actual rom
406+
* region data usage match. */
407+
LONG(CONFIG_LINKER_LAST_SECTION_ID_PATTERN)
408+
#endif
404409
} GROUP_LINK_IN(ROMABLE_REGION)
405410

406411
/* To provide the image size as a const expression,
407412
* calculate this value here. */
408-
__rom_region_end = LOADADDR(.last_section);
413+
__rom_region_end = LOADADDR(.last_section) + SIZEOF(.last_section);
409414
__rom_region_size = __rom_region_end - __rom_region_start;
410415
#endif
411416

soc/riscv/riscv-privilege/andes_v5/ae350/linker.ld

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -360,13 +360,18 @@ GROUP_END(DTCM)
360360
}
361361

362362
/* Must be last in romable region */
363-
SECTION_PROLOGUE(.last_section,(NOLOAD),)
363+
SECTION_PROLOGUE(.last_section,,)
364364
{
365+
#ifdef CONFIG_LINKER_LAST_SECTION_ID
366+
/* Fill last section with a word to ensure location counter and actual rom
367+
* region data usage match. */
368+
LONG(CONFIG_LINKER_LAST_SECTION_ID_PATTERN)
369+
#endif
365370
} GROUP_LINK_IN(ROMABLE_REGION)
366371

367372
/* To provide the image size as a const expression,
368373
* calculate this value here. */
369-
__rom_region_end = LOADADDR(.last_section);
374+
__rom_region_end = LOADADDR(.last_section) + SIZEOF(.last_section);
370375
__rom_region_size = __rom_region_end - __rom_region_start;
371376

372377
}

0 commit comments

Comments
 (0)