Skip to content

Commit bc72fb6

Browse files
carlocaionenashif
authored andcommitted
linker: Create sections from zephyr,memory-region nodes
Currently when a node has a 'zephyr,memory-region' compatible and a 'zephyr,memory-region' string property, a new memory region is created in the linker script. Having a memory region without a section to place variables in could be not that useful. With this patch we extend the memory-region mechanism to also create sections. The user can then place variables in the sections as usual by using for example the GCC attributes. Signed-off-by: Carlo Caione <[email protected]>
1 parent 67ba990 commit bc72fb6

File tree

6 files changed

+92
-0
lines changed

6 files changed

+92
-0
lines changed

cmake/linker_script/arm/linker.cmake

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -195,3 +195,8 @@ zephyr_linker_section_configure(SECTION .data ANY FLAGS "+RW")
195195
zephyr_linker_section_configure(SECTION .bss ANY FLAGS "+ZI")
196196

197197
include(${COMMON_ZEPHYR_LINKER_DIR}/debug-sections.cmake)
198+
199+
dt_comp_path(paths COMPATIBLE "zephyr,memory-region")
200+
foreach(path IN LISTS paths)
201+
zephyr_linker_dts_section(PATH ${path})
202+
endforeach()

cmake/modules/extensions.cmake

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3333,6 +3333,53 @@ macro(zephyr_linker_memory_ifdef feature_toggle)
33333333
endif()
33343334
endmacro()
33353335

3336+
# Usage:
3337+
# zephyr_linker_dts_section(PATH <path>)
3338+
#
3339+
# Zephyr linker devicetree memory section from path.
3340+
#
3341+
# This function specifies an output section for the platform in use based on its
3342+
# devicetree configuration.
3343+
#
3344+
# The section will only be defined if the devicetree exists and has status okay.
3345+
#
3346+
# PATH <path> : Devicetree node path.
3347+
#
3348+
function(zephyr_linker_dts_section)
3349+
set(single_args "PATH")
3350+
cmake_parse_arguments(DTS_SECTION "" "${single_args}" "" ${ARGN})
3351+
3352+
if(DTS_SECTION_UNPARSED_ARGUMENTS)
3353+
message(FATAL_ERROR "zephyr_linker_dts_section(${ARGV0} ...) given unknown "
3354+
"arguments: ${DTS_SECTION_UNPARSED_ARGUMENTS}"
3355+
)
3356+
endif()
3357+
3358+
if(NOT DEFINED DTS_SECTION_PATH)
3359+
message(FATAL_ERROR "zephyr_linker_dts_section(${ARGV0} ...) missing "
3360+
"required argument: PATH"
3361+
)
3362+
endif()
3363+
3364+
dt_node_exists(exists PATH ${DTS_SECTION_PATH})
3365+
if(NOT ${exists})
3366+
return()
3367+
endif()
3368+
3369+
dt_prop(name PATH ${DTS_SECTION_PATH} PROPERTY "zephyr,memory-region")
3370+
if(NOT DEFINED name)
3371+
message(FATAL_ERROR "zephyr_linker_dts_section(${ARGV0} ...) missing "
3372+
"\"zephyr,memory-region\" property"
3373+
)
3374+
endif()
3375+
zephyr_string(SANITIZE name ${name})
3376+
3377+
dt_reg_addr(addr PATH ${DTS_SECTION_PATH})
3378+
3379+
zephyr_linker_section(NAME ${name} ADDRESS ${addr} VMA ${name} TYPE NOLOAD)
3380+
3381+
endfunction()
3382+
33363383
# Usage:
33373384
# zephyr_linker_dts_memory(PATH <path> FLAGS <flags>)
33383385
# zephyr_linker_dts_memory(NODELABEL <nodelabel> FLAGS <flags>)

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

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -383,6 +383,9 @@ GROUP_END(OCM)
383383
KEEP(*(.gnu.attributes))
384384
}
385385

386+
/* Sections generated from 'zephyr,memory-region' nodes */
387+
LINKER_DT_SECTIONS()
388+
386389
/* Must be last in romable region */
387390
SECTION_PROLOGUE(.last_section,(NOLOAD),)
388391
{

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

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -437,6 +437,9 @@ GROUP_END(DTCM)
437437
KEEP(*(.gnu.attributes))
438438
}
439439

440+
/* Sections generated from 'zephyr,memory-region' nodes */
441+
LINKER_DT_SECTIONS()
442+
440443
/* Must be last in romable region */
441444
SECTION_PROLOGUE(.last_section,(NOLOAD),)
442445
{

include/linker/devicetree_regions.h

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,13 @@
3939

4040
#define _DT_COMPATIBLE zephyr_memory_region
4141

42+
#define _DT_SECTION_NAME(node_id) DT_STRING_TOKEN(node_id, zephyr_memory_region)
43+
#define _DT_SECTION_PREFIX(node_id) UTIL_CAT(__, _DT_SECTION_NAME(node_id))
44+
#define _DT_SECTION_START(node_id) UTIL_CAT(_DT_SECTION_PREFIX(node_id), _start)
45+
#define _DT_SECTION_END(node_id) UTIL_CAT(_DT_SECTION_PREFIX(node_id), _end)
46+
#define _DT_SECTION_SIZE(node_id) UTIL_CAT(_DT_SECTION_PREFIX(node_id), _size)
47+
#define _DT_SECTION_LOAD(node_id) UTIL_CAT(_DT_SECTION_PREFIX(node_id), _load_start)
48+
4249
/**
4350
* @brief Declare a memory region
4451
*
@@ -50,6 +57,23 @@
5057
ORIGIN = DT_REG_ADDR(node_id), \
5158
LENGTH = DT_REG_SIZE(node_id)
5259

60+
/**
61+
* @brief Declare a memory section from the device tree nodes with
62+
* compatible 'zephyr,memory-region'
63+
*
64+
* @param node_id devicetree node identifier
65+
*/
66+
#define _SECTION_DECLARE(node_id) \
67+
_DT_SECTION_NAME(node_id) DT_REG_ADDR(node_id) (NOLOAD) : \
68+
{ \
69+
_DT_SECTION_START(node_id) = .; \
70+
KEEP(*(_DT_SECTION_NAME(node_id))) \
71+
KEEP(*(_DT_SECTION_NAME(node_id).*)) \
72+
_DT_SECTION_END(node_id) = .; \
73+
} > _DT_SECTION_NAME(node_id) \
74+
_DT_SECTION_SIZE(node_id) = _DT_SECTION_END(node_id) - _DT_SECTION_START(node_id); \
75+
_DT_SECTION_LOAD(node_id) = LOADADDR(_DT_SECTION_NAME(node_id));
76+
5377
/** @endcond */
5478

5579
/**
@@ -62,3 +86,10 @@
6286
*/
6387
#define LINKER_DT_REGIONS() \
6488
DT_FOREACH_STATUS_OKAY(_DT_COMPATIBLE, _REGION_DECLARE)
89+
90+
/**
91+
* @brief Generate linker memory sections from the device tree nodes with
92+
* compatible 'zephyr,memory-region'
93+
*/
94+
#define LINKER_DT_SECTIONS() \
95+
DT_FOREACH_STATUS_OKAY(_DT_COMPATIBLE, _SECTION_DECLARE)

scripts/dts/gen_dts_cmake.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,9 @@ def main():
148148
for path in compatible2paths[comp]:
149149
cmake_path = f'{cmake_path}{path};'
150150

151+
# Remove the last ';'
152+
cmake_path = cmake_path[:-1]
153+
151154
cmake_comp = f'DT_COMP|{comp}'
152155
cmake_props.append(f'"{cmake_comp}" "{cmake_path}"')
153156

0 commit comments

Comments
 (0)