1#!/usr/bin/env python3 2# SPDX-License-Identifier: BSD-2-Clause 3# 4# Copyright (c) 2024, Telechips Inc. 5# 6 7import sys 8from hashlib import sha256 9 10ALIGN_SIZE = 64 11FOOTER_SIZE = 128 12 13 14def calc_hash(inputfile): 15 sha = sha256() 16 inputfile.seek(0) 17 while True: 18 buf = inputfile.read(ALIGN_SIZE) 19 if len(buf) == 0: 20 break 21 sha.update(buf.ljust(ALIGN_SIZE, b'\0')) 22 return sha.digest() 23 24 25def fill_dummy_cert(outputfile): 26 outputfile.write(b'CERT'.ljust(256, b'\0')) 27 return 0 28 29 30def fill_header(outputfile, inputfile, argv): 31 imagename = bytes(argv[3], 'utf-8') 32 imageversion = bytes(argv[4], 'utf-8') 33 targetaddress = int(argv[5], 16) 34 socname = bytes(argv[6], 'utf-8') 35 inputfile.seek(0, 2) 36 offset = 4096 # Min: 256 37 length = (inputfile.tell() + (ALIGN_SIZE - 1)) & ~(ALIGN_SIZE - 1) 38 length += FOOTER_SIZE 39 buf = bytearray(offset - outputfile.tell()) 40 buf[0:4] = b'HDR\0' # Marker 41 buf[4:8] = length.to_bytes(4, byteorder='little') 42 buf[8:12] = offset.to_bytes(4, byteorder='little') 43 buf[16:20] = socname.ljust(4, b'\0')[-4:] 44 buf[20:32] = imagename.ljust(12, b'\0')[0:12] 45 buf[32:48] = imageversion.ljust(16, b'\0')[0:16] 46 buf[48:56] = targetaddress.to_bytes(8, byteorder='little') 47 buf[96:128] = calc_hash(inputfile) 48 outputfile.write(buf) 49 return 0 50 51 52def fill_image(outputfile, inputfile): 53 inputfile.seek(0) 54 while True: 55 buf = inputfile.read(ALIGN_SIZE) 56 if len(buf) == 0: 57 break 58 outputfile.write(buf.ljust(ALIGN_SIZE, b'\0')) 59 return 0 60 61 62def fill_dummy_footer(outputfile): 63 outputfile.write(bytearray(FOOTER_SIZE)) 64 return 0 65 66 67def make_image(inputfile, outputfile, argv): 68 if fill_dummy_cert(outputfile) != 0: 69 return -1 70 if fill_header(outputfile, inputfile, argv) != 0: 71 return -2 72 if fill_image(outputfile, inputfile) != 0: 73 return -3 74 if fill_dummy_footer(outputfile) != 0: 75 return -4 76 return 0 77 78 79def print_help(): 80 print("") 81 print("Telechips Image Maker") 82 print("") 83 print("Usage: python tcmktool.py [INPUT] [OUTPUT] [NAME] [VERSION]" + 84 " [TARGET_ADDRESS] [SOC_NAME]") 85 print("") 86 print(" INPUT input file name.") 87 print(" OUTPUT output file name.") 88 print(" NAME image name.") 89 print(" VERSION string version. (max 16 bytes)") 90 print(" TARGET_ADDRESS target address") 91 print(" SOC_NAME SoC name. (only the last 4 bytes are used") 92 93 94def main(argc, argv): 95 ret = -1 96 97 if argc != 7: 98 print_help() 99 return -1 100 101 try: 102 with open(argv[1], "rb") as inputfile: 103 with open(argv[2], "wb") as outputfile: 104 ret = make_image(inputfile, outputfile, argv) 105 except Exception as e: 106 if 'inputfile' not in locals(): 107 print("ERROR: input file open error\n") 108 elif 'outputfile' not in locals(): 109 print("ERROR: output file open error\n") 110 else: 111 print(e) 112 113 if ret == 0: 114 print("{} was generated successfilly\n".format(argv[2])) 115 else: 116 print("Failed to generate output file (error code: {})\n".format(ret)) 117 118 return ret 119 120 121if (__name__ == "__main__"): 122 exit(main(len(sys.argv), sys.argv)) 123