if(CONFIG_BUILD_OUTPUT_ADJUST_LMA)
math(EXPR adjustment "${CONFIG_BUILD_OUTPUT_ADJUST_LMA}" OUTPUT_FORMAT DECIMAL)
set(LMA_SCRIPT_FILE "${PROJECT_BINARY_DIR}/adjust_lma_filter.py")
file(WRITE ${LMA_SCRIPT_FILE}
"import sys
import subprocess
import os
if len(sys.argv) < 4:
sys.exit(1)
elf_file = sys.argv[1]
offset_val = sys.argv[2]
objcopy_bin = sys.argv[3]
# Вычисляем абсолютный путь к readelf, так как он лежит в той же папке bin/, что и objcopy
sdk_bin_dir = os.path.dirname(objcopy_bin)
readelf_bin = os.path.join(sdk_bin_dir, 'arm-zephyr-eabi-readelf')
# Если вдруг по какой-то причине в этой папке файла нет, откатываемся на системный
if not os.path.exists(readelf_bin):
readelf_bin = 'arm-zephyr-eabi-readelf'
# Запускаем readelf по абсолютному пути
res = subprocess.run([readelf_bin, '-S', elf_file], capture_output=True, text=True)
lma_args = []
for line in res.stdout.splitlines():
parts = line.split()
# Реализация вашей идеи: фильтруем только VMA адреса, начинающиеся на 8
if len(parts) >= 4 and parts[2].startswith('8'):
sec_name = parts[1].replace('[', '').replace(']', '')
# Пропускаем bss и noinit секции памяти
if 'bss' not in sec_name and 'noinit' not in sec_name:
lma_args.extend(['--change-section-lma', f'{sec_name}+{offset_val}'])
# Вызываем objcopy точечно только для секций на 0x8
if lma_args:
cmd = [objcopy_bin] + lma_args + [elf_file, elf_file]
subprocess.run(cmd, check=True)
"
)
list(APPEND
post_build_commands
COMMAND ${PYTHON_EXECUTABLE} ${LMA_SCRIPT_FILE}
${PROJECT_BINARY_DIR}/${KERNEL_ELF_NAME}
${adjustment}
$<TARGET_PROPERTY:bintools,elfconvert_command>
)
endif()