2015-04-10 16:44:37 -07:00
|
|
|
/*
|
|
|
|
* Copyright (c) 2013-2014, Wind River Systems, Inc.
|
|
|
|
*
|
2017-01-18 17:01:01 -08:00
|
|
|
* SPDX-License-Identifier: Apache-2.0
|
2015-04-10 16:44:37 -07:00
|
|
|
*/
|
|
|
|
|
|
|
|
/*
|
2015-10-20 09:42:33 -07:00
|
|
|
* DESCRIPTION
|
|
|
|
* Platform independent, commonly used macros and defines related to linker
|
|
|
|
* script.
|
|
|
|
*
|
|
|
|
* This file may be included by:
|
|
|
|
* - Linker script files: for linker section declarations
|
|
|
|
* - C files: for external declaration of address or size of linker section
|
|
|
|
* - Assembly files: for external declaration of address or size of linker
|
|
|
|
* section
|
2015-07-01 17:22:39 -04:00
|
|
|
*/
|
2015-04-10 16:44:37 -07:00
|
|
|
|
2018-09-14 10:43:44 -07:00
|
|
|
#ifndef ZEPHYR_INCLUDE_LINKER_LINKER_DEFS_H_
|
|
|
|
#define ZEPHYR_INCLUDE_LINKER_LINKER_DEFS_H_
|
2015-04-10 16:44:37 -07:00
|
|
|
|
|
|
|
#include <toolchain.h>
|
2020-05-23 14:38:39 -07:00
|
|
|
#include <toolchain/common.h>
|
2017-06-17 11:30:47 -04:00
|
|
|
#include <linker/sections.h>
|
2019-06-26 10:33:55 -04:00
|
|
|
#include <sys/util.h>
|
2018-08-10 17:05:10 +02:00
|
|
|
#include <offsets.h>
|
2015-04-10 16:44:37 -07:00
|
|
|
|
2020-05-11 11:56:08 -07:00
|
|
|
/* We need to dummy out DT_NODE_HAS_STATUS when building the unittests.
|
|
|
|
* Including devicetree.h would require generating dummy header files
|
|
|
|
* to match what gen_defines creates, so it's easier to just dummy out
|
|
|
|
* DT_NODE_HAS_STATUS.
|
2020-04-23 17:51:08 -05:00
|
|
|
*/
|
|
|
|
#ifdef ZTEST_UNITTEST
|
2020-05-11 11:56:08 -07:00
|
|
|
#define DT_NODE_HAS_STATUS(node, status) 0
|
2020-04-23 17:51:08 -05:00
|
|
|
#else
|
2021-05-17 17:31:35 +02:00
|
|
|
#include <linker/devicetree_reserved.h>
|
2020-04-23 17:51:08 -05:00
|
|
|
#include <devicetree.h>
|
|
|
|
#endif
|
|
|
|
|
2015-04-10 16:44:37 -07:00
|
|
|
#ifdef _LINKER
|
2021-08-03 17:12:03 +01:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @addtogroup iterable_section_apis
|
|
|
|
* @{
|
|
|
|
*/
|
|
|
|
|
2020-05-23 14:38:39 -07:00
|
|
|
#define Z_LINK_ITERABLE(struct_type) \
|
|
|
|
_CONCAT(_##struct_type, _list_start) = .; \
|
2020-09-02 16:52:09 +03:00
|
|
|
KEEP(*(SORT_BY_NAME(._##struct_type.static.*))); \
|
2020-05-23 14:38:39 -07:00
|
|
|
_CONCAT(_##struct_type, _list_end) = .
|
|
|
|
|
2021-06-01 12:09:02 -03:00
|
|
|
#define Z_LINK_ITERABLE_ALIGNED(struct_type, align) \
|
|
|
|
. = ALIGN(align); \
|
|
|
|
Z_LINK_ITERABLE(struct_type);
|
|
|
|
|
2020-09-16 16:19:15 -07:00
|
|
|
#define Z_LINK_ITERABLE_GC_ALLOWED(struct_type) \
|
|
|
|
_CONCAT(_##struct_type, _list_start) = .; \
|
|
|
|
*(SORT_BY_NAME(._##struct_type.static.*)); \
|
|
|
|
_CONCAT(_##struct_type, _list_end) = .
|
|
|
|
|
2021-08-03 18:24:28 +01:00
|
|
|
/**
|
|
|
|
* @brief Define a read-only iterable section output.
|
|
|
|
*
|
|
|
|
* @details
|
|
|
|
* Define an output section which will set up an iterable area
|
|
|
|
* of equally-sized data structures. For use with STRUCT_SECTION_ITERABLE().
|
2020-05-23 14:38:39 -07:00
|
|
|
* Input sections will be sorted by name, per ld's SORT_BY_NAME.
|
|
|
|
*
|
|
|
|
* This macro should be used for read-only data.
|
2020-09-16 16:19:15 -07:00
|
|
|
*
|
|
|
|
* Note that this keeps the symbols in the image even though
|
|
|
|
* they are not being directly referenced. Use this when symbols
|
|
|
|
* are indirectly referenced by iterating through the section.
|
2020-05-23 14:38:39 -07:00
|
|
|
*/
|
2021-08-03 18:24:28 +01:00
|
|
|
#define ITERABLE_SECTION_ROM(struct_type, subalign) \
|
2020-05-23 14:38:39 -07:00
|
|
|
SECTION_PROLOGUE(struct_type##_area,,SUBALIGN(subalign)) \
|
|
|
|
{ \
|
|
|
|
Z_LINK_ITERABLE(struct_type); \
|
2021-03-06 17:44:44 -08:00
|
|
|
} GROUP_ROM_LINK_IN(RAMABLE_REGION, ROMABLE_REGION)
|
2020-05-23 14:38:39 -07:00
|
|
|
|
2021-08-04 19:28:46 +01:00
|
|
|
#define Z_ITERABLE_SECTION_ROM(struct_type, subalign) \
|
|
|
|
ITERABLE_SECTION_ROM(struct_type, subalign)
|
|
|
|
|
2021-08-03 18:24:28 +01:00
|
|
|
/**
|
|
|
|
* @brief Define a garbage collectable read-only iterable section output.
|
|
|
|
*
|
|
|
|
* @details
|
|
|
|
* Define an output section which will set up an iterable area
|
|
|
|
* of equally-sized data structures. For use with STRUCT_SECTION_ITERABLE().
|
2020-09-16 16:19:15 -07:00
|
|
|
* Input sections will be sorted by name, per ld's SORT_BY_NAME.
|
|
|
|
*
|
|
|
|
* This macro should be used for read-only data.
|
|
|
|
*
|
|
|
|
* Note that the symbols within the section can be garbage collected.
|
|
|
|
*/
|
2021-08-03 18:24:28 +01:00
|
|
|
#define ITERABLE_SECTION_ROM_GC_ALLOWED(struct_type, subalign) \
|
2020-09-16 16:19:15 -07:00
|
|
|
SECTION_PROLOGUE(struct_type##_area,,SUBALIGN(subalign)) \
|
|
|
|
{ \
|
|
|
|
Z_LINK_ITERABLE_GC_ALLOWED(struct_type); \
|
|
|
|
} GROUP_LINK_IN(ROMABLE_REGION)
|
|
|
|
|
2021-08-04 19:28:46 +01:00
|
|
|
#define Z_ITERABLE_SECTION_ROM_GC_ALLOWED(struct_type, subalign) \
|
|
|
|
ITERABLE_SECTION_ROM_GC_ALLOWED(struct_type, subalign)
|
|
|
|
|
2021-08-03 18:24:28 +01:00
|
|
|
/**
|
|
|
|
* @brief Define a read-write iterable section output.
|
|
|
|
*
|
|
|
|
* @details
|
|
|
|
* Define an output section which will set up an iterable area
|
|
|
|
* of equally-sized data structures. For use with STRUCT_SECTION_ITERABLE().
|
2020-05-23 14:38:39 -07:00
|
|
|
* Input sections will be sorted by name, per ld's SORT_BY_NAME.
|
|
|
|
*
|
|
|
|
* This macro should be used for read-write data that is modified at runtime.
|
2020-09-16 16:19:15 -07:00
|
|
|
*
|
|
|
|
* Note that this keeps the symbols in the image even though
|
|
|
|
* they are not being directly referenced. Use this when symbols
|
|
|
|
* are indirectly referenced by iterating through the section.
|
2020-05-23 14:38:39 -07:00
|
|
|
*/
|
2021-08-03 18:24:28 +01:00
|
|
|
#define ITERABLE_SECTION_RAM(struct_type, subalign) \
|
2020-05-23 14:38:39 -07:00
|
|
|
SECTION_DATA_PROLOGUE(struct_type##_area,,SUBALIGN(subalign)) \
|
|
|
|
{ \
|
|
|
|
Z_LINK_ITERABLE(struct_type); \
|
|
|
|
} GROUP_DATA_LINK_IN(RAMABLE_REGION, ROMABLE_REGION)
|
|
|
|
|
2021-08-04 19:28:46 +01:00
|
|
|
#define Z_ITERABLE_SECTION_RAM(struct_type, subalign) \
|
|
|
|
ITERABLE_SECTION_RAM(struct_type, subalign)
|
2020-09-16 16:19:15 -07:00
|
|
|
|
2021-08-03 18:24:28 +01:00
|
|
|
/**
|
|
|
|
* @brief Define a garbage collectable read-write iterable section output.
|
|
|
|
*
|
|
|
|
* @details
|
|
|
|
* Define an output section which will set up an iterable area
|
|
|
|
* of equally-sized data structures. For use with STRUCT_SECTION_ITERABLE().
|
2020-09-16 16:19:15 -07:00
|
|
|
* Input sections will be sorted by name, per ld's SORT_BY_NAME.
|
|
|
|
*
|
|
|
|
* This macro should be used for read-write data that is modified at runtime.
|
|
|
|
*
|
|
|
|
* Note that the symbols within the section can be garbage collected.
|
|
|
|
*/
|
2021-08-03 18:24:28 +01:00
|
|
|
#define ITERABLE_SECTION_RAM_GC_ALLOWED(struct_type, subalign) \
|
2020-09-16 16:19:15 -07:00
|
|
|
SECTION_DATA_PROLOGUE(struct_type##_area,,SUBALIGN(subalign)) \
|
|
|
|
{ \
|
|
|
|
Z_LINK_ITERABLE_GC_ALLOWED(struct_type); \
|
|
|
|
} GROUP_DATA_LINK_IN(RAMABLE_REGION, ROMABLE_REGION)
|
|
|
|
|
2021-08-04 19:28:46 +01:00
|
|
|
#define Z_ITERABLE_SECTION_RAM_GC_ALLOWED(struct_type, subalign) \
|
|
|
|
ITERABLE_SECTION_RAM_GC_ALLOWED(struct_type, subalign)
|
|
|
|
|
2021-08-03 17:12:03 +01:00
|
|
|
/**
|
|
|
|
* @}
|
|
|
|
*/ /* end of struct_section_apis */
|
|
|
|
|
2015-10-14 11:17:20 -04:00
|
|
|
/*
|
2020-03-09 11:02:20 +01:00
|
|
|
* generate a symbol to mark the start of the objects array for
|
|
|
|
* the specified object and level, then link all of those objects
|
|
|
|
* (sorted by priority). Ensure the objects aren't discarded if there is
|
|
|
|
* no direct reference to them
|
2015-10-14 11:17:20 -04:00
|
|
|
*/
|
2020-03-09 11:02:20 +01:00
|
|
|
#define CREATE_OBJ_LEVEL(object, level) \
|
|
|
|
__##object##_##level##_start = .; \
|
2021-04-23 15:55:53 +03:00
|
|
|
KEEP(*(SORT(.z_##object##_##level[0-9]_*))); \
|
|
|
|
KEEP(*(SORT(.z_##object##_##level[1-9][0-9]_*)));
|
2016-07-31 16:16:29 +03:00
|
|
|
|
2018-05-16 08:50:33 +02:00
|
|
|
/*
|
|
|
|
* link in shell initialization objects for all modules that use shell and
|
|
|
|
* their shell commands are automatically initialized by the kernel.
|
|
|
|
*/
|
|
|
|
|
2015-04-10 16:44:37 -07:00
|
|
|
#elif defined(_ASMLANGUAGE)
|
2015-10-14 11:17:20 -04:00
|
|
|
|
2015-04-10 16:44:37 -07:00
|
|
|
/* Assembly FILES: declaration defined by the linker script */
|
|
|
|
GDATA(__bss_start)
|
|
|
|
GDATA(__bss_num_words)
|
|
|
|
#ifdef CONFIG_XIP
|
2021-05-21 21:21:52 +02:00
|
|
|
GDATA(__data_region_load_start)
|
|
|
|
GDATA(__data_region_start)
|
|
|
|
GDATA(__data_region_num_words)
|
2015-04-10 16:44:37 -07:00
|
|
|
#endif
|
|
|
|
|
2015-10-14 11:17:20 -04:00
|
|
|
#else /* ! _ASMLANGUAGE */
|
2015-04-10 16:44:37 -07:00
|
|
|
|
Introduce new sized integer typedefs
This is a start to move away from the C99 {u}int{8,16,32,64}_t types to
Zephyr defined u{8,16,32,64}_t and s{8,16,32,64}_t. This allows Zephyr
to define the sized types in a consistent manor across all the
architectures we support and not conflict with what various compilers
and libc might do with regards to the C99 types.
We introduce <zephyr/types.h> as part of this and have it include
<stdint.h> for now until we transition all the code away from the C99
types.
We go with u{8,16,32,64}_t and s{8,16,32,64}_t as there are some
existing variables defined u8 & u16 as well as to be consistent with
Zephyr naming conventions.
Jira: ZEP-2051
Change-Id: I451fed0623b029d65866622e478225dfab2c0ca8
Signed-off-by: Kumar Gala <kumar.gala@linaro.org>
2017-04-19 10:32:08 -05:00
|
|
|
#include <zephyr/types.h>
|
userspace: compartmentalized app memory organization
Summary: revised attempt at addressing issue 6290. The
following provides an alternative to using
CONFIG_APPLICATION_MEMORY by compartmentalizing data into
Memory Domains. Dependent on MPU limitations, supports
compartmentalized Memory Domains for 1...N logical
applications. This is considered an initial attempt at
designing flexible compartmentalized Memory Domains for
multiple logical applications and, with the provided python
script and edited CMakeLists.txt, provides support for power
of 2 aligned MPU architectures.
Overview: The current patch uses qualifiers to group data into
subsections. The qualifier usage allows for dynamic subsection
creation and affords the developer a large amount of flexibility
in the grouping, naming, and size of the resulting partitions and
domains that are built on these subsections. By additional macro
calls, functions are created that help calculate the size,
address, and permissions for the subsections and enable the
developer to control application data in specified partitions and
memory domains.
Background: Initial attempts focused on creating a single
section in the linker script that then contained internally
grouped variables/data to allow MPU/MMU alignment and protection.
This did not provide additional functionality beyond
CONFIG_APPLICATION_MEMORY as we were unable to reliably group
data or determine their grouping via exported linker symbols.
Thus, the resulting decision was made to dynamically create
subsections using the current qualifier method. An attempt to
group the data by object file was tested, but found that this
broke applications such as ztest where two object files are
created: ztest and main. This also creates an issue of grouping
the two object files together in the same memory domain while
also allowing for compartmenting other data among threads.
Because it is not possible to know a) the name of the partition
and thus the symbol in the linker, b) the size of all the data
in the subsection, nor c) the overall number of partitions
created by the developer, it was not feasible to align the
subsections at compile time without using dynamically generated
linker script for MPU architectures requiring power of 2
alignment.
In order to provide support for MPU architectures that require a
power of 2 alignment, a python script is run at build prior to
when linker_priv_stacks.cmd is generated. This script scans the
built object files for all possible partitions and the names given
to them. It then generates a linker file (app_smem.ld) that is
included in the main linker.ld file. This app_smem.ld allows the
compiler and linker to then create each subsection and align to
the next power of 2.
Usage:
- Requires: app_memory/app_memdomain.h .
- _app_dmem(id) marks a variable to be placed into a data
section for memory partition id.
- _app_bmem(id) marks a variable to be placed into a bss
section for memory partition id.
- These are seen in the linker.map as "data_smem_id" and
"data_smem_idb".
- To create a k_mem_partition, call the macro
app_mem_partition(part0) where "part0" is the name then used to
refer to that partition. This macro only creates a function and
necessary data structures for the later "initialization".
- To create a memory domain for the partition, the macro
app_mem_domain(dom0) is called where "dom0" is the name then
used for the memory domain.
- To initialize the partition (effectively adding the partition
to a linked list), init_part_part0() is called. This is followed
by init_app_memory(), which walks all partitions in the linked
list and calculates the sizes for each partition.
- Once the partition is initialized, the domain can be
initialized with init_domain_dom0(part0) which initializes the
domain with partition part0.
- After the domain has been initialized, the current thread
can be added using add_thread_dom0(k_current_get()).
- The code used in ztests ans kernel/init has been added under
a conditional #ifdef to isolate the code from other tests.
The userspace test CMakeLists.txt file has commands to insert
the CONFIG_APP_SHARED_MEM definition into the required build
targets.
Example:
/* create partition at top of file outside functions */
app_mem_partition(part0);
/* create domain */
app_mem_domain(dom0);
_app_dmem(dom0) int var1;
_app_bmem(dom0) static volatile int var2;
int main()
{
init_part_part0();
init_app_memory();
init_domain_dom0(part0);
add_thread_dom0(k_current_get());
...
}
- If multiple partitions are being created, a variadic
preprocessor macro can be used as provided in
app_macro_support.h:
FOR_EACH(app_mem_partition, part0, part1, part2);
or, for multiple domains, similarly:
FOR_EACH(app_mem_domain, dom0, dom1);
Similarly, the init_part_* can also be used in the macro:
FOR_EACH(init_part, part0, part1, part2);
Testing:
- This has been successfully tested on qemu_x86 and the
ARM frdm_k64f board. It compiles and builds power of 2
aligned subsections for the linker script on the 96b_carbon
boards. These power of 2 alignments have been checked by
hand and are viewable in the zephyr.map file that is
produced during build. However, due to a shortage of
available MPU regions on the 96b_carbon board, we are unable
to test this.
- When run on the 96b_carbon board, the test suite will
enter execution, but each individaul test will fail due to
an MPU FAULT. This is expected as the required number of
MPU regions exceeds the number allowed due to the static
allocation. As the MPU driver does not detect this issue,
the fault occurs because the data being accessed has been
placed outside the active MPU region.
- This now compiles successfully for the ARC boards
em_starterkit_em7d and em_starterkit_em7d_v22. However,
as we lack ARC hardware to run this build on, we are unable
to test this build.
Current known issues:
1) While the script and edited CMakeLists.txt creates the
ability to align to the next power of 2, this does not
address the shortage of available MPU regions on certain
devices (e.g. 96b_carbon). In testing the APB and PPB
regions were commented out.
2) checkpatch.pl lists several issues regarding the
following:
a) Complex macros. The FOR_EACH macros as defined in
app_macro_support.h are listed as complex macros needing
parentheses. Adding parentheses breaks their
functionality, and we have otherwise been unable to
resolve the reported error.
b) __aligned() preferred. The _app_dmem_pad() and
_app_bmem_pad() macros give warnings that __aligned()
is preferred. Prior iterations had this implementation,
which resulted in errors due to "complex macros".
c) Trailing semicolon. The macro init_part(name) has
a trailing semicolon as the semicolon is needed for the
inlined macro call that is generated when this macro
expands.
Update: updated to alternative CONFIG_APPLCATION_MEMORY.
Added config option CONFIG_APP_SHARED_MEM to enable a new section
app_smem to contain the shared memory component. This commit
seperates the Kconfig definition from the definition used for the
conditional code. The change is in response to changes in the
way the build system treats definitions. The python script used
to generate a linker script for app_smem was also midified to
simplify the alignment directives. A default linker script
app_smem.ld was added to remove the conditional includes dependency
on CONFIG_APP_SHARED_MEM. By addining the default linker script
the prebuild stages link properly prior to the python script running
Signed-off-by: Joshua Domagalski <jedomag@tycho.nsa.gov>
Signed-off-by: Shawn Mosley <smmosle@tycho.nsa.gov>
2018-04-26 10:14:02 -04:00
|
|
|
/*
|
2018-11-06 11:46:05 +01:00
|
|
|
* Memory owned by the kernel, to be used as shared memory between
|
|
|
|
* application threads.
|
|
|
|
*
|
|
|
|
* The following are extern symbols from the linker. This enables
|
userspace: compartmentalized app memory organization
Summary: revised attempt at addressing issue 6290. The
following provides an alternative to using
CONFIG_APPLICATION_MEMORY by compartmentalizing data into
Memory Domains. Dependent on MPU limitations, supports
compartmentalized Memory Domains for 1...N logical
applications. This is considered an initial attempt at
designing flexible compartmentalized Memory Domains for
multiple logical applications and, with the provided python
script and edited CMakeLists.txt, provides support for power
of 2 aligned MPU architectures.
Overview: The current patch uses qualifiers to group data into
subsections. The qualifier usage allows for dynamic subsection
creation and affords the developer a large amount of flexibility
in the grouping, naming, and size of the resulting partitions and
domains that are built on these subsections. By additional macro
calls, functions are created that help calculate the size,
address, and permissions for the subsections and enable the
developer to control application data in specified partitions and
memory domains.
Background: Initial attempts focused on creating a single
section in the linker script that then contained internally
grouped variables/data to allow MPU/MMU alignment and protection.
This did not provide additional functionality beyond
CONFIG_APPLICATION_MEMORY as we were unable to reliably group
data or determine their grouping via exported linker symbols.
Thus, the resulting decision was made to dynamically create
subsections using the current qualifier method. An attempt to
group the data by object file was tested, but found that this
broke applications such as ztest where two object files are
created: ztest and main. This also creates an issue of grouping
the two object files together in the same memory domain while
also allowing for compartmenting other data among threads.
Because it is not possible to know a) the name of the partition
and thus the symbol in the linker, b) the size of all the data
in the subsection, nor c) the overall number of partitions
created by the developer, it was not feasible to align the
subsections at compile time without using dynamically generated
linker script for MPU architectures requiring power of 2
alignment.
In order to provide support for MPU architectures that require a
power of 2 alignment, a python script is run at build prior to
when linker_priv_stacks.cmd is generated. This script scans the
built object files for all possible partitions and the names given
to them. It then generates a linker file (app_smem.ld) that is
included in the main linker.ld file. This app_smem.ld allows the
compiler and linker to then create each subsection and align to
the next power of 2.
Usage:
- Requires: app_memory/app_memdomain.h .
- _app_dmem(id) marks a variable to be placed into a data
section for memory partition id.
- _app_bmem(id) marks a variable to be placed into a bss
section for memory partition id.
- These are seen in the linker.map as "data_smem_id" and
"data_smem_idb".
- To create a k_mem_partition, call the macro
app_mem_partition(part0) where "part0" is the name then used to
refer to that partition. This macro only creates a function and
necessary data structures for the later "initialization".
- To create a memory domain for the partition, the macro
app_mem_domain(dom0) is called where "dom0" is the name then
used for the memory domain.
- To initialize the partition (effectively adding the partition
to a linked list), init_part_part0() is called. This is followed
by init_app_memory(), which walks all partitions in the linked
list and calculates the sizes for each partition.
- Once the partition is initialized, the domain can be
initialized with init_domain_dom0(part0) which initializes the
domain with partition part0.
- After the domain has been initialized, the current thread
can be added using add_thread_dom0(k_current_get()).
- The code used in ztests ans kernel/init has been added under
a conditional #ifdef to isolate the code from other tests.
The userspace test CMakeLists.txt file has commands to insert
the CONFIG_APP_SHARED_MEM definition into the required build
targets.
Example:
/* create partition at top of file outside functions */
app_mem_partition(part0);
/* create domain */
app_mem_domain(dom0);
_app_dmem(dom0) int var1;
_app_bmem(dom0) static volatile int var2;
int main()
{
init_part_part0();
init_app_memory();
init_domain_dom0(part0);
add_thread_dom0(k_current_get());
...
}
- If multiple partitions are being created, a variadic
preprocessor macro can be used as provided in
app_macro_support.h:
FOR_EACH(app_mem_partition, part0, part1, part2);
or, for multiple domains, similarly:
FOR_EACH(app_mem_domain, dom0, dom1);
Similarly, the init_part_* can also be used in the macro:
FOR_EACH(init_part, part0, part1, part2);
Testing:
- This has been successfully tested on qemu_x86 and the
ARM frdm_k64f board. It compiles and builds power of 2
aligned subsections for the linker script on the 96b_carbon
boards. These power of 2 alignments have been checked by
hand and are viewable in the zephyr.map file that is
produced during build. However, due to a shortage of
available MPU regions on the 96b_carbon board, we are unable
to test this.
- When run on the 96b_carbon board, the test suite will
enter execution, but each individaul test will fail due to
an MPU FAULT. This is expected as the required number of
MPU regions exceeds the number allowed due to the static
allocation. As the MPU driver does not detect this issue,
the fault occurs because the data being accessed has been
placed outside the active MPU region.
- This now compiles successfully for the ARC boards
em_starterkit_em7d and em_starterkit_em7d_v22. However,
as we lack ARC hardware to run this build on, we are unable
to test this build.
Current known issues:
1) While the script and edited CMakeLists.txt creates the
ability to align to the next power of 2, this does not
address the shortage of available MPU regions on certain
devices (e.g. 96b_carbon). In testing the APB and PPB
regions were commented out.
2) checkpatch.pl lists several issues regarding the
following:
a) Complex macros. The FOR_EACH macros as defined in
app_macro_support.h are listed as complex macros needing
parentheses. Adding parentheses breaks their
functionality, and we have otherwise been unable to
resolve the reported error.
b) __aligned() preferred. The _app_dmem_pad() and
_app_bmem_pad() macros give warnings that __aligned()
is preferred. Prior iterations had this implementation,
which resulted in errors due to "complex macros".
c) Trailing semicolon. The macro init_part(name) has
a trailing semicolon as the semicolon is needed for the
inlined macro call that is generated when this macro
expands.
Update: updated to alternative CONFIG_APPLCATION_MEMORY.
Added config option CONFIG_APP_SHARED_MEM to enable a new section
app_smem to contain the shared memory component. This commit
seperates the Kconfig definition from the definition used for the
conditional code. The change is in response to changes in the
way the build system treats definitions. The python script used
to generate a linker script for app_smem was also midified to
simplify the alignment directives. A default linker script
app_smem.ld was added to remove the conditional includes dependency
on CONFIG_APP_SHARED_MEM. By addining the default linker script
the prebuild stages link properly prior to the python script running
Signed-off-by: Joshua Domagalski <jedomag@tycho.nsa.gov>
Signed-off-by: Shawn Mosley <smmosle@tycho.nsa.gov>
2018-04-26 10:14:02 -04:00
|
|
|
* the dynamic k_mem_domain and k_mem_partition creation and alignment
|
|
|
|
* to the section produced in the linker.
|
2018-11-06 11:46:05 +01:00
|
|
|
|
|
|
|
* The policy for this memory will be to initially configure all of it as
|
|
|
|
* kernel / supervisor thread accessible.
|
userspace: compartmentalized app memory organization
Summary: revised attempt at addressing issue 6290. The
following provides an alternative to using
CONFIG_APPLICATION_MEMORY by compartmentalizing data into
Memory Domains. Dependent on MPU limitations, supports
compartmentalized Memory Domains for 1...N logical
applications. This is considered an initial attempt at
designing flexible compartmentalized Memory Domains for
multiple logical applications and, with the provided python
script and edited CMakeLists.txt, provides support for power
of 2 aligned MPU architectures.
Overview: The current patch uses qualifiers to group data into
subsections. The qualifier usage allows for dynamic subsection
creation and affords the developer a large amount of flexibility
in the grouping, naming, and size of the resulting partitions and
domains that are built on these subsections. By additional macro
calls, functions are created that help calculate the size,
address, and permissions for the subsections and enable the
developer to control application data in specified partitions and
memory domains.
Background: Initial attempts focused on creating a single
section in the linker script that then contained internally
grouped variables/data to allow MPU/MMU alignment and protection.
This did not provide additional functionality beyond
CONFIG_APPLICATION_MEMORY as we were unable to reliably group
data or determine their grouping via exported linker symbols.
Thus, the resulting decision was made to dynamically create
subsections using the current qualifier method. An attempt to
group the data by object file was tested, but found that this
broke applications such as ztest where two object files are
created: ztest and main. This also creates an issue of grouping
the two object files together in the same memory domain while
also allowing for compartmenting other data among threads.
Because it is not possible to know a) the name of the partition
and thus the symbol in the linker, b) the size of all the data
in the subsection, nor c) the overall number of partitions
created by the developer, it was not feasible to align the
subsections at compile time without using dynamically generated
linker script for MPU architectures requiring power of 2
alignment.
In order to provide support for MPU architectures that require a
power of 2 alignment, a python script is run at build prior to
when linker_priv_stacks.cmd is generated. This script scans the
built object files for all possible partitions and the names given
to them. It then generates a linker file (app_smem.ld) that is
included in the main linker.ld file. This app_smem.ld allows the
compiler and linker to then create each subsection and align to
the next power of 2.
Usage:
- Requires: app_memory/app_memdomain.h .
- _app_dmem(id) marks a variable to be placed into a data
section for memory partition id.
- _app_bmem(id) marks a variable to be placed into a bss
section for memory partition id.
- These are seen in the linker.map as "data_smem_id" and
"data_smem_idb".
- To create a k_mem_partition, call the macro
app_mem_partition(part0) where "part0" is the name then used to
refer to that partition. This macro only creates a function and
necessary data structures for the later "initialization".
- To create a memory domain for the partition, the macro
app_mem_domain(dom0) is called where "dom0" is the name then
used for the memory domain.
- To initialize the partition (effectively adding the partition
to a linked list), init_part_part0() is called. This is followed
by init_app_memory(), which walks all partitions in the linked
list and calculates the sizes for each partition.
- Once the partition is initialized, the domain can be
initialized with init_domain_dom0(part0) which initializes the
domain with partition part0.
- After the domain has been initialized, the current thread
can be added using add_thread_dom0(k_current_get()).
- The code used in ztests ans kernel/init has been added under
a conditional #ifdef to isolate the code from other tests.
The userspace test CMakeLists.txt file has commands to insert
the CONFIG_APP_SHARED_MEM definition into the required build
targets.
Example:
/* create partition at top of file outside functions */
app_mem_partition(part0);
/* create domain */
app_mem_domain(dom0);
_app_dmem(dom0) int var1;
_app_bmem(dom0) static volatile int var2;
int main()
{
init_part_part0();
init_app_memory();
init_domain_dom0(part0);
add_thread_dom0(k_current_get());
...
}
- If multiple partitions are being created, a variadic
preprocessor macro can be used as provided in
app_macro_support.h:
FOR_EACH(app_mem_partition, part0, part1, part2);
or, for multiple domains, similarly:
FOR_EACH(app_mem_domain, dom0, dom1);
Similarly, the init_part_* can also be used in the macro:
FOR_EACH(init_part, part0, part1, part2);
Testing:
- This has been successfully tested on qemu_x86 and the
ARM frdm_k64f board. It compiles and builds power of 2
aligned subsections for the linker script on the 96b_carbon
boards. These power of 2 alignments have been checked by
hand and are viewable in the zephyr.map file that is
produced during build. However, due to a shortage of
available MPU regions on the 96b_carbon board, we are unable
to test this.
- When run on the 96b_carbon board, the test suite will
enter execution, but each individaul test will fail due to
an MPU FAULT. This is expected as the required number of
MPU regions exceeds the number allowed due to the static
allocation. As the MPU driver does not detect this issue,
the fault occurs because the data being accessed has been
placed outside the active MPU region.
- This now compiles successfully for the ARC boards
em_starterkit_em7d and em_starterkit_em7d_v22. However,
as we lack ARC hardware to run this build on, we are unable
to test this build.
Current known issues:
1) While the script and edited CMakeLists.txt creates the
ability to align to the next power of 2, this does not
address the shortage of available MPU regions on certain
devices (e.g. 96b_carbon). In testing the APB and PPB
regions were commented out.
2) checkpatch.pl lists several issues regarding the
following:
a) Complex macros. The FOR_EACH macros as defined in
app_macro_support.h are listed as complex macros needing
parentheses. Adding parentheses breaks their
functionality, and we have otherwise been unable to
resolve the reported error.
b) __aligned() preferred. The _app_dmem_pad() and
_app_bmem_pad() macros give warnings that __aligned()
is preferred. Prior iterations had this implementation,
which resulted in errors due to "complex macros".
c) Trailing semicolon. The macro init_part(name) has
a trailing semicolon as the semicolon is needed for the
inlined macro call that is generated when this macro
expands.
Update: updated to alternative CONFIG_APPLCATION_MEMORY.
Added config option CONFIG_APP_SHARED_MEM to enable a new section
app_smem to contain the shared memory component. This commit
seperates the Kconfig definition from the definition used for the
conditional code. The change is in response to changes in the
way the build system treats definitions. The python script used
to generate a linker script for app_smem was also midified to
simplify the alignment directives. A default linker script
app_smem.ld was added to remove the conditional includes dependency
on CONFIG_APP_SHARED_MEM. By addining the default linker script
the prebuild stages link properly prior to the python script running
Signed-off-by: Joshua Domagalski <jedomag@tycho.nsa.gov>
Signed-off-by: Shawn Mosley <smmosle@tycho.nsa.gov>
2018-04-26 10:14:02 -04:00
|
|
|
*/
|
|
|
|
extern char _app_smem_start[];
|
|
|
|
extern char _app_smem_end[];
|
|
|
|
extern char _app_smem_size[];
|
|
|
|
extern char _app_smem_rom_start[];
|
2018-12-20 15:34:04 +05:30
|
|
|
extern char _app_smem_num_words[];
|
2017-06-14 13:31:11 -07:00
|
|
|
|
2021-07-12 13:33:32 -07:00
|
|
|
#ifdef CONFIG_LINKER_USE_PINNED_SECTION
|
|
|
|
extern char _app_smem_pinned_start[];
|
|
|
|
extern char _app_smem_pinned_end[];
|
|
|
|
extern char _app_smem_pinned_size[];
|
|
|
|
extern char _app_smem_pinned_num_words[];
|
|
|
|
#endif
|
|
|
|
|
2017-08-01 15:13:44 -07:00
|
|
|
/* Memory owned by the kernel. Start and end will be aligned for memory
|
2018-11-06 11:46:05 +01:00
|
|
|
* management/protection hardware for the target architecture.
|
2017-08-01 15:13:44 -07:00
|
|
|
*
|
|
|
|
* Consists of all kernel-side globals, all kernel objects, all thread stacks,
|
2019-01-31 15:53:24 -08:00
|
|
|
* and all currently unused RAM.
|
2017-08-01 15:13:44 -07:00
|
|
|
*
|
|
|
|
* Except for the stack of the currently executing thread, none of this memory
|
|
|
|
* is normally accessible to user threads unless specifically granted at
|
|
|
|
* runtime.
|
|
|
|
*/
|
2017-06-19 11:13:19 -07:00
|
|
|
extern char __kernel_ram_start[];
|
|
|
|
extern char __kernel_ram_end[];
|
2017-08-01 15:13:44 -07:00
|
|
|
extern char __kernel_ram_size[];
|
2017-06-19 11:13:19 -07:00
|
|
|
|
2019-03-08 14:19:05 -07:00
|
|
|
/* Used by z_bss_zero or arch-specific implementation */
|
2015-04-10 16:44:37 -07:00
|
|
|
extern char __bss_start[];
|
2016-06-30 16:45:08 -07:00
|
|
|
extern char __bss_end[];
|
2017-06-14 13:31:11 -07:00
|
|
|
|
2019-03-08 14:19:05 -07:00
|
|
|
/* Used by z_data_copy() or arch-specific implementation */
|
2015-04-10 16:44:37 -07:00
|
|
|
#ifdef CONFIG_XIP
|
2021-05-21 21:21:52 +02:00
|
|
|
extern char __data_region_load_start[];
|
|
|
|
extern char __data_region_start[];
|
|
|
|
extern char __data_region_end[];
|
2017-06-19 11:13:19 -07:00
|
|
|
#endif /* CONFIG_XIP */
|
2015-04-10 16:44:37 -07:00
|
|
|
|
2020-12-10 12:33:12 -08:00
|
|
|
#ifdef CONFIG_MMU
|
|
|
|
/* Virtual addresses of page-aligned kernel image mapped into RAM at boot */
|
|
|
|
extern char z_mapped_start[];
|
|
|
|
extern char z_mapped_end[];
|
|
|
|
#endif /* CONFIG_MMU */
|
|
|
|
|
2017-07-11 08:58:43 -07:00
|
|
|
/* Includes text and rodata */
|
2021-08-09 18:16:51 +02:00
|
|
|
extern char __rom_region_start[];
|
|
|
|
extern char __rom_region_end[];
|
|
|
|
extern char __rom_region_size[];
|
2017-07-11 08:58:43 -07:00
|
|
|
|
2018-11-29 12:12:19 +00:00
|
|
|
/* Includes all ROMable data, i.e. the size of the output image file. */
|
|
|
|
extern char _flash_used[];
|
|
|
|
|
2017-07-11 08:58:43 -07:00
|
|
|
/* datas, bss, noinit */
|
2015-09-16 19:14:40 -04:00
|
|
|
extern char _image_ram_start[];
|
|
|
|
extern char _image_ram_end[];
|
2017-07-11 08:58:43 -07:00
|
|
|
|
2021-08-09 21:24:02 +02:00
|
|
|
extern char __text_region_start[];
|
|
|
|
extern char __text_region_end[];
|
|
|
|
extern char __text_region_size[];
|
2015-09-16 19:14:40 -04:00
|
|
|
|
2021-08-09 18:16:51 +02:00
|
|
|
extern char __rodata_region_start[];
|
|
|
|
extern char __rodata_region_end[];
|
|
|
|
extern char __rodata_region_size[];
|
2017-07-11 08:58:43 -07:00
|
|
|
|
2017-06-23 11:02:50 +08:00
|
|
|
extern char _vector_start[];
|
|
|
|
extern char _vector_end[];
|
|
|
|
|
2021-05-17 17:31:35 +02:00
|
|
|
#if DT_NODE_HAS_STATUS(_NODE_RESERVED, okay)
|
|
|
|
DT_RESERVED_MEM_SYMBOLS()
|
|
|
|
#endif
|
|
|
|
|
2020-05-13 14:01:55 +02:00
|
|
|
#ifdef CONFIG_SW_VECTOR_RELAY
|
|
|
|
extern char __vector_relay_table[];
|
|
|
|
#endif
|
|
|
|
|
2018-08-31 15:09:26 +05:30
|
|
|
#ifdef CONFIG_COVERAGE_GCOV
|
|
|
|
extern char __gcov_bss_start[];
|
|
|
|
extern char __gcov_bss_end[];
|
|
|
|
extern char __gcov_bss_size[];
|
|
|
|
#endif /* CONFIG_COVERAGE_GCOV */
|
|
|
|
|
2017-06-14 13:31:11 -07:00
|
|
|
/* end address of image, used by newlib for the heap */
|
2015-04-10 16:44:37 -07:00
|
|
|
extern char _end[];
|
|
|
|
|
2020-05-11 11:56:08 -07:00
|
|
|
#if DT_NODE_HAS_STATUS(DT_CHOSEN(zephyr_ccm), okay)
|
2017-10-05 01:20:21 +02:00
|
|
|
extern char __ccm_data_rom_start[];
|
|
|
|
extern char __ccm_start[];
|
|
|
|
extern char __ccm_data_start[];
|
|
|
|
extern char __ccm_data_end[];
|
|
|
|
extern char __ccm_bss_start[];
|
|
|
|
extern char __ccm_bss_end[];
|
|
|
|
extern char __ccm_noinit_start[];
|
|
|
|
extern char __ccm_noinit_end[];
|
|
|
|
extern char __ccm_end[];
|
2020-04-23 17:55:58 -05:00
|
|
|
#endif
|
2017-10-05 01:20:21 +02:00
|
|
|
|
2021-01-06 08:52:28 -06:00
|
|
|
#if DT_NODE_HAS_STATUS(DT_CHOSEN(zephyr_itcm), okay)
|
|
|
|
extern char __itcm_start[];
|
|
|
|
extern char __itcm_end[];
|
|
|
|
extern char __itcm_size[];
|
|
|
|
extern char __itcm_rom_start[];
|
|
|
|
#endif
|
|
|
|
|
2020-05-11 11:56:08 -07:00
|
|
|
#if DT_NODE_HAS_STATUS(DT_CHOSEN(zephyr_dtcm), okay)
|
2019-07-03 14:19:29 +02:00
|
|
|
extern char __dtcm_data_start[];
|
|
|
|
extern char __dtcm_data_end[];
|
|
|
|
extern char __dtcm_bss_start[];
|
|
|
|
extern char __dtcm_bss_end[];
|
|
|
|
extern char __dtcm_noinit_start[];
|
|
|
|
extern char __dtcm_noinit_end[];
|
|
|
|
extern char __dtcm_data_rom_start[];
|
|
|
|
extern char __dtcm_start[];
|
|
|
|
extern char __dtcm_end[];
|
2020-04-23 17:51:08 -05:00
|
|
|
#endif
|
2019-07-03 14:19:29 +02:00
|
|
|
|
2018-04-03 09:39:43 +02:00
|
|
|
/* Used by the Security Attribution Unit to configure the
|
|
|
|
* Non-Secure Callable region.
|
|
|
|
*/
|
|
|
|
#ifdef CONFIG_ARM_FIRMWARE_HAS_SECURE_ENTRY_FUNCS
|
|
|
|
extern char __sg_start[];
|
|
|
|
extern char __sg_end[];
|
|
|
|
extern char __sg_size[];
|
|
|
|
#endif /* CONFIG_ARM_FIRMWARE_HAS_SECURE_ENTRY_FUNCS */
|
|
|
|
|
2018-11-07 23:40:43 +01:00
|
|
|
/*
|
|
|
|
* Non-cached kernel memory region, currently only available on ARM Cortex-M7
|
|
|
|
* with a MPU. Start and end will be aligned for memory management/protection
|
|
|
|
* hardware for the target architecture.
|
|
|
|
*
|
|
|
|
* All the functions with '__nocache' keyword will be placed into this
|
|
|
|
* section.
|
|
|
|
*/
|
|
|
|
#ifdef CONFIG_NOCACHE_MEMORY
|
|
|
|
extern char _nocache_ram_start[];
|
|
|
|
extern char _nocache_ram_end[];
|
|
|
|
extern char _nocache_ram_size[];
|
|
|
|
#endif /* CONFIG_NOCACHE_MEMORY */
|
2017-10-05 01:20:21 +02:00
|
|
|
|
2018-09-27 14:14:17 +08:00
|
|
|
/* Memory owned by the kernel. Start and end will be aligned for memory
|
|
|
|
* management/protection hardware for the target architecture.
|
|
|
|
*
|
|
|
|
* All the functions with '__ramfunc' keyword will be placed into this
|
2019-02-10 11:05:51 +01:00
|
|
|
* section, stored in RAM instead of FLASH.
|
2018-09-27 14:14:17 +08:00
|
|
|
*/
|
2019-02-10 11:05:51 +01:00
|
|
|
#ifdef CONFIG_ARCH_HAS_RAMFUNC_SUPPORT
|
2021-05-21 21:29:59 +02:00
|
|
|
extern char __ramfunc_start[];
|
|
|
|
extern char __ramfunc_end[];
|
|
|
|
extern char __ramfunc_size[];
|
|
|
|
extern char __ramfunc_load_start[];
|
2019-02-10 11:05:51 +01:00
|
|
|
#endif /* CONFIG_ARCH_HAS_RAMFUNC_SUPPORT */
|
2018-09-27 14:14:17 +08:00
|
|
|
|
2019-06-14 09:08:11 +02:00
|
|
|
/* Memory owned by the kernel. Memory region for thread privilege stack buffers,
|
|
|
|
* currently only applicable on ARM Cortex-M architecture when building with
|
|
|
|
* support for User Mode.
|
|
|
|
*
|
|
|
|
* All thread privilege stack buffers will be placed into this section.
|
|
|
|
*/
|
|
|
|
#ifdef CONFIG_USERSPACE
|
|
|
|
extern char z_priv_stacks_ram_start[];
|
|
|
|
extern char z_priv_stacks_ram_end[];
|
2020-04-24 16:24:46 -07:00
|
|
|
extern char z_user_stacks_start[];
|
|
|
|
extern char z_user_stacks_end[];
|
2020-12-18 15:18:04 -08:00
|
|
|
extern char z_kobject_data_begin[];
|
2019-06-14 09:08:11 +02:00
|
|
|
#endif /* CONFIG_USERSPACE */
|
|
|
|
|
2020-09-25 13:10:00 -07:00
|
|
|
#ifdef CONFIG_THREAD_LOCAL_STORAGE
|
|
|
|
extern char __tdata_start[];
|
|
|
|
extern char __tdata_end[];
|
|
|
|
extern char __tdata_size[];
|
2021-02-04 20:05:45 -08:00
|
|
|
extern char __tdata_align[];
|
2020-09-25 13:10:00 -07:00
|
|
|
extern char __tbss_start[];
|
|
|
|
extern char __tbss_end[];
|
|
|
|
extern char __tbss_size[];
|
2021-02-04 20:05:45 -08:00
|
|
|
extern char __tbss_align[];
|
2020-09-25 13:10:00 -07:00
|
|
|
extern char __tls_start[];
|
|
|
|
extern char __tls_end[];
|
|
|
|
extern char __tls_size[];
|
|
|
|
#endif /* CONFIG_THREAD_LOCAL_STORAGE */
|
|
|
|
|
2021-02-24 10:18:34 -08:00
|
|
|
#ifdef CONFIG_LINKER_USE_BOOT_SECTION
|
|
|
|
/* lnkr_boot_start[] and lnkr_boot_end[]
|
|
|
|
* must encapsulate all the boot sections.
|
|
|
|
*/
|
|
|
|
extern char lnkr_boot_start[];
|
|
|
|
extern char lnkr_boot_end[];
|
|
|
|
|
|
|
|
extern char lnkr_boot_text_start[];
|
|
|
|
extern char lnkr_boot_text_end[];
|
|
|
|
extern char lnkr_boot_text_size[];
|
|
|
|
extern char lnkr_boot_data_start[];
|
|
|
|
extern char lnkr_boot_data_end[];
|
|
|
|
extern char lnkr_boot_data_size[];
|
|
|
|
extern char lnkr_boot_rodata_start[];
|
|
|
|
extern char lnkr_boot_rodata_end[];
|
|
|
|
extern char lnkr_boot_rodata_size[];
|
|
|
|
extern char lnkr_boot_bss_start[];
|
|
|
|
extern char lnkr_boot_bss_end[];
|
|
|
|
extern char lnkr_boot_bss_size[];
|
|
|
|
extern char lnkr_boot_noinit_start[];
|
|
|
|
extern char lnkr_boot_noinit_end[];
|
|
|
|
extern char lnkr_boot_noinit_size[];
|
|
|
|
#endif /* CONFIG_LINKER_USE_BOOT_SECTION */
|
|
|
|
|
2021-02-23 13:33:38 -08:00
|
|
|
#ifdef CONFIG_LINKER_USE_PINNED_SECTION
|
|
|
|
/* lnkr_pinned_start[] and lnkr_pinned_end[] must encapsulate
|
|
|
|
* all the pinned sections as these are used by
|
|
|
|
* the MMU code to mark the physical page frames with
|
|
|
|
* Z_PAGE_FRAME_PINNED.
|
|
|
|
*/
|
|
|
|
extern char lnkr_pinned_start[];
|
|
|
|
extern char lnkr_pinned_end[];
|
|
|
|
|
|
|
|
extern char lnkr_pinned_text_start[];
|
|
|
|
extern char lnkr_pinned_text_end[];
|
|
|
|
extern char lnkr_pinned_text_size[];
|
|
|
|
extern char lnkr_pinned_data_start[];
|
|
|
|
extern char lnkr_pinned_data_end[];
|
|
|
|
extern char lnkr_pinned_data_size[];
|
|
|
|
extern char lnkr_pinned_rodata_start[];
|
|
|
|
extern char lnkr_pinned_rodata_end[];
|
|
|
|
extern char lnkr_pinned_rodata_size[];
|
|
|
|
extern char lnkr_pinned_bss_start[];
|
|
|
|
extern char lnkr_pinned_bss_end[];
|
|
|
|
extern char lnkr_pinned_bss_size[];
|
|
|
|
extern char lnkr_pinned_noinit_start[];
|
|
|
|
extern char lnkr_pinned_noinit_end[];
|
|
|
|
extern char lnkr_pinned_noinit_size[];
|
2021-08-03 13:49:25 -07:00
|
|
|
|
|
|
|
__pinned_func
|
|
|
|
static inline bool lnkr_is_pinned(uint8_t *addr)
|
|
|
|
{
|
|
|
|
if ((addr >= (uint8_t *)lnkr_pinned_start) &&
|
|
|
|
(addr < (uint8_t *)lnkr_pinned_end)) {
|
|
|
|
return true;
|
|
|
|
} else {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
__pinned_func
|
|
|
|
static inline bool lnkr_is_region_pinned(uint8_t *addr, size_t sz)
|
|
|
|
{
|
|
|
|
if ((addr >= (uint8_t *)lnkr_pinned_start) &&
|
|
|
|
((addr + sz) < (uint8_t *)lnkr_pinned_end)) {
|
|
|
|
return true;
|
|
|
|
} else {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-02-23 13:33:38 -08:00
|
|
|
#endif /* CONFIG_LINKER_USE_PINNED_SECTION */
|
|
|
|
|
2015-04-10 16:44:37 -07:00
|
|
|
#endif /* ! _ASMLANGUAGE */
|
|
|
|
|
2018-09-14 10:43:44 -07:00
|
|
|
#endif /* ZEPHYR_INCLUDE_LINKER_LINKER_DEFS_H_ */
|