import os
import sys
import getopt
-
-# pip install pyelftools
-from elftools.elf.elffile import ELFFile
-
-ELF_SEG_P_TYPE = 'p_type'
-ELF_SEG_P_PADDR = 'p_paddr'
-ELF_SEG_P_VADDR = 'p_vaddr'
-ELF_SEG_P_OFFSET = 'p_offset'
-ELF_SEG_P_FILESZ = 'p_filesz'
-ELF_SEG_P_MEMSZ = 'p_memsz'
+import logging
+import struct
DT_HEADER = """
/*
file.write('\t\tconfig_%d {\n' % cnt)
file.write('\t\t\tdescription = "%s";\n' % dtname)
file.write('\t\t\tfirmware = "atf_1";\n')
- file.write('\t\t\tloadables = "uboot",')
+ file.write('\t\t\tloadables = "uboot"')
+ if segments > 1:
+ file.write(',')
for i in range(1, segments):
- file.write('"atf_%d"' % (i))
+ file.write('"atf_%d"' % (i + 1))
if i != (segments - 1):
file.write(',')
else:
file.write(';\n')
+ if segments <= 1:
+ file.write(';\n')
file.write('\t\t\tfdt = "fdt_1";\n')
file.write('\t\t};\n')
file.write('\n')
file.write('\n')
def generate_atf_fit_dts_uboot(fit_file, uboot_file_name):
- num_load_seg = 0
- p_paddr = 0xFFFFFFFF
- with open(uboot_file_name, 'rb') as uboot_file:
- uboot = ELFFile(uboot_file)
- for i in range(uboot.num_segments()):
- seg = uboot.get_segment(i)
- if seg.__getitem__(ELF_SEG_P_TYPE) == 'PT_LOAD':
- p_paddr = seg.__getitem__(ELF_SEG_P_PADDR)
- num_load_seg = num_load_seg + 1
-
- assert (p_paddr != 0xFFFFFFFF and num_load_seg == 1)
-
+ segments = unpack_elf(uboot_file_name)
+ if len(segments) != 1:
+ raise ValueError("Invalid u-boot ELF image '%s'" % uboot_file_name)
+ index, entry, p_paddr, data = segments[0]
fit_file.write(DT_UBOOT % p_paddr)
def generate_atf_fit_dts_bl31(fit_file, bl31_file_name, dtbs_file_name):
- with open(bl31_file_name, 'rb') as bl31_file:
- bl31 = ELFFile(bl31_file)
- elf_entry = bl31.header['e_entry']
- segments = bl31.num_segments()
- for i in range(segments):
- seg = bl31.get_segment(i)
- if seg.__getitem__(ELF_SEG_P_TYPE) == 'PT_LOAD':
- paddr = seg.__getitem__(ELF_SEG_P_PADDR)
- append_bl31_node(fit_file, i + 1, paddr, elf_entry)
+ segments = unpack_elf(bl31_file_name)
+ for index, entry, paddr, data in segments:
+ append_bl31_node(fit_file, index + 1, paddr, entry)
append_fdt_node(fit_file, dtbs_file_name)
fit_file.write(DT_IMAGES_NODE_END)
- append_conf_node(fit_file, dtbs_file_name, segments)
+ append_conf_node(fit_file, dtbs_file_name, len(segments))
def generate_atf_fit_dts(fit_file_name, bl31_file_name, uboot_file_name, dtbs_file_name):
# Generate FIT script for ATF image.
fit_file.close()
def generate_atf_binary(bl31_file_name):
- with open(bl31_file_name, 'rb') as bl31_file:
- bl31 = ELFFile(bl31_file)
-
- num = bl31.num_segments()
- for i in range(num):
- seg = bl31.get_segment(i)
- if seg.__getitem__(ELF_SEG_P_TYPE) == 'PT_LOAD':
- paddr = seg.__getitem__(ELF_SEG_P_PADDR)
- file_name = 'bl31_0x%08x.bin' % paddr
- with open(file_name, "wb") as atf:
- atf.write(seg.data())
+ for index, entry, paddr, data in unpack_elf(bl31_file_name):
+ file_name = 'bl31_0x%08x.bin' % paddr
+ with open(file_name, "wb") as atf:
+ atf.write(data)
+
+def unpack_elf(filename):
+ with open(filename, 'rb') as file:
+ elf = file.read()
+ if elf[0:7] != b'\x7fELF\x02\x01\x01' or elf[18:20] != b'\xb7\x00':
+ raise ValueError("Invalid arm64 ELF file '%s'" % filename)
+
+ e_entry, e_phoff = struct.unpack_from('<2Q', elf, 0x18)
+ e_phentsize, e_phnum = struct.unpack_from('<2H', elf, 0x36)
+ segments = []
+
+ for index in range(e_phnum):
+ offset = e_phoff + e_phentsize * index
+ p_type, p_flags, p_offset = struct.unpack_from('<LLQ', elf, offset)
+ if p_type == 1: # PT_LOAD
+ p_paddr, p_filesz = struct.unpack_from('<2Q', elf, offset + 0x18)
+ p_data = elf[p_offset:p_offset + p_filesz]
+ segments.append((index, e_entry, p_paddr, p_data))
+ return segments
def main():
uboot_elf = "./u-boot"
- bl31_elf = "./bl31.elf"
fit_its = sys.stdout
+ if "BL31" in os.environ:
+ bl31_elf=os.getenv("BL31");
+ elif os.path.isfile("./bl31.elf"):
+ bl31_elf = "./bl31.elf"
+ else:
+ os.system("echo 'int main(){}' > bl31.c")
+ os.system("${CROSS_COMPILE}gcc -c bl31.c -o bl31.elf")
+ bl31_elf = "./bl31.elf"
+ logging.basicConfig(format='%(levelname)s:%(message)s', level=logging.DEBUG)
+ logging.warning(' BL31 file bl31.elf NOT found, resulting binary is non-functional')
+ logging.warning(' Please read Building section in doc/README.rockchip')
opts, args = getopt.getopt(sys.argv[1:], "o:u:b:h")
for opt, val in opts: