From d51a67b7c098c8bb5479a7b87f05dc40fb76e065 Mon Sep 17 00:00:00 2001 From: Torsten Rasmussen Date: Wed, 12 Jan 2022 14:21:07 +0100 Subject: [PATCH] cmake: support ELF image adjustment This commit adds support for adjust the addresses of the final image. This is useful when the image is to be flashed at a location different from the LMA address encoded in the ELF file by the linker. An example use-case is multicore systems where core A might load image from a flash partition into RAM in order for core B to execute and load, but where the image itself is build with the RAM addresses as LMA. It updates the zephyr_image_info.h header with information of adjustment value. Signed-off-by: Torsten Rasmussen --- CMakeLists.txt | 13 +++++++++++++ Kconfig.zephyr | 24 ++++++++++++++++++++++++ cmake/bintools/gnu/target_bintools.cmake | 2 ++ scripts/gen_image_info.py | 8 ++++++-- 4 files changed, 45 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 092b9ad31f5..36bc079a944 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1393,6 +1393,18 @@ if(CONFIG_OUTPUT_PRINT_MEMORY_USAGE) endif() endif() +if(CONFIG_BUILD_OUTPUT_ADJUST_LMA) + math(EXPR adjustment "${CONFIG_BUILD_OUTPUT_ADJUST_LMA}" OUTPUT_FORMAT DECIMAL) + list(APPEND + post_build_commands + COMMAND $ + $ + $${adjustment} + $${KERNEL_ELF_NAME} + $${KERNEL_ELF_NAME} + ) +endif() + if(CONFIG_BUILD_OUTPUT_HEX OR BOARD_FLASH_RUNNER STREQUAL openocd) get_property(elfconvert_formats TARGET bintools PROPERTY elfconvert_formats) if(ihex IN_LIST elfconvert_formats) @@ -1582,6 +1594,7 @@ if(CONFIG_BUILD_OUTPUT_INFO_HEADER) COMMAND ${PYTHON_EXECUTABLE} ${ZEPHYR_BASE}/scripts/gen_image_info.py --elf-file=${KERNEL_ELF_NAME} --header-file=${PROJECT_BINARY_DIR}/include/public/zephyr_image_info.h + $<$:--adjusted-lma=${adjustment}> ) list(APPEND post_build_byproducts diff --git a/Kconfig.zephyr b/Kconfig.zephyr index 9d43b6bab63..ecc92df362b 100644 --- a/Kconfig.zephyr +++ b/Kconfig.zephyr @@ -494,6 +494,30 @@ config BUILD_OUTPUT_STRIPPED Build a stripped binary zephyr/zephyr.strip in the build directory. The name of this file can be customized with CONFIG_KERNEL_BIN_NAME. +config BUILD_OUTPUT_ADJUST_LMA + string + help + This will adjust the LMA address in the final ELF and hex files with + the value provided. + This will not affect the internal address symbols inside the image but + can be useful when adjusting the LMA address for flash tools or multi + stage loaders where a pre-loader may copy image to a second location + before booting a second core. + The value will be evaluated as a math expression, this means that + following are valid expression + - 1024 + - 0x1000 + - -0x1000 + - 0x20000000 - 0x10000000 + Note: negative numbers are valid. + To adjust according to a chosen flash partition one can specify a + default as: + DT_CHOSEN_IMAGE_ := ,-partition + DT_CHOSEN_Z_FLASH := zephyr,flash + config BUILD_OUTPUT_ADJUST_LMA + default "$(dt_chosen_reg_addr_hex,$(DT_CHOSEN_IMAGE_M4))-\ + $(dt_chosen_reg_addr_hex,$(DT_CHOSEN_Z_FLASH))" + config BUILD_OUTPUT_INFO_HEADER bool "Create a image information header" help diff --git a/cmake/bintools/gnu/target_bintools.cmake b/cmake/bintools/gnu/target_bintools.cmake index 6cc27b70a90..5db7eae8269 100644 --- a/cmake/bintools/gnu/target_bintools.cmake +++ b/cmake/bintools/gnu/target_bintools.cmake @@ -41,6 +41,8 @@ set_property(TARGET bintools PROPERTY elfconvert_flag_section_remove "--remove-s set_property(TARGET bintools PROPERTY elfconvert_flag_section_only "--only-section=") set_property(TARGET bintools PROPERTY elfconvert_flag_section_rename "--rename-section;") +set_property(TARGET bintools PROPERTY elfconvert_flag_lma_adjust "--change-section-lma;*+") + # Note, placing a ';' at the end results in the following param to be a list, # and hence space separated. # Thus the command line argument becomes: diff --git a/scripts/gen_image_info.py b/scripts/gen_image_info.py index aad71b1e3e5..758c0b8e2aa 100644 --- a/scripts/gen_image_info.py +++ b/scripts/gen_image_info.py @@ -16,6 +16,7 @@ Information included in the image information header: - Number of segments in the image - LMA address of each segment - VMA address of each segment +- LMA adjusted of each segment if the LMA addresses has been adjusted after linking - Size of each segment ''' @@ -23,7 +24,7 @@ import argparse from elftools.elf.elffile import ELFFile -def write_header(filename, segments): +def write_header(filename, segments, adjusted_lma): content = [] filename_we = filename.split('.h')[0].upper() @@ -31,6 +32,7 @@ def write_header(filename, segments): content.append(f'#define {filename_we}_H') content.append(f'') content.append(f'#define SEGMENT_NUM {len(segments)}') + content.append(f'#define ADJUSTED_LMA {adjusted_lma}') for idx, segment in enumerate(segments): segment_header = segment['segment'].header @@ -69,10 +71,12 @@ def main(): help="""Header file to write with image data.""") parser.add_argument('--elf-file', required=True, help="""ELF File to process.""") + parser.add_argument('--adjusted-lma', required=False, default=0, + help="""Adjusted LMA address value.""") args = parser.parse_args() segments = read_segments(args.elf_file) - write_header(args.header_file, segments) + write_header(args.header_file, segments, args.adjusted_lma) if __name__ == "__main__":