#!/usr/bin/env python3
import sys
import subprocess
import os
import struct
def patch_boot_data_length(bin_path, final_length):
if not os.path.exists(bin_path):
return
try:
with open(bin_path, "r+b") as f:
f.seek(0x24) # Фиксированное смещение NXP Boot Data Length
f.write(struct.pack("<I", final_length))
print(f"[LMA Filter] BootROM Patch: Successfully updated Boot Data Length to {final_length} bytes ({hex(final_length)})")
except Exception as e:
print(f"[LMA Filter] BootROM Patch Error: {e}")
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:]
elf_path = "zephyr.elf"
for arg in args:
if arg.endswith("zephyr.elf"):
elf_path = arg
break
# 1. Даем Zephyr выполнить стандартную команду objcopy
final_cmd = [real_objcopy] + args
subprocess.run(final_cmd, check=True)
# 2. Перехватываем этап финальной генерации HEX-файла
if "--output-target=ihex" in " ".join(args) and os.path.exists(elf_path):
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")
# Шаг А: Линейно сдвигаем LMA всех секций и сегментов прошивки на 0x20000000 вниз
# Это превратит LMA 0x80000000 в 0x60000000, а 0x81000000 в 0x61000000 в точности как в эталоне!
print("[LMA Filter] Global LMA shifting applied via Segment Translation...")
shift_hex_cmd = [
real_objcopy,
"--change-addresses", "-0x20000000",
elf_path,
hex_path
]
subprocess.run(shift_hex_cmd, check=True)
# Шаг Б: Создаем точно такой же сдвинутый ELF-файл для GDB отладчика
shift_elf_cmd = [
real_objcopy,
"--change-addresses", "-0x20000000",
elf_path,
gdb_elf_path
]
try:
subprocess.run(shift_elf_cmd, check=True)
print(f"[LMA Filter] Successfully generated shifted {gdb_elf_path} for GDB")
except Exception as e:
print(f"[LMA Filter] GDB ELF Generation skipped/failed: {e}")
# Шаг В: Корректируем Boot Data Length в бинарнике
if os.path.exists(bin_path):
image_size = os.path.getsize(bin_path)
patch_boot_data_length(bin_path, image_size)
if __name__ == "__main__":
main()