Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Script to relocate code/data/bss sections to different memory types. #10892

Merged
merged 14 commits into from
Dec 7, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 35 additions & 6 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,7 @@ zephyr_compile_options(
-imacros ${AUTOCONF_H}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The commit message needs to be re-written.

It should be clear to the reader that this is a
breaking change and how to identify whether he is affected.

The discussion leading up to this change had a good explanation
I believe.

This is so that, when this breaks something, it is easier to identify
where it broke.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@SebastianBoe yep make it a bit more verbose. Please re-review.

-ffreestanding
-Wno-main
-fno-common
${NOSTDINC_F}
${TOOLCHAIN_C_FLAGS}
)
Expand Down Expand Up @@ -776,7 +777,9 @@ if(CONFIG_APPLICATION_MEMORY)
)
endif() # CONFIG_APPLICATION_MEMORY


if (CONFIG_CODE_DATA_RELOCATION)
set(CODE_RELOCATION_DEP code_relocation_source_lib)
endif() # CONFIG_CODE_DATA_RELOCATION

construct_add_custom_command_for_linker_pass(linker custom_command)
add_custom_command(
Expand All @@ -788,6 +791,7 @@ add_custom_target(
DEPENDS
${ALIGN_SIZING_DEP} ${PRIV_STACK_DEP}
${APP_SMEM_DEP}
${CODE_RELOCATION_DEP}
linker.cmd
offsets_h
)
Expand Down Expand Up @@ -851,6 +855,28 @@ if(CONFIG_GEN_ISR_TABLES)
set_property(GLOBAL APPEND PROPERTY GENERATED_KERNEL_SOURCE_FILES isr_tables.c)
endif()

if(CONFIG_CODE_DATA_RELOCATION)
set(MEM_RELOCATAION_LD "${PROJECT_BINARY_DIR}/include/generated/linker_relocate.ld")
set(MEM_RELOCATAION_CODE "${PROJECT_BINARY_DIR}/code_relocation.c")

add_custom_command(
OUTPUT ${MEM_RELOCATAION_CODE} ${MEM_RELOCATAION_LD}
COMMAND
${PYTHON_EXECUTABLE}
${ZEPHYR_BASE}/scripts/gen_relocate_app.py
$<$<BOOL:${CMAKE_VERBOSE_MAKEFILE}>:--verbose>
-d ${APPLICATION_BINARY_DIR}
-i '$<TARGET_PROPERTY:code_data_relocation_target,COMPILE_DEFINITIONS>'
-o ${MEM_RELOCATAION_LD}
-c ${MEM_RELOCATAION_CODE}
DEPENDS app kernel ${ZEPHYR_LIBS_PROPERTY}
)

add_library(code_relocation_source_lib STATIC ${MEM_RELOCATAION_CODE})
target_link_libraries(code_relocation_source_lib zephyr_interface)

endif()

if(CONFIG_ARM AND CONFIG_USERSPACE)
set(GEN_PRIV_STACKS $ENV{ZEPHYR_BASE}/scripts/gen_priv_stacks.py)
set(PROCESS_PRIV_STACKS_GPERF $ENV{ZEPHYR_BASE}/scripts/process_gperf.py)
Expand Down Expand Up @@ -1138,6 +1164,7 @@ if(CONFIG_CPU_HAS_MPU AND CONFIG_USERSPACE)
linker_app_sizing.cmd
offsets_h
${APP_SMEM_DEP}
${CODE_RELOCATION_DEP}
)

set_property(TARGET
Expand All @@ -1152,9 +1179,9 @@ if(CONFIG_CPU_HAS_MPU AND CONFIG_USERSPACE)
# other ELF files are built
set(GEN_APP_ALIGN $ENV{ZEPHYR_BASE}/scripts/gen_alignment_script.py)
add_executable( app_sizing_prebuilt misc/empty_file.c)
target_link_libraries(app_sizing_prebuilt ${TOPT} ${PROJECT_BINARY_DIR}/linker_app_sizing.cmd ${zephyr_lnk})
target_link_libraries(app_sizing_prebuilt ${TOPT} ${PROJECT_BINARY_DIR}/linker_app_sizing.cmd ${zephyr_lnk} ${CODE_RELOCATION_DEP})
set_property(TARGET app_sizing_prebuilt PROPERTY LINK_DEPENDS ${PROJECT_BINARY_DIR}/linker_app_sizing.cmd)
add_dependencies( app_sizing_prebuilt linker_app_sizing_script offsets )
add_dependencies( app_sizing_prebuilt linker_app_sizing_script offsets ${CODE_RELOCATION_DEP} )

add_custom_command(
TARGET app_sizing_prebuilt
Expand All @@ -1177,6 +1204,7 @@ if(CONFIG_ARM)
linker_priv_stacks_script
DEPENDS
${ALIGN_SIZING_DEP} ${APP_SMEM_DEP}
${CODE_RELOCATION_DEP}
linker_priv_stacks.cmd
offsets_h
)
Expand All @@ -1189,7 +1217,7 @@ if(CONFIG_ARM)

set(PRIV_STACK_LIB priv_stacks_output_obj_renamed_lib)
add_executable( priv_stacks_prebuilt misc/empty_file.c)
target_link_libraries(priv_stacks_prebuilt ${TOPT} ${PROJECT_BINARY_DIR}/linker_priv_stacks.cmd ${zephyr_lnk})
target_link_libraries(priv_stacks_prebuilt ${TOPT} ${PROJECT_BINARY_DIR}/linker_priv_stacks.cmd ${zephyr_lnk} ${CODE_RELOCATION_DEP})
set_property(TARGET priv_stacks_prebuilt PROPERTY LINK_DEPENDS ${PROJECT_BINARY_DIR}/linker_priv_stacks.cmd)
add_dependencies( priv_stacks_prebuilt ${ALIGN_SIZING_DEP} linker_priv_stacks_script offsets)
endif()
Expand All @@ -1198,7 +1226,7 @@ endif()

# FIXME: Is there any way to get rid of empty_file.c?
add_executable( zephyr_prebuilt misc/empty_file.c)
target_link_libraries(zephyr_prebuilt ${TOPT} ${PROJECT_BINARY_DIR}/linker.cmd ${PRIV_STACK_LIB} ${zephyr_lnk})
target_link_libraries(zephyr_prebuilt ${TOPT} ${PROJECT_BINARY_DIR}/linker.cmd ${PRIV_STACK_LIB} ${zephyr_lnk} ${CODE_RELOCATION_DEP})
set_property(TARGET zephyr_prebuilt PROPERTY LINK_DEPENDS ${PROJECT_BINARY_DIR}/linker.cmd)
add_dependencies( zephyr_prebuilt ${ALIGN_SIZING_DEP} ${PRIV_STACK_DEP} linker_script offsets)

Expand All @@ -1218,6 +1246,7 @@ if(GKOF OR GKSF)
linker_pass_final_script
DEPENDS
${ALIGN_SIZING_DEP} ${PRIV_STACK_DEP}
${CODE_RELOCATION_DEP}
zephyr_prebuilt
linker_pass_final.cmd
offsets_h
Expand All @@ -1229,7 +1258,7 @@ if(GKOF OR GKSF)
)

add_executable( kernel_elf misc/empty_file.c ${GKSF})
target_link_libraries(kernel_elf ${GKOF} ${TOPT} ${PROJECT_BINARY_DIR}/linker_pass_final.cmd ${zephyr_lnk})
target_link_libraries(kernel_elf ${GKOF} ${TOPT} ${PROJECT_BINARY_DIR}/linker_pass_final.cmd ${zephyr_lnk} ${CODE_RELOCATION_DEP})
set_property(TARGET kernel_elf PROPERTY LINK_DEPENDS ${PROJECT_BINARY_DIR}/linker_pass_final.cmd)
add_dependencies( kernel_elf ${ALIGN_SIZING_DEP} ${PRIV_STACK_DEP} linker_pass_final_script)
else()
Expand Down
9 changes: 9 additions & 0 deletions Kconfig.zephyr
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,15 @@ config LINKER_ORPHAN_SECTION_ERROR

endchoice

config CODE_DATA_RELOCATION
bool "Relocate code/data sections"
depends on ARM
help
When selected this will relocate .text, data and .bss sections from
the specified files and places it in the required memory region. The
files should be specified in the CMakeList.txt file with
a cmake API zephyr_code_relocation().

config HAS_FLASH_LOAD_OFFSET
bool
help
Expand Down
3 changes: 2 additions & 1 deletion arch/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ config PRIVILEGED_STACK_SIZE

config PRIVILEGED_STACK_TEXT_AREA
int "Privileged stacks text area"
default 256 if (DEBUG || STACK_CANARIES)
default 256 if (DEBUG || STACK_CANARIES || CODE_DATA_RELOCATION)
default 128
depends on ARCH_HAS_USERSPACE
help
Expand All @@ -159,6 +159,7 @@ config PRIVILEGED_STACK_TEXT_AREA
config KOBJECT_TEXT_AREA
int "Size if kobject text area"
default 256 if (!SIZE_OPTIMIZATIONS || STACK_CANARIES || ARC)
default 256 if CODE_DATA_RELOCATION
default 128
depends on ARCH_HAS_USERSPACE
help
Expand Down
2 changes: 2 additions & 0 deletions cmake/app/boilerplate.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,8 @@ set(__build_dir ${CMAKE_CURRENT_BINARY_DIR}/zephyr)

set(PROJECT_BINARY_DIR ${__build_dir})

add_custom_target(code_data_relocation_target)

# CMake's 'project' concept has proven to not be very useful for Zephyr
# due in part to how Zephyr is organized and in part to it not fitting well
# with cross compilation.
Expand Down
8 changes: 8 additions & 0 deletions cmake/extensions.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -692,6 +692,14 @@ function(zephyr_check_compiler_flag lang option check)
endif()
endfunction()

# Helper function for CONFIG_CODE_DATA_RELOCATION
# Call this function with 2 arguments file and then memory location
function(zephyr_code_relocate file location)
set_property(TARGET code_data_relocation_target
APPEND PROPERTY COMPILE_DEFINITIONS
"${location}:${CMAKE_CURRENT_SOURCE_DIR}/${file}")
endfunction()

########################################################
# 2. Kconfig-aware extensions
########################################################
Expand Down
1 change: 1 addition & 0 deletions doc/application/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,4 @@ Developer Guides
../README.rst
../west/index.rst
coccinelle.rst
relocation.rst
97 changes: 97 additions & 0 deletions doc/application/relocation.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
.. _code_data_relocation:

Code data relocation
####################

Overview
********
This script will relocate .text, .rodata, .data, and .bss sections from
required files and place them in the required memory region. The
memory region and file are given to this python script in the form
of a string. This script is always invoked from inside cmake.

This script provides a robust way to re-order
the memory contents without actually having to modify the code.
In simple terms this script will do the job of
``__attribute__((section("name")))`` for a bunch of files together.

Details
*******
The memory region and file are given to this python script in the form of a string.

An example of such a string is:
``SRAM2:/home/xyz/zephyr/samples/hello_world/src/main.c,SRAM1:/home/xyz/zephyr/samples/hello_world/src/main2.c``

This script is invoked with the following parameters:
``python3 gen_relocate_app.py -i input_string -o generated_linker -c generated_code``

Kconfig :option:`CONFIG_CODE_DATA_RELOCATION` option, when enabled in ``prj.conf``, will
invoke the script and do the required relocation.

This script also trigger the generation of ``linker_relocate.ld`` and ``code_relocation.c`` files.
The ``linker_relocate.ld`` file creates appropriate sections and
links the required functions or variables from all the selected files.

**Note**:
The text section is split into 2 parts in the main linker script. The first section
will have some info regarding vector tables and other debug related info.
The second section will have the complete text section.
This is needed to force the required functions and data variables to the correct locations.
This is due to the behavior of the linker. The linker will only link once and
hence this text section had to be split to make room for the generated linker script.

The ``code_relocation.c`` file has code that is needed for
initializing data sections, and a copy of the text sections (if XIP).
Also this contains code needed for bss zeroing and
for data copy operations from ROM to required memory type.

**The procedure to invoke this feature is:**

* Enable :option:`CONFIG_CODE_DATA_RELOCATION` in the ``prj.conf`` file

* Inside the ``CMakeLists.txt`` file in the project, mention
all the files that need relocation.

``zephyr_code_relocate(src/*.c SRAM2)``

Where the first argument is the file/files and the second
argument is the memory where it must be placed.

.. note::
The file argument supports limited regular expressions.
function zephyr_code_relocate() can be called as many times as required.
This step has to be performed before the inclusion of boilerplate.cmake.


Additional Configurations
=========================
This section shows additional configuration options that can be set in ``CMakeLists.txt``

* if the memory is SRAM1, SRAM2, CCD, or AON, then place the full object in the sections
for example:

.. code-block:: none

zephyr_code_relocate(src/file1.c SRAM2)
zephyr_code_relocate(src/file2.c.c SRAM)

* if the memory type is appended with _DATA, _TEXT, _RODATA or _BSS, only the
selected memory is placed in the required memory region.
for example:

.. code-block:: none

zephyr_code_relocate(src/file1.c SRAM2_DATA)
zephyr_code_relocate(src/file2.c.c SRAM2_TEXT)

* Multiple regions can also be appended together such as: SRAM2_DATA_BSS.
This will place data and bss inside SRAM2.

Sample
======
A sample showcasing this feature is provided at
``$ZEPHYR_BASE/samples/test_relocation/``

This is an example of using the code relocation feature.
This example will place .text, .data, .bss from 3 files to various parts in the SRAM
using a custom linker file derived from ``include/arch/arm/cortex_m/scripts/linker.ld``
1 change: 1 addition & 0 deletions drivers/ipm/ipm_quark_se.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
*/
static struct device *device_by_channel[QUARK_SE_IPM_CHANNELS];
static u32_t inbound_channels;
const struct ipm_driver_api ipm_quark_se_api_funcs;

static u32_t quark_se_ipm_sts_get(void)
{
Expand Down
2 changes: 1 addition & 1 deletion drivers/ipm/ipm_quark_se.h
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ struct quark_se_ipm_driver_data {
void *callback_ctx;
};

const struct ipm_driver_api ipm_quark_se_api_funcs;
extern const struct ipm_driver_api ipm_quark_se_api_funcs;

void quark_se_ipm_isr(void *param);

Expand Down
10 changes: 10 additions & 0 deletions include/arch/arm/cortex_m/scripts/linker.ld
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,16 @@ SECTIONS
KEEP(*(".kinetis_flash_config.*"))

_vector_end = .;
} GROUP_LINK_IN(ROMABLE_REGION)

#ifdef CONFIG_CODE_DATA_RELOCATION

#include <linker_relocate.ld>

#endif /* CONFIG_CODE_DATA_RELOCATION */

SECTION_PROLOGUE(_TEXT_SECTION_NAME_2,,)
{
_image_text_start = .;
*(.text)
*(".text.*")
Expand Down
2 changes: 1 addition & 1 deletion include/drivers/pci/pci_mgr.h
Original file line number Diff line number Diff line change
Expand Up @@ -541,7 +541,7 @@ union pci_dev {
* +---------------------------------------------------------------------------+
*/

union pci_cap_hdr {
typedef union pci_cap_hdr {
struct {
/* offset 00: */
u32_t id : 8; /* capability ID */
Expand Down
2 changes: 1 addition & 1 deletion include/stats.h
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ extern "C" {
struct stats_name_map {
u16_t snm_off;
const char *snm_name;
} __packed;
} __attribute__((packed));

struct stats_hdr {
const char *s_name;
Expand Down
10 changes: 10 additions & 0 deletions kernel/init.c
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,11 @@ void _bss_zero(void)
(void)memset(&__ccm_bss_start, 0,
((u32_t) &__ccm_bss_end - (u32_t) &__ccm_bss_start));
#endif
#ifdef CONFIG_CODE_DATA_RELOCATION
extern void bss_zeroing_relocation(void);

bss_zeroing_relocation();
#endif /* CONFIG_CODE_DATA_RELOCATION */
#ifdef CONFIG_APPLICATION_MEMORY
(void)memset(&__app_bss_start, 0,
((u32_t) &__app_bss_end - (u32_t) &__app_bss_start));
Expand All @@ -171,6 +176,11 @@ void _data_copy(void)
(void)memcpy(&__ccm_data_start, &__ccm_data_rom_start,
((u32_t) &__ccm_data_end - (u32_t) &__ccm_data_start));
#endif
#ifdef CONFIG_CODE_DATA_RELOCATION
extern void data_copy_xip_relocation(void);

data_copy_xip_relocation();
#endif /* CONFIG_CODE_DATA_RELOCATION */
#ifdef CONFIG_APP_SHARED_MEM
(void)memcpy(&_app_smem_start, &_app_smem_rom_start,
((u32_t) &_app_smem_end - (u32_t) &_app_smem_start));
Expand Down
18 changes: 18 additions & 0 deletions samples/application_development/code_relocation/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
cmake_minimum_required(VERSION 3.8.2)

include($ENV{ZEPHYR_BASE}/cmake/app/boilerplate.cmake NO_POLICY_SCOPE)
project(test_relocation)

FILE(GLOB app_sources src/*.c)
target_sources(app PRIVATE ${app_sources})

# Code relocation feature
zephyr_code_relocate(src/test_file1.c SRAM2)

zephyr_code_relocate(src/test_file2.c SRAM)

zephyr_code_relocate(src/test_file3.c SRAM2_TEXT)
zephyr_code_relocate(src/test_file3.c SRAM_DATA)
zephyr_code_relocate(src/test_file3.c SRAM2_BSS)

zephyr_code_relocate(../../../kernel/sem.c SRAM)
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
SECTION_DATA_PROLOGUE(_CUSTOM_SECTION_NAME2,,)
{
KEEP(*(".custom_section.*"));
} GROUP_DATA_LINK_IN(RAMABLE_REGION, ROMABLE_REGION)
Loading