xref: /optee_os/core/arch/arm/plat-stm32mp1/scripts/stm32image.py (revision ed4b5e39c96bd035788ff4f07c87232d934c1264)
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