#!/usr/bin/env python3 # # Build ATF image file # # Copyright (c) 2019 Actions Semiconductor Co., Ltd # # SPDX-License-Identifier: Apache-2.0 # import os import sys import struct import argparse import zlib ATF_DATA_ALIGN_SIZE = 512 ATF_MAX_FILE_CNT = 15 ATF_VERSION = 0x01000000 ''' /* ATF image */ typedef struct { uint8 magic[8]; uint8 sdk_version[4]; uint8 file_total; uint8 reserved[19]; atf_dir_t atf_dir[15]; }atf_head_t; typedef struct { uint8 filename[12]; uint8 reserved1[4]; uint32 offset; uint32 length; uint8 reserved2[4]; uint32 checksum; }atf_dir_t; ''' class atf_dir: def __init__(self): self.name = '' self.offset = 0 self.length = 0 self.aligned_length = 0 self.checksum = 0 self.data = None atf_file_list = [] cur_data_offset = ATF_DATA_ALIGN_SIZE atf_header = None def atf_add_crc(filename): if os.path.isfile(filename): # update data crc with open(filename, 'rb+') as f: #skip magic header f.read(512) crc = zlib.crc32(f.read(), 0) & 0xffffffff #update crc field in header f.seek(24) f.write(struct.pack(' 12: print('ATF: file %s name is too long' %(fpath)) return False af.length = len(fdata) if af.length == 0: print('ATF: file %s length is zero' %(fpath)) return False padsize = ATF_DATA_ALIGN_SIZE - af.length % ATF_DATA_ALIGN_SIZE af.aligned_length = af.length + padsize af.data = fdata + bytearray(padsize) af.offset = cur_data_offset # caculate file crc af.checksum = zlib.crc32(fdata, 0) & 0xffffffff cur_data_offset = cur_data_offset + af.aligned_length atf_file_list.append(af) return True def atf_gen_header(): global atf_header atf_dir = bytearray(0) if len(atf_file_list) == 0: return; for af in atf_file_list: atf_dir = atf_dir + struct.pack('<12s4xII4xI', af.name.encode('utf8'), \ af.offset, af.length, af.checksum) total_len = cur_data_offset atf_header = bytearray("ACTTEST0", 'utf8') + \ struct.pack(' ATF_MAX_FILE_CNT: print('ATF: too much input files') sys.exit(1) for input_file in args.input_files: if not os.path.isfile(input_file): continue print('ATF: Add file: %s' %input_file) if atf_add_file(input_file) != True: sys.exit(1) atf_gen_header() # write the merged property file with open(args.output_file, 'wb+') as f: f.write(atf_header) for af in atf_file_list: f.write(af.data) atf_add_crc(args.output_file) if __name__ == "__main__": main(sys.argv)