#!/usr/bin/env python3
import sys
import subprocess
import os
import struct
def main():
if len(sys.argv) < 2:
print("[LMA Filter] Error: No real objcopy path provided.")
sys.exit(1)
real_objcopy = sys.argv[1]
args = sys.argv[2:]
# 1. Сначала даем Zephyr собрать стандартный zephyr.hex и zephyr.bin
# В этот момент они слинкованы в адресах 0x80000000
final_cmd = [real_objcopy] + args
subprocess.run(final_cmd, check=True)
# Работаем только на этапе финальной генерации IHEX
if "--output-target=ihex" in " ".join(args):
print("[LMA Filter] Starting global LMA shift via Intel HEX generation...")
# Находим пути к файлам
elf_path = "zephyr.elf"
for arg in args:
if arg.endswith("zephyr.elf"):
elf_path = arg
break
build_dir = os.path.dirname(elf_path)
bin_path = os.path.join(build_dir, "zephyr.bin")
hex_path = os.path.join(build_dir, "zephyr.hex")
gdb_elf_path = os.path.join(build_dir, "zephyr_gdb.elf")
if os.path.exists(bin_path):
# Вычисляем реальный размер прошивки
image_size = os.path.getsize(bin_path)
# Шаг A: Патчим Boot Data Length (смещение 0x24) в сыром бинарнике
with open(bin_path, "r+b") as f:
f.seek(0x24)
f.write(struct.pack("<I", image_size))
print(f"[LMA Filter] Patched Boot Data Length: {image_size} bytes")
# Шаг B: Генерируем ПРАВИЛЬНЫЙ zephyr.hex, принудительно смещая ВСЁ содержимое на 0x60000000.
# Вместо изменения секций, мы берем готовый сырой бинарник (в котором адресов нет)
# и упаковываем его в HEX-формат с базового адреса Flash-памяти!
gen_hex_cmd = [
real_objcopy,
"-I", "binary",
"-O", "ihex",
"--change-addresses", "0x60000000",
bin_path,
hex_path
]
subprocess.run(gen_hex_cmd, check=True)
print("[LMA Filter] Successfully generated global 0x60000000 LMA shifted zephyr.hex")
# Шаг C: Создаем корректный ELF для GDB отладчика.
# Чтобы objcopy не ругался на сегменты, мы смещаем не отдельные секции,
# а ВСЕ программные сегменты (Program Headers) целиком!
gen_elf_cmd = [
real_objcopy,
"--change-addresses", "-0x20000000", # Сдвигаем LMA/VMA глобально для отладчика
elf_path,
gdb_elf_path
]
try:
subprocess.run(gen_elf_cmd, check=True)
print(f"[LMA Filter] Successfully generated non-corrupted {gdb_elf_path} for GDB")
except Exception as e:
print(f"[LMA Filter] GDB ELF Generation skipped/failed: {e}")
if __name__ == "__main__":
main()