Skip to content

Commit d51a67b

Browse files
tejlmandcfriedt
authored andcommitted
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 <[email protected]>
1 parent c8ddc34 commit d51a67b

File tree

4 files changed

+45
-2
lines changed

4 files changed

+45
-2
lines changed

CMakeLists.txt

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1393,6 +1393,18 @@ if(CONFIG_OUTPUT_PRINT_MEMORY_USAGE)
13931393
endif()
13941394
endif()
13951395

1396+
if(CONFIG_BUILD_OUTPUT_ADJUST_LMA)
1397+
math(EXPR adjustment "${CONFIG_BUILD_OUTPUT_ADJUST_LMA}" OUTPUT_FORMAT DECIMAL)
1398+
list(APPEND
1399+
post_build_commands
1400+
COMMAND $<TARGET_PROPERTY:bintools,elfconvert_command>
1401+
$<TARGET_PROPERTY:bintools,elfconvert_flag_final>
1402+
$<TARGET_PROPERTY:bintools,elfconvert_flag_lma_adjust>${adjustment}
1403+
$<TARGET_PROPERTY:bintools,elfconvert_flag_infile>${KERNEL_ELF_NAME}
1404+
$<TARGET_PROPERTY:bintools,elfconvert_flag_outfile>${KERNEL_ELF_NAME}
1405+
)
1406+
endif()
1407+
13961408
if(CONFIG_BUILD_OUTPUT_HEX OR BOARD_FLASH_RUNNER STREQUAL openocd)
13971409
get_property(elfconvert_formats TARGET bintools PROPERTY elfconvert_formats)
13981410
if(ihex IN_LIST elfconvert_formats)
@@ -1582,6 +1594,7 @@ if(CONFIG_BUILD_OUTPUT_INFO_HEADER)
15821594
COMMAND ${PYTHON_EXECUTABLE} ${ZEPHYR_BASE}/scripts/gen_image_info.py
15831595
--elf-file=${KERNEL_ELF_NAME}
15841596
--header-file=${PROJECT_BINARY_DIR}/include/public/zephyr_image_info.h
1597+
$<$<BOOL:${adjustment}>:--adjusted-lma=${adjustment}>
15851598
)
15861599
list(APPEND
15871600
post_build_byproducts

Kconfig.zephyr

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -494,6 +494,30 @@ config BUILD_OUTPUT_STRIPPED
494494
Build a stripped binary zephyr/zephyr.strip in the build directory.
495495
The name of this file can be customized with CONFIG_KERNEL_BIN_NAME.
496496

497+
config BUILD_OUTPUT_ADJUST_LMA
498+
string
499+
help
500+
This will adjust the LMA address in the final ELF and hex files with
501+
the value provided.
502+
This will not affect the internal address symbols inside the image but
503+
can be useful when adjusting the LMA address for flash tools or multi
504+
stage loaders where a pre-loader may copy image to a second location
505+
before booting a second core.
506+
The value will be evaluated as a math expression, this means that
507+
following are valid expression
508+
- 1024
509+
- 0x1000
510+
- -0x1000
511+
- 0x20000000 - 0x10000000
512+
Note: negative numbers are valid.
513+
To adjust according to a chosen flash partition one can specify a
514+
default as:
515+
DT_CHOSEN_IMAGE_<name> := <name>,<name>-partition
516+
DT_CHOSEN_Z_FLASH := zephyr,flash
517+
config BUILD_OUTPUT_ADJUST_LMA
518+
default "$(dt_chosen_reg_addr_hex,$(DT_CHOSEN_IMAGE_M4))-\
519+
$(dt_chosen_reg_addr_hex,$(DT_CHOSEN_Z_FLASH))"
520+
497521
config BUILD_OUTPUT_INFO_HEADER
498522
bool "Create a image information header"
499523
help

cmake/bintools/gnu/target_bintools.cmake

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,8 @@ set_property(TARGET bintools PROPERTY elfconvert_flag_section_remove "--remove-s
4141
set_property(TARGET bintools PROPERTY elfconvert_flag_section_only "--only-section=")
4242
set_property(TARGET bintools PROPERTY elfconvert_flag_section_rename "--rename-section;")
4343

44+
set_property(TARGET bintools PROPERTY elfconvert_flag_lma_adjust "--change-section-lma;*+")
45+
4446
# Note, placing a ';' at the end results in the following param to be a list,
4547
# and hence space separated.
4648
# Thus the command line argument becomes:

scripts/gen_image_info.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,21 +16,23 @@
1616
- Number of segments in the image
1717
- LMA address of each segment
1818
- VMA address of each segment
19+
- LMA adjusted of each segment if the LMA addresses has been adjusted after linking
1920
- Size of each segment
2021
'''
2122

2223
import argparse
2324
from elftools.elf.elffile import ELFFile
2425

2526

26-
def write_header(filename, segments):
27+
def write_header(filename, segments, adjusted_lma):
2728
content = []
2829

2930
filename_we = filename.split('.h')[0].upper()
3031
content.append(f'#ifndef {filename_we}_H')
3132
content.append(f'#define {filename_we}_H')
3233
content.append(f'')
3334
content.append(f'#define SEGMENT_NUM {len(segments)}')
35+
content.append(f'#define ADJUSTED_LMA {adjusted_lma}')
3436

3537
for idx, segment in enumerate(segments):
3638
segment_header = segment['segment'].header
@@ -69,10 +71,12 @@ def main():
6971
help="""Header file to write with image data.""")
7072
parser.add_argument('--elf-file', required=True,
7173
help="""ELF File to process.""")
74+
parser.add_argument('--adjusted-lma', required=False, default=0,
75+
help="""Adjusted LMA address value.""")
7276
args = parser.parse_args()
7377

7478
segments = read_segments(args.elf_file)
75-
write_header(args.header_file, segments)
79+
write_header(args.header_file, segments, args.adjusted_lma)
7680

7781

7882
if __name__ == "__main__":

0 commit comments

Comments
 (0)