diff --git a/Kconfig.zephyr b/Kconfig.zephyr index b623b2892c0..289abc2194c 100644 --- a/Kconfig.zephyr +++ b/Kconfig.zephyr @@ -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 diff --git a/include/zephyr/arch/arm/aarch32/cortex_a_r/scripts/linker.ld b/include/zephyr/arch/arm/aarch32/cortex_a_r/scripts/linker.ld index f56548f3bca..2a3d7a2d39e 100644 --- a/include/zephyr/arch/arm/aarch32/cortex_a_r/scripts/linker.ld +++ b/include/zephyr/arch/arm/aarch32/cortex_a_r/scripts/linker.ld @@ -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; } diff --git a/include/zephyr/arch/arm/aarch32/cortex_m/scripts/linker.ld b/include/zephyr/arch/arm/aarch32/cortex_m/scripts/linker.ld index e6341d587b6..9620f96f406 100644 --- a/include/zephyr/arch/arm/aarch32/cortex_m/scripts/linker.ld +++ b/include/zephyr/arch/arm/aarch32/cortex_m/scripts/linker.ld @@ -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; } diff --git a/include/zephyr/arch/arm64/scripts/linker.ld b/include/zephyr/arch/arm64/scripts/linker.ld index 05ae9464fe6..1a608150ef5 100644 --- a/include/zephyr/arch/arm64/scripts/linker.ld +++ b/include/zephyr/arch/arm64/scripts/linker.ld @@ -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; } diff --git a/include/zephyr/arch/riscv/common/linker.ld b/include/zephyr/arch/riscv/common/linker.ld index e5b623e0506..52f0a2b97e8 100644 --- a/include/zephyr/arch/riscv/common/linker.ld +++ b/include/zephyr/arch/riscv/common/linker.ld @@ -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 diff --git a/soc/riscv/riscv-privilege/andes_v5/ae350/linker.ld b/soc/riscv/riscv-privilege/andes_v5/ae350/linker.ld index 9245971c6d3..0db410ca997 100644 --- a/soc/riscv/riscv-privilege/andes_v5/ae350/linker.ld +++ b/soc/riscv/riscv-privilege/andes_v5/ae350/linker.ld @@ -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; }