Skip to content

Commit c8ddc34

Browse files
tejlmandcfriedt
authored andcommitted
scripts: generate image info header file
This commit adds the `gen_image_info.py` script which supports creation of a header file with image information from the EFL file. This version populates the header file with: - Number of segments in the image - LMA address of each segment - VMA address of each segment - Size of each segment The header file can be used by a secondary build system which needs this information. Signed-off-by: Torsten Rasmussen <Torsten.Rasmussen@nordicsemi.no>
1 parent eb9a972 commit c8ddc34

File tree

4 files changed

+104
-0
lines changed

4 files changed

+104
-0
lines changed

CMakeLists.txt

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1576,6 +1576,19 @@ if(CONFIG_BUILD_OUTPUT_EXE)
15761576
)
15771577
endif()
15781578

1579+
if(CONFIG_BUILD_OUTPUT_INFO_HEADER)
1580+
list(APPEND
1581+
post_build_commands
1582+
COMMAND ${PYTHON_EXECUTABLE} ${ZEPHYR_BASE}/scripts/gen_image_info.py
1583+
--elf-file=${KERNEL_ELF_NAME}
1584+
--header-file=${PROJECT_BINARY_DIR}/include/public/zephyr_image_info.h
1585+
)
1586+
list(APPEND
1587+
post_build_byproducts
1588+
${PROJECT_BINARY_DIR}/include/public/zephyr_image_info.h
1589+
)
1590+
endif()
1591+
15791592
# Generate and use MCUboot related artifacts as needed.
15801593
if(CONFIG_BOOTLOADER_MCUBOOT)
15811594
include(${CMAKE_CURRENT_LIST_DIR}/cmake/mcuboot.cmake)

CODEOWNERS

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -658,6 +658,7 @@
658658
/scripts/pylib/twister/expr_parser.py @nashif
659659
/scripts/schemas/twister/ @nashif
660660
/scripts/gen_app_partitions.py @dcpleung @nashif
661+
scripts/gen_image_info.py @tejlmand
661662
/scripts/get_maintainer.py @nashif
662663
/scripts/dts/ @mbolivar-nordic @galak
663664
/scripts/release/ @nashif

Kconfig.zephyr

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -494,6 +494,17 @@ 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_INFO_HEADER
498+
bool "Create a image information header"
499+
help
500+
Create an image information header which will contain image
501+
information from the Zephyr binary.
502+
Example of information contained in the header file:
503+
- Number of segments in the image
504+
- LMA address of each segment
505+
- VMA address of each segment
506+
- Size of each segment
507+
497508
config APPLICATION_DEFINED_SYSCALL
498509
bool "Scan application folder for any syscall definition"
499510
help

scripts/gen_image_info.py

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
#!/usr/bin/env python3
2+
#
3+
# Copyright (c) 2022, Nordic Semiconductor ASA
4+
#
5+
# SPDX-License-Identifier: Apache-2.0
6+
7+
'''
8+
Script to generate image information files.
9+
10+
This script creates a image information header which can be included by a
11+
second build system.
12+
This allows a second stage build system to use image information from a Zephyr
13+
build by including the generated header.
14+
15+
Information included in the image information header:
16+
- Number of segments in the image
17+
- LMA address of each segment
18+
- VMA address of each segment
19+
- Size of each segment
20+
'''
21+
22+
import argparse
23+
from elftools.elf.elffile import ELFFile
24+
25+
26+
def write_header(filename, segments):
27+
content = []
28+
29+
filename_we = filename.split('.h')[0].upper()
30+
content.append(f'#ifndef {filename_we}_H')
31+
content.append(f'#define {filename_we}_H')
32+
content.append(f'')
33+
content.append(f'#define SEGMENT_NUM {len(segments)}')
34+
35+
for idx, segment in enumerate(segments):
36+
segment_header = segment['segment'].header
37+
hex_lma_addr = hex(segment_header.p_paddr)
38+
hex_vma_addr = hex(segment_header.p_vaddr)
39+
hex_size = hex(segment_header.p_filesz)
40+
41+
content.append(f'')
42+
content.append(f'#define SEGMENT_LMA_ADDRESS_{idx} {hex_lma_addr}')
43+
content.append(f'#define SEGMENT_VMA_ADDRESS_{idx} {hex_vma_addr}')
44+
content.append(f'#define SEGMENT_SIZE_{idx} {hex_size}')
45+
46+
content.append(f'')
47+
content.append(f'#endif /* {filename_we}_H */')
48+
49+
with open(filename, 'w') as out_file:
50+
out_file.write('\n'.join(content))
51+
52+
53+
def read_segments(filename):
54+
elffile = ELFFile(open(filename, 'rb'))
55+
segments = list()
56+
for segment_idx in range(elffile.num_segments()):
57+
segments.insert(segment_idx, dict())
58+
segments[segment_idx]['segment'] = elffile.get_segment(segment_idx)
59+
return segments
60+
61+
62+
def main():
63+
parser = argparse.ArgumentParser(description='''
64+
Process ELF file and extract image information.
65+
Create header file with extracted image information which can be included
66+
in other build systems.''')
67+
68+
parser.add_argument('--header-file', required=True,
69+
help="""Header file to write with image data.""")
70+
parser.add_argument('--elf-file', required=True,
71+
help="""ELF File to process.""")
72+
args = parser.parse_args()
73+
74+
segments = read_segments(args.elf_file)
75+
write_header(args.header_file, segments)
76+
77+
78+
if __name__ == "__main__":
79+
main()

0 commit comments

Comments
 (0)