Skip to content
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
16 changes: 16 additions & 0 deletions arch/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,7 @@ config RISCV
select ARCH_IS_SET
select HAS_DTS
select ARCH_SUPPORTS_COREDUMP
select ARCH_HAS_CODE_DATA_RELOCATION
select ARCH_HAS_THREAD_LOCAL_STORAGE
select IRQ_OFFLOAD_NESTED if IRQ_OFFLOAD
select USE_SWITCH_SUPPORTED
Expand Down Expand Up @@ -577,6 +578,12 @@ config ARCH_HAS_SUSPEND_TO_RAM
config ARCH_HAS_THREAD_ABORT
bool

config ARCH_HAS_CODE_DATA_RELOCATION
bool
help
When selected, the architecture/SoC implements support for
CODE_DATA_RELOCATION in its linker scripts.

#
# Hidden CPU family configs
#
Expand Down Expand Up @@ -755,6 +762,15 @@ config SRAM_REGION_PERMISSIONS
paging, do not need memory protection, and would rather not use up
RAM for the alignment between regions.

config CODE_DATA_RELOCATION
bool "Support code/data section relocation"
depends on ARCH_HAS_CODE_DATA_RELOCATION
help
Enable support for relocating .text, data and .bss sections from specified
files and placing them in a chosen memory region. Files to relocate and
the target regions should be specified in CMakeLists.txt using
zephyr_code_relocate().

menu "Floating Point Options"

config FPU
Expand Down
9 changes: 0 additions & 9 deletions arch/arm/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -34,15 +34,6 @@ config ARM_CUSTOM_INTERRUPT_CONTROLLER
family cores. The Cortex-M family cores are always equipped with
the ARM Nested Vectored Interrupt Controller (NVIC).

config CODE_DATA_RELOCATION
bool "Relocate code/data sections"
depends on CPU_CORTEX_M || CPU_AARCH32_CORTEX_R
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_relocate().

config CODE_DATA_RELOCATION_SRAM
bool "Relocate code/data sections to SRAM"
depends on CPU_CORTEX_M
Expand Down
2 changes: 2 additions & 0 deletions arch/arm/core/aarch32/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ config CPU_CORTEX_M
select ARCH_HAS_TIMING_FUNCTIONS if CPU_CORTEX_M_HAS_DWT
select ARCH_SUPPORTS_ARCH_HW_INIT
select ARCH_HAS_SUSPEND_TO_RAM
select ARCH_HAS_CODE_DATA_RELOCATION
imply XIP
help
This option signifies the use of a CPU of the Cortex-M family.
Expand All @@ -34,6 +35,7 @@ config CPU_AARCH32_CORTEX_R
select HAS_FLASH_LOAD_OFFSET
select ARCH_HAS_USERSPACE if ARM_MPU
select ARCH_HAS_EXTRA_EXCEPTION_INFO
select ARCH_HAS_CODE_DATA_RELOCATION
help
This option signifies the use of a CPU of the Cortex-R family.

Expand Down
9 changes: 9 additions & 0 deletions cmake/linker/ld/target_relocation.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,14 @@ macro(toolchain_ld_relocation)
set(MEM_RELOCATION_SRAM_BSS_LD
"${PROJECT_BINARY_DIR}/include/generated/linker_sram_bss_relocate.ld")
set(MEM_RELOCATION_CODE "${PROJECT_BINARY_DIR}/code_relocation.c")
if(CONFIG_ARM)
set(MEM_REGION_DEFAULT_RAM SRAM)
elseif(CONFIG_RISCV)
set(MEM_REGION_DEFAULT_RAM RAM)
else()
# Name must be configured for newly-supported architectures
message(SEND_ERROR "Default RAM region name is unknown for target architecture")
endif()

add_custom_command(
OUTPUT ${MEM_RELOCATION_CODE} ${MEM_RELOCATION_LD}
Expand All @@ -22,6 +30,7 @@ macro(toolchain_ld_relocation)
-s ${MEM_RELOCATION_SRAM_DATA_LD}
-b ${MEM_RELOCATION_SRAM_BSS_LD}
-c ${MEM_RELOCATION_CODE}
--default_ram_region ${MEM_REGION_DEFAULT_RAM}
DEPENDS app kernel ${ZEPHYR_LIBS_PROPERTY}
)

Expand Down
14 changes: 14 additions & 0 deletions include/zephyr/arch/riscv/common/linker.ld
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,10 @@ SECTIONS
#include <snippets-rom-start.ld>
} GROUP_LINK_IN(ROMABLE_REGION)

#ifdef CONFIG_CODE_DATA_RELOCATION
#include <linker_relocate.ld>
#endif

SECTION_PROLOGUE(_RESET_SECTION_NAME,,)
{
KEEP(*(.reset.*))
Expand Down Expand Up @@ -246,6 +250,11 @@ SECTIONS
*(.bss)
*(".bss.*")
COMMON_SYMBOLS

#ifdef CONFIG_CODE_DATA_RELOCATION
#include <linker_sram_bss_relocate.ld>
#endif

/*
* As memory is cleared in words only, it is simpler to ensure the BSS
* section ends on a 4 byte boundary. This wastes a maximum of 3 bytes.
Expand Down Expand Up @@ -287,6 +296,11 @@ SECTIONS
* zephyr_linker_sources() Cmake function.
*/
#include <snippets-rwdata.ld>

#ifdef CONFIG_CODE_DATA_RELOCATION
#include <linker_sram_data_relocate.ld>
#endif

__data_end = .;

} GROUP_DATA_LINK_IN(RAMABLE_REGION, ROMABLE_REGION)
Expand Down
37 changes: 26 additions & 11 deletions scripts/build/gen_relocate_app.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,8 @@
import glob
import warnings
from elftools.elf.elffile import ELFFile
from elftools.elf.sections import SymbolTableSection

# This script will create linker commands for text,rodata data, bss section relocation

PRINT_TEMPLATE = """
KEEP(*({0}))
Expand All @@ -54,7 +54,7 @@

LOAD_ADDRESS_LOCATION_FLASH = """
#ifdef CONFIG_XIP
GROUP_DATA_LINK_IN({0}, FLASH)
GROUP_DATA_LINK_IN({0}, ROMABLE_REGION)
#else
GROUP_DATA_LINK_IN({0}, {0})
#endif
Expand Down Expand Up @@ -153,6 +153,19 @@
"""


def region_is_default_ram(region_name: str) -> bool:
"""
Test whether a memory region with the given name is the system's default
RAM region or not.

This is used to determine whether some items need to be omitted from
custom regions and instead be placed in the default. In particular, mutable
data placed in the default RAM section is ignored and is allowed to be
handled normally by the linker because it is placed in that region anyway.
"""
return region_name == args.default_ram_region


def find_sections(filename, full_list_of_sections):
with open(filename, 'rb') as obj_file_desc:
full_lib = ELFFile(obj_file_desc)
Expand Down Expand Up @@ -180,7 +193,7 @@ def find_sections(filename, full_list_of_sections):
# common symbols and warns the user of the problem.
# The solution to which is simply assigning a 0 to
# bss variable and it will go to the required place.
if ".symtab" in section.name:
if isinstance(section, SymbolTableSection):
symbols = [x for x in section.iter_symbols()]
for symbol in symbols:
if symbol.entry["st_shndx"] == 'SHN_COMMON':
Expand Down Expand Up @@ -257,18 +270,18 @@ def string_create_helper(region, memory_type,
# Create a complete list of funcs/ variables that goes in for this
# memory type
tmp = print_linker_sections(full_list_of_sections[region])
if memory_type == 'SRAM' and region in {'data', 'bss'}:
if region_is_default_ram(memory_type) and region in {'data', 'bss'}:
linker_string += tmp
else:
if memory_type != 'SRAM' and region == 'rodata':
if not region_is_default_ram(memory_type) and region == 'rodata':
align_size = 0
if memory_type in mpu_align:
align_size = mpu_align[memory_type]

linker_string += LINKER_SECTION_SEQ_MPU.format(memory_type.lower(), region, memory_type.upper(),
region.upper(), tmp, load_address_string, align_size)
else:
if memory_type == 'SRAM' and region == 'text':
if region_is_default_ram(memory_type) and region == 'text':
align_size = 0
linker_string += LINKER_SECTION_SEQ_MPU.format(memory_type.lower(), region, memory_type.upper(),
region.upper(), tmp, load_address_string, align_size)
Expand All @@ -292,16 +305,16 @@ def generate_linker_script(linker_file, sram_data_linker_file, sram_bss_linker_f
is_copy = bool("|COPY" in memory_type)
memory_type = memory_type.split("|", 1)[0]

if memory_type != "SRAM" and is_copy:
if region_is_default_ram(memory_type) and is_copy:
gen_string += MPU_RO_REGION_START.format(memory_type.lower(), memory_type.upper())

gen_string += string_create_helper("text", memory_type, full_list_of_sections, 1, is_copy)
gen_string += string_create_helper("rodata", memory_type, full_list_of_sections, 1, is_copy)

if memory_type != "SRAM" and is_copy:
if region_is_default_ram(memory_type) and is_copy:
gen_string += MPU_RO_REGION_END.format(memory_type.lower())

if memory_type == 'SRAM':
if region_is_default_ram(memory_type):
gen_string_sram_data += string_create_helper("data", memory_type, full_list_of_sections, 1, 1)
gen_string_sram_bss += string_create_helper("bss", memory_type, full_list_of_sections, 0, 1)
else:
Expand Down Expand Up @@ -336,7 +349,7 @@ def generate_memcpy_code(memory_type, full_list_of_sections, code_generation):

# add all the regions that needs to be copied on boot up
for mtype in ["text", "rodata", "data"]:
if memory_type == "SRAM" and mtype == "data":
if region_is_default_ram(memory_type) and mtype == "data":
continue

if full_list_of_sections[mtype] and generate_section[mtype]:
Expand All @@ -345,7 +358,7 @@ def generate_memcpy_code(memory_type, full_list_of_sections, code_generation):
memory_type.lower(), mtype)

# add for all the bss data that needs to be zeroed on boot up
if full_list_of_sections["bss"] and generate_section["bss"] and memory_type != "SRAM":
if full_list_of_sections["bss"] and generate_section["bss"] and not region_is_default_ram(memory_type):
code_generation["zero_code"] += MEMSET_TEMPLATE.format(memory_type.lower())
code_generation["extern"] += EXTERN_LINKER_VAR_DECLARATION.format(
memory_type.lower(), "bss")
Expand Down Expand Up @@ -390,6 +403,8 @@ def parse_args():
help="Output sram bss ld file")
parser.add_argument("-c", "--output_code", required=False,
help="Output relocation code header file")
parser.add_argument("-R", "--default_ram_region", default='SRAM',
help="Name of default RAM memory region for system")
parser.add_argument("-v", "--verbose", action="count", default=0,
help="Verbose Output")
args = parser.parse_args()
Expand Down
12 changes: 9 additions & 3 deletions tests/application_development/code_relocation/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,22 @@ project(code_relocation)
FILE(GLOB app_sources src/*.c)
target_sources(app PRIVATE ${app_sources})

if (CONFIG_ARM)
set(RAM_SECTION SRAM)
else()
set(RAM_SECTION RAM)
endif()

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

zephyr_code_relocate(src/test_file2.c SRAM)
zephyr_code_relocate(src/test_file2.c ${RAM_SECTION})

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 ${RAM_SECTION}_DATA)
zephyr_code_relocate(src/test_file3.c SRAM2_BSS)

zephyr_code_relocate(../../../kernel/sem.c SRAM)
zephyr_code_relocate(../../../kernel/sem.c ${RAM_SECTION})

if (CONFIG_RELOCATE_TO_ITCM)
zephyr_code_relocate(../../../lib/libc/minimal/source/string/string.c ITCM_TEXT)
Expand Down
1 change: 0 additions & 1 deletion tests/application_development/code_relocation/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,5 @@

config RELOCATE_TO_ITCM
bool "test with code relocate to itcm"
default y

source "Kconfig.zephyr"
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
/*
* Copyright 2022 The Chromium OS Authors
*
* SPDX-License-Identifier: Apache-2.0
*/

/**
* @file
* @brief Linker command/script file
*
* Linker script for the Cortex-M platforms.
Copy link
Contributor

Choose a reason for hiding this comment

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

Cortex-M?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Hah, oops. I've added a commit to #49438 that fixes this.

*/

#include <zephyr/linker/sections.h>
#include <zephyr/devicetree.h>

#include <zephyr/linker/linker-defs.h>
#include <zephyr/linker/linker-tool.h>

/** enable CONFIG_SRAM2 or any other partition in soc Kconfig,
* this is just an example to show relocation of code/data/bss script
*/
#define _SRAM2_DATA_SECTION_NAME .sram2_data
#define _SRAM2_BSS_SECTION_NAME .sram2_bss
#define _SRAM2_TEXT_SECTION_NAME .sram2_text
#define SRAM2_ADDR (CONFIG_SRAM_BASE_ADDRESS + RAM_SIZE2)

#define RAM_SIZE2 (CONFIG_SRAM_SIZE * 512)
MEMORY
{
SRAM2 (wx) : ORIGIN = (CONFIG_SRAM_BASE_ADDRESS + RAM_SIZE2), LENGTH = RAM_SIZE2
}

#include <zephyr/arch/riscv/common/linker.ld>
5 changes: 5 additions & 0 deletions tests/application_development/code_relocation/prj_riscv.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
CONFIG_CODE_DATA_RELOCATION=y
CONFIG_ZTEST=y
CONFIG_ZTEST_NEW_API=y
CONFIG_HAVE_CUSTOM_LINKER_SCRIPT=y
CONFIG_CUSTOM_LINKER_SCRIPT="linker_riscv_qemu_sram2.ld"
Loading