#!/usr/bin/env python3 # Copyright 2023 The ChromiumOS Authors # SPDX-License-Identifier: Apache-2.0 import sys import struct import elftools.elf.elffile import elftools.elf.sections # Converts a zephyr.elf file into an extremely simple "image format" # for device loading. Really we should just load the ELF file # directly, but the python ChromeOS test image lacks elftools. Longer # term we should probably just use rimage, but that's significantly # harder to parse. # # Format: # # 1. Three LE 32 bit words: MagicNumber, SRAM len, BootAddress # 2. Two byte arrays: SRAM (length specified), and DRAM (remainder of file) # # No padding or uninterpreted bytes. FILE_MAGIC = 0xe463be95 SRAM_START = 0x40000000 SRAM_END = 0x40040000 DRAM_START = 0x60000000 DRAM_END = 0x61100000 elf_file = sys.argv[1] out_file = sys.argv[2] ef = elftools.elf.elffile.ELFFile(open(elf_file, "rb")) sram = bytearray() dram = bytearray() for seg in ef.iter_segments(): h = seg.header if h.p_type == "PT_LOAD": if h.p_paddr in range(SRAM_START, SRAM_END): buf = sram off = h.p_paddr - SRAM_START elif h.p_paddr in range(DRAM_START, DRAM_END): buf = dram off = h.p_paddr - DRAM_START else: print(f"Invalid PT_LOAD address {h.p_paddr:x}") sys.exit(1) dat = seg.data() end = off + len(dat) if end > len(buf): buf.extend(b'\x00' * (end - len(buf))) for i in range(len(dat)): buf[i + off] = dat[i] for sec in ef.iter_sections(): if isinstance(sec, elftools.elf.sections.SymbolTableSection): for sym in sec.iter_symbols(): if sym.name == "mtk_adsp_boot_entry": boot_vector = sym.entry['st_value'] assert len(sram) < SRAM_END - SRAM_START assert len(dram) < DRAM_END - DRAM_START assert (SRAM_START <= boot_vector < SRAM_END) or (DRAM_START <= boot_vector < DRAM_END) of = open(out_file, "wb") of.write(struct.pack("