1#!/usr/bin/env python3 2# SPDX-License-Identifier: BSD-2-Clause 3# 4# Copyright (c) 2017-2018, STMicroelectronics 5# 6import argparse 7import struct 8import mmap 9 10header_size = 256 11hdr_magic_number = 0x324D5453 # magic ='S' 'T' 'M' 0x32 12hdr_header_ver_variant = 0 13hdr_header_ver_minor = 0 14hdr_header_ver_major = 1 15hdr_version_number = 0 16hdr_option_flags = 1 # bit0=1 no signature 17hdr_edcsa_algo = 1 18 19 20def get_size(file): 21 file.seek(0, 2) # End of the file 22 size = file.tell() 23 return size 24 25 26def stm32image_checksum(dest_fd, sizedest): 27 csum = 0 28 if sizedest < header_size: 29 return 0 30 dest_fd.seek(header_size, 0) 31 length = sizedest - header_size 32 while length > 0: 33 csum += ord(dest_fd.read(1)) 34 length -= 1 35 return csum 36 37 38def stm32image_set_header(dest_fd, load, entry, bintype): 39 sizedest = get_size(dest_fd) 40 41 checksum = stm32image_checksum(dest_fd, sizedest) 42 43 dest_fd.seek(0, 0) 44 45 # Magic number 46 dest_fd.write(struct.pack('<I', hdr_magic_number)) 47 48 # Image signature (empty) 49 dest_fd.write(b'\x00' * 64) 50 51 # Image checksum ... EDCSA algorithm 52 dest_fd.write(struct.pack('<IBBBBIIIIIIII', 53 checksum, 54 hdr_header_ver_variant, 55 hdr_header_ver_minor, 56 hdr_header_ver_major, 57 0, 58 sizedest - header_size, 59 entry, 60 0, 61 load, 62 0, 63 hdr_version_number, 64 hdr_option_flags, 65 hdr_edcsa_algo)) 66 67 # EDCSA public key (empty) 68 dest_fd.write(b'\x00' * 64) 69 70 # Padding 71 dest_fd.write(b'\x00' * 83) 72 dest_fd.write(struct.pack('<B', bintype)) 73 dest_fd.close() 74 75 76def stm32image_create_header_file(source, dest, load, entry, bintype): 77 dest_fd = open(dest, 'w+b') 78 src_fd = open(source, 'rb') 79 80 dest_fd.write(b'\x00' * header_size) 81 82 sizesrc = get_size(src_fd) 83 if sizesrc > 0: 84 mmsrc = mmap.mmap(src_fd.fileno(), 0, access=mmap.ACCESS_READ) 85 dest_fd.write(mmsrc[:sizesrc]) 86 mmsrc.close() 87 88 src_fd.close() 89 90 stm32image_set_header(dest_fd, load, entry, bintype) 91 92 dest_fd.close() 93 94 95def int_parse(str): 96 return int(str, 0) 97 98 99def get_args(): 100 parser = argparse.ArgumentParser() 101 parser.add_argument('--source', 102 required=True, 103 help='Source file') 104 105 parser.add_argument('--dest', 106 required=True, 107 help='Destination file') 108 109 parser.add_argument('--load', 110 required=True, type=int_parse, 111 help='Load address') 112 113 parser.add_argument('--entry', 114 required=True, type=int_parse, 115 help='Entry point') 116 117 parser.add_argument('--bintype', 118 required=True, type=int_parse, 119 help='Binary identification') 120 121 return parser.parse_args() 122 123 124def main(): 125 args = get_args() 126 source_file = args.source 127 destination_file = args.dest 128 load_address = args.load 129 entry_point = args.entry 130 binary_type = args.bintype 131 132 stm32image_create_header_file(source_file, 133 destination_file, 134 load_address, 135 entry_point, 136 binary_type) 137 138 139if __name__ == "__main__": 140 main() 141