[U-Boot] [PATCH v2 1/2] rockchip: make_fit_atf.py: Eliminate pyelftools dependency

Andy Yan andy.yan at rock-chips.com
Tue Jul 16 08:45:24 UTC 2019


Hi Chris:

On 7/14/19 4:46 PM, Chris Webb wrote:
> 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 at arachsys.com>
> ---
>   arch/arm/mach-rockchip/make_fit_atf.py | 75 +++++++++++---------------
>   1 file changed, 32 insertions(+), 43 deletions(-)
>
> diff --git a/arch/arm/mach-rockchip/make_fit_atf.py b/arch/arm/mach-rockchip/make_fit_atf.py
> index db0ae96ca8..9acc1edfc6 100755
> --- a/arch/arm/mach-rockchip/make_fit_atf.py
> +++ b/arch/arm/mach-rockchip/make_fit_atf.py
> @@ -13,16 +13,7 @@ import os
>   import sys
>   import getopt
>   import logging
> -
> -# 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 struct
>   
>   DT_HEADER = """
>   /*
> @@ -118,33 +109,19 @@ def append_conf_node(file, dtbs, segments):
>       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.
> @@ -162,17 +139,29 @@ def generate_atf_fit_dts(fit_file_name, bl31_file_name, uboot_file_name, dtbs_fi
>           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


One small coding style issue:

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"
>
>




More information about the U-Boot mailing list