Skip to content

Commit

Permalink
linker: Add devnull memory for cortex_m and riscv32
Browse files Browse the repository at this point in the history
Added memory region which is intended to be removed from the final
binary but may be using in byproduct to extract data used by the
host tools (e.g. strings used by logging).

Add devnull region to Cortex-M and RISCV linker scripts.

Signed-off-by: Krzysztof Chruściński <[email protected]>
  • Loading branch information
nordic-krch authored and carlescufi committed Oct 27, 2023
1 parent 0fe6c72 commit dfb3674
Show file tree
Hide file tree
Showing 4 changed files with 108 additions and 1 deletion.
18 changes: 18 additions & 0 deletions Kconfig.zephyr
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down
7 changes: 6 additions & 1 deletion include/zephyr/arch/arm/cortex_m/scripts/linker.ld
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -75,10 +75,15 @@ _region_min_align = 4;
. = ALIGN(_region_min_align)
#endif

#include <zephyr/linker/linker-devnull.h>

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
Expand Down
6 changes: 6 additions & 0 deletions include/zephyr/arch/riscv/common/linker.ld
Original file line number Diff line number Diff line change
Expand Up @@ -72,13 +72,19 @@
#define MPU_ALIGN(region_size) . = ALIGN(4)
#endif

#include <zephyr/linker/linker-devnull.h>

MEMORY
{
#ifdef CONFIG_XIP
ROM (rx) : ORIGIN = ROM_BASE, LENGTH = ROM_SIZE
#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 */
Expand Down
78 changes: 78 additions & 0 deletions include/zephyr/linker/linker-devnull.h
Original file line number Diff line number Diff line change
@@ -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_ */

0 comments on commit dfb3674

Please sign in to comment.