blob: 5d14f5e9d13fb100ba8c5dbd469d99f8dcc8e87f [file] [log] [blame]
#!/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("<III", FILE_MAGIC, len(sram), boot_vector))
of.write(sram)
of.write(dram)