rockchip: make_fit_atf.py: Eliminate pyelftools dependency
make_fit_aft.py depends on the non-standard library pyelftools to pull out PT_LOAD segments from ELF files. However, this is as easy to do manually, without imposing the extra dependency on users. Structures in the ELF file are unpacked into variables named to exactly match the ELF spec to ensure the destructuring code is reasonably self-documenting. Signed-off-by: Chris Webb <chris@arachsys.com> Reviewed-by: Andy Yan <andy.yan@rock-chips.com> Reviewed-by: Kever Yang <Kever.yang@rock-chips.com>
This commit is contained in:
parent
fb7b1b79c1
commit
f05d574356
@ -13,16 +13,7 @@ import os
|
|||||||
import sys
|
import sys
|
||||||
import getopt
|
import getopt
|
||||||
import logging
|
import logging
|
||||||
|
import struct
|
||||||
# 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'
|
|
||||||
|
|
||||||
DT_HEADER = """
|
DT_HEADER = """
|
||||||
/*
|
/*
|
||||||
@ -118,33 +109,19 @@ def append_conf_node(file, dtbs, segments):
|
|||||||
file.write('\n')
|
file.write('\n')
|
||||||
|
|
||||||
def generate_atf_fit_dts_uboot(fit_file, uboot_file_name):
|
def generate_atf_fit_dts_uboot(fit_file, uboot_file_name):
|
||||||
num_load_seg = 0
|
segments = unpack_elf(uboot_file_name)
|
||||||
p_paddr = 0xFFFFFFFF
|
if len(segments) != 1:
|
||||||
with open(uboot_file_name, 'rb') as uboot_file:
|
raise ValueError("Invalid u-boot ELF image '%s'" % uboot_file_name)
|
||||||
uboot = ELFFile(uboot_file)
|
index, entry, p_paddr, data = segments[0]
|
||||||
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)
|
|
||||||
|
|
||||||
fit_file.write(DT_UBOOT % p_paddr)
|
fit_file.write(DT_UBOOT % p_paddr)
|
||||||
|
|
||||||
def generate_atf_fit_dts_bl31(fit_file, bl31_file_name, dtbs_file_name):
|
def generate_atf_fit_dts_bl31(fit_file, bl31_file_name, dtbs_file_name):
|
||||||
with open(bl31_file_name, 'rb') as bl31_file:
|
segments = unpack_elf(bl31_file_name)
|
||||||
bl31 = ELFFile(bl31_file)
|
for index, entry, paddr, data in segments:
|
||||||
elf_entry = bl31.header['e_entry']
|
append_bl31_node(fit_file, index + 1, paddr, 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)
|
|
||||||
append_fdt_node(fit_file, dtbs_file_name)
|
append_fdt_node(fit_file, dtbs_file_name)
|
||||||
fit_file.write(DT_IMAGES_NODE_END)
|
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):
|
def generate_atf_fit_dts(fit_file_name, bl31_file_name, uboot_file_name, dtbs_file_name):
|
||||||
# Generate FIT script for ATF image.
|
# Generate FIT script for ATF image.
|
||||||
@ -162,17 +139,29 @@ def generate_atf_fit_dts(fit_file_name, bl31_file_name, uboot_file_name, dtbs_fi
|
|||||||
fit_file.close()
|
fit_file.close()
|
||||||
|
|
||||||
def generate_atf_binary(bl31_file_name):
|
def generate_atf_binary(bl31_file_name):
|
||||||
with open(bl31_file_name, 'rb') as bl31_file:
|
for index, entry, paddr, data in unpack_elf(bl31_file_name):
|
||||||
bl31 = ELFFile(bl31_file)
|
file_name = 'bl31_0x%08x.bin' % paddr
|
||||||
|
with open(file_name, "wb") as atf:
|
||||||
|
atf.write(data)
|
||||||
|
|
||||||
num = bl31.num_segments()
|
def unpack_elf(filename):
|
||||||
for i in range(num):
|
with open(filename, 'rb') as file:
|
||||||
seg = bl31.get_segment(i)
|
elf = file.read()
|
||||||
if seg.__getitem__(ELF_SEG_P_TYPE) == 'PT_LOAD':
|
if elf[0:7] != b'\x7fELF\x02\x01\x01' or elf[18:20] != b'\xb7\x00':
|
||||||
paddr = seg.__getitem__(ELF_SEG_P_PADDR)
|
raise ValueError("Invalid arm64 ELF file '%s'" % filename)
|
||||||
file_name = 'bl31_0x%08x.bin' % paddr
|
|
||||||
with open(file_name, "wb") as atf:
|
e_entry, e_phoff = struct.unpack_from('<2Q', elf, 0x18)
|
||||||
atf.write(seg.data())
|
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():
|
def main():
|
||||||
uboot_elf = "./u-boot"
|
uboot_elf = "./u-boot"
|
||||||
|
Loading…
Reference in New Issue
Block a user