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")
# 1. Записываем вашу идею фильтрации VMA 0x8 в чистый файл скрипта
file(WRITE ${LMA_SCRIPT_FILE}
"import sys
import subprocess
if len(sys.argv) < 4:
sys.exit(1)
elf_file = sys.argv[1]
offset_val = sys.argv[2]
objcopy_bin = sys.argv[3]
# Запускаем readelf для анализа структуры секций
res = subprocess.run(['arm-zephyr-eabi-readelf', '-S', elf_file], capture_output=True, text=True)
lma_args = []
for line in res.stdout.splitlines():
parts = line.split()
# Если строка описывает секцию и её VMA адрес (3-я колонка) начинается на 8
if len(parts) >= 4 and parts[2].startswith('8'):
sec_name = parts[1].replace('[', '').replace(']', '')
# Пропускаем bss и noinit секции, так как они не содержат данных во Flash
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)
"
)
# 2. Интегрируем вызов готового файла в конвейер сборки Zephyr.
# Команда абсолютно плоская, в ней нет скобок и кавычек, Bash выполнит её мгновенно.
list(APPEND
post_build_commands
COMMAND ${PYTHON_EXECUTABLE} ${LMA_SCRIPT_FILE}
${PROJECT_BINARY_DIR}/${KERNEL_ELF_NAME}
${adjustment}
$<TARGET_PROPERTY:bintools,elfconvert_command>
)
endif()