linker: move last section id constant to c-code
Move creation of last section id from ld linker script LONG() usage to
C code with last section attribute.
The use of `LONG()` works correctly with ld but lld emits a warning
because .last_section section is not allocated as there are no matching
input sections and discards the `LONG()` call, meaning the last section
identifier will not be present in the flash.
> ld.lld: warning: ignoring memory region assignment for
> non-allocatable section '.last_section'
Placing the last section id in `.last_section` in C code makes lld
allocate the memory for the id and thereby create the output section
with the correct output.
Signed-off-by: Torsten Rasmussen <Torsten.Rasmussen@nordicsemi.no>
diff --git a/include/zephyr/arch/arm/cortex_a_r/scripts/linker.ld b/include/zephyr/arch/arm/cortex_a_r/scripts/linker.ld
index aed26ab..ba5413c 100644
--- a/include/zephyr/arch/arm/cortex_a_r/scripts/linker.ld
+++ b/include/zephyr/arch/arm/cortex_a_r/scripts/linker.ld
@@ -366,11 +366,9 @@
/* Must be last in romable region */
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
+ /* .last_section contains a fixed word to ensure location counter and actual
+ * rom region data usage match when CONFIG_LINKER_LAST_SECTION_ID=y. */
+ KEEP(*(.last_section))
} GROUP_LINK_IN(ROMABLE_REGION)
/* To provide the image size as a const expression,
diff --git a/include/zephyr/arch/arm/cortex_m/scripts/linker.ld b/include/zephyr/arch/arm/cortex_m/scripts/linker.ld
index ff11d49..278620d 100644
--- a/include/zephyr/arch/arm/cortex_m/scripts/linker.ld
+++ b/include/zephyr/arch/arm/cortex_m/scripts/linker.ld
@@ -412,11 +412,9 @@
/* Must be last in romable region */
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
+ /* .last_section contains a fixed word to ensure location counter and actual
+ * rom region data usage match when CONFIG_LINKER_LAST_SECTION_ID=y. */
+ KEEP(*(.last_section))
} GROUP_LINK_IN(ROMABLE_REGION)
/* To provide the image size as a const expression,
diff --git a/include/zephyr/arch/arm64/scripts/linker.ld b/include/zephyr/arch/arm64/scripts/linker.ld
index d5a4e25..ee29e43 100644
--- a/include/zephyr/arch/arm64/scripts/linker.ld
+++ b/include/zephyr/arch/arm64/scripts/linker.ld
@@ -351,11 +351,9 @@
/* Must be last in romable region */
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
+ /* .last_section contains a fixed word to ensure location counter and actual
+ * rom region data usage match when CONFIG_LINKER_LAST_SECTION_ID=y. */
+ KEEP(*(.last_section))
} GROUP_ROM_LINK_IN(RAMABLE_REGION, ROMABLE_REGION)
/* To provide the image size as a const expression,
diff --git a/include/zephyr/arch/riscv/common/linker.ld b/include/zephyr/arch/riscv/common/linker.ld
index 87aa159..a63bc03 100644
--- a/include/zephyr/arch/riscv/common/linker.ld
+++ b/include/zephyr/arch/riscv/common/linker.ld
@@ -454,15 +454,13 @@
/* Must be last in romable region */
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)
+ /* .last_section contains a fixed word to ensure location counter and actual
+ * rom region data usage match when CONFIG_LINKER_LAST_SECTION_ID=y. */
+ KEEP(*(.last_section))
/* __rom_region_size is used when configuring the PMP entry of the ROM region.
* Addresses (pmpaddr) in PMP registers need to be aligned to 4. Align
* __rom_region_size to 4 to meet that requirement. */
MPU_MIN_SIZE_ALIGN
-#endif
} GROUP_LINK_IN(ROMABLE_REGION)
/* To provide the image size as a const expression,
diff --git a/lib/utils/CMakeLists.txt b/lib/utils/CMakeLists.txt
index 7062d69..aca2e69 100644
--- a/lib/utils/CMakeLists.txt
+++ b/lib/utils/CMakeLists.txt
@@ -28,3 +28,5 @@
${ZEPHYR_BASE}/kernel/include
${ZEPHYR_BASE}/arch/${ARCH}/include
)
+
+zephyr_sources_ifdef(CONFIG_LINKER_LAST_SECTION_ID last_section_id.c)
diff --git a/lib/utils/last_section_id.c b/lib/utils/last_section_id.c
new file mode 100644
index 0000000..02a2065
--- /dev/null
+++ b/lib/utils/last_section_id.c
@@ -0,0 +1,10 @@
+/*
+ * Copyright (C) 2025, Nordic Semiconductor ASA
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ */
+#include <zephyr/types.h>
+
+static uint32_t last_id __attribute__((section(".last_section"))) __attribute__((__used__)) =
+ CONFIG_LINKER_LAST_SECTION_ID_PATTERN;
diff --git a/soc/andestech/ae350/linker.ld b/soc/andestech/ae350/linker.ld
index ae10cab..36e4e51 100644
--- a/soc/andestech/ae350/linker.ld
+++ b/soc/andestech/ae350/linker.ld
@@ -421,11 +421,9 @@
/* Must be last in romable region */
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
+ /* .last_section contains a fixed word to ensure location counter and actual
+ * rom region data usage match when CONFIG_LINKER_LAST_SECTION_ID=y. */
+ KEEP(*(.last_section))
} GROUP_LINK_IN(ROMABLE_REGION)
/* Because ROMABLE_REGION != RAMABLE_REGION in XIP-system, it is valid
diff --git a/soc/infineon/cat1b/cyw20829/linker.ld b/soc/infineon/cat1b/cyw20829/linker.ld
index 2395740..5f6b02e 100644
--- a/soc/infineon/cat1b/cyw20829/linker.ld
+++ b/soc/infineon/cat1b/cyw20829/linker.ld
@@ -466,11 +466,9 @@
/* Must be last in romable region */
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
+ /* .last_section contains a fixed word to ensure location counter and actual
+ * rom region data usage match when CONFIG_LINKER_LAST_SECTION_ID=y. */
+ KEEP(*(.last_section))
} GROUP_LINK_IN(ROMABLE_REGION)
/* To provide the image size as a const expression,