diff --git a/Kconfig.zephyr b/Kconfig.zephyr index 4710cc82149..0edb610d677 100644 --- a/Kconfig.zephyr +++ b/Kconfig.zephyr @@ -306,6 +306,24 @@ config LINKER_USE_RELAX endmenu # "Linker Sections" +config LINKER_DEVNULL_SUPPORT + bool + default y if CPU_CORTEX_M || (RISCV && !64BIT) + +config LINKER_DEVNULL_MEMORY + bool "Devnull region" + depends on LINKER_DEVNULL_SUPPORT + help + Devnull region is created. It is stripped from final binary but remains + in byproduct elf file. + +config LINKER_DEVNULL_MEMORY_SIZE + int "Devnull region size" + depends on LINKER_DEVNULL_MEMORY + default 262144 + help + Size can be adjusted so it fits all data placed in that region. + endmenu menu "Compiler Options" diff --git a/include/zephyr/arch/arm/cortex_m/scripts/linker.ld b/include/zephyr/arch/arm/cortex_m/scripts/linker.ld index 92b6f02d029..13c2747f5a3 100644 --- a/include/zephyr/arch/arm/cortex_m/scripts/linker.ld +++ b/include/zephyr/arch/arm/cortex_m/scripts/linker.ld @@ -35,7 +35,7 @@ #if CONFIG_FLASH_LOAD_SIZE > 0 #define ROM_SIZE CONFIG_FLASH_LOAD_SIZE #else -#define ROM_SIZE (CONFIG_FLASH_SIZE*1K - CONFIG_FLASH_LOAD_OFFSET) +#define ROM_SIZE (CONFIG_FLASH_SIZE * 1024 - CONFIG_FLASH_LOAD_OFFSET) #endif #if defined(CONFIG_XIP) @@ -75,10 +75,15 @@ _region_min_align = 4; . = ALIGN(_region_min_align) #endif +#include + MEMORY { FLASH (rx) : ORIGIN = ROM_ADDR, LENGTH = ROM_SIZE RAM (wx) : ORIGIN = RAM_ADDR, LENGTH = RAM_SIZE +#if defined(CONFIG_LINKER_DEVNULL_MEMORY) + DEVNULL_ROM (rx) : ORIGIN = DEVNULL_ADDR, LENGTH = DEVNULL_SIZE +#endif LINKER_DT_REGIONS() /* Used by and documented in include/linker/intlist.ld */ IDT_LIST (wx) : ORIGIN = 0xFFFFF7FF, LENGTH = 2K diff --git a/include/zephyr/arch/riscv/common/linker.ld b/include/zephyr/arch/riscv/common/linker.ld index 5bed82439d6..eb5c4782441 100644 --- a/include/zephyr/arch/riscv/common/linker.ld +++ b/include/zephyr/arch/riscv/common/linker.ld @@ -72,6 +72,8 @@ #define MPU_ALIGN(region_size) . = ALIGN(4) #endif +#include + MEMORY { #ifdef CONFIG_XIP @@ -79,6 +81,10 @@ MEMORY #endif RAM (rwx) : ORIGIN = RAM_BASE, LENGTH = RAM_SIZE +#if defined(CONFIG_LINKER_DEVNULL_MEMORY) + DEVNULL_ROM (rx) : ORIGIN = DEVNULL_ADDR, LENGTH = DEVNULL_SIZE +#endif + LINKER_DT_REGIONS() /* Used by and documented in include/linker/intlist.ld */ diff --git a/include/zephyr/linker/linker-devnull.h b/include/zephyr/linker/linker-devnull.h new file mode 100644 index 00000000000..0545da7c8a5 --- /dev/null +++ b/include/zephyr/linker/linker-devnull.h @@ -0,0 +1,78 @@ +/* + * Copyright (c) 2023 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/* + * DESCRIPTION + * Platform independent set of macros for creating a memory segment for + * aggregating data that shall be kept in the elf file but not in the binary. + */ + +#ifndef ZEPHYR_INCLUDE_LINKER_LINKER_DEVNULL_H_ + +#if defined(CONFIG_LINKER_DEVNULL_MEMORY) + +#if defined(CONFIG_XIP) +#if (!defined(ROM_ADDR) && !defined(ROM_BASE)) || !defined(ROM_SIZE) +#error "ROM_SIZE, ROM_ADDR or ROM_BASE not defined" +#endif +#endif /* CONFIG_XIP */ + +#if (!defined(RAM_ADDR) && !defined(RAM_BASE)) || !defined(RAM_SIZE) +#error "RAM_SIZE, RAM_ADDR or RAM_BASE not defined" +#endif + +#if defined(CONFIG_XIP) && !defined(ROM_ADDR) +#define ROM_ADDR ROM_BASE +#endif + +#if !defined(RAM_ADDR) +#define RAM_ADDR RAM_BASE +#endif + +#define ROM_END_ADDR (ROM_ADDR + ROM_SIZE) +#define DEVNULL_SIZE CONFIG_LINKER_DEVNULL_MEMORY_SIZE +#define ROM_DEVNULL_END_ADDR (ROM_END_ADDR + DEVNULL_SIZE) +#define MAX_ADDR UINT32_MAX + +/* Determine where to put the devnull region. It should be adjacent to the ROM + * region. If ROM starts after RAM or the distance between ROM and RAM is big + * enough to fit the devnull region then devnull region is placed just after + * the ROM region. If it cannot be done then the devnull region is placed before + * the ROM region. It is possible that the devnull region cannot be placed + * adjacent to the ROM (e.g. ROM starts at 0 and RAM follows ROM). In that + * case compilation fails and the devnull region is not supported in that + * configuration. + */ +#if !defined(CONFIG_XIP) + +#if RAM_ADDR >= DEVNULL_SIZE +#define DEVNULL_ADDR (RAM_ADDR - DEVNULL_SIZE) +#else +#define DEVNULL_ADDR (RAM_ADDR + RAM_SIZE) +#endif + +#else /* CONFIG_XIP */ + +#if ((ROM_ADDR > RAM_ADDR) && ((MAX_ADDR - ROM_END_ADDR) >= DEVNULL_SIZE)) || \ + ((ROM_END_ADDR + DEVNULL_SIZE) <= RAM_ADDR) +#define DEVNULL_ADDR ROM_END_ADDR +#elif ROM_ADDR > DEVNULL_SIZE +#define DEVNULL_ADDR (ROM_ADDR - DEVNULL_SIZE) +#else +#error "Cannot place devnull segment adjacent to ROM region." +#endif + +#if defined(CONFIG_LINKER_DEVNULL_MEMORY) +#define DEVNULL_REGION DEVNULL_ROM +#else +#define DEVNULL_REGION ROMABLE_REGION +#endif + +#endif /* CONFIG_XIP */ + +#endif /* CONFIG_LINKER_DEVNULL_MEMORY */ + +#endif /* ZEPHYR_INCLUDE_LINKER_LINKER_DEVNULL_H_ */