xref: /optee_os/core/arch/arm/plat-stm32mp1/scripts/stm32image.py (revision 62f21181c547da3bd098908300e5699e9ae5cca9)
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):
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' * 84)
72        dest_fd.close()
73
74
75def stm32image_create_header_file(source, dest, load, entry):
76        dest_fd = open(dest, 'w+b')
77        src_fd = open(source, 'rb')
78
79        dest_fd.write(b'\x00' * header_size)
80
81        sizesrc = get_size(src_fd)
82        if sizesrc > 0:
83                mmsrc = mmap.mmap(src_fd.fileno(), 0, access=mmap.ACCESS_READ)
84                dest_fd.write(mmsrc[:sizesrc])
85                mmsrc.close()
86
87        src_fd.close()
88
89        stm32image_set_header(dest_fd, load, entry)
90
91        dest_fd.close()
92
93
94def int_parse(str):
95        return int(str, 0)
96
97
98def get_args():
99        parser = argparse.ArgumentParser()
100        parser.add_argument('--source',
101                            required=True,
102                            help='Source file')
103
104        parser.add_argument('--dest',
105                            required=True,
106                            help='Destination file')
107
108        parser.add_argument('--load',
109                            required=True, type=int_parse,
110                            help='Load address')
111
112        parser.add_argument('--entry',
113                            required=True, type=int_parse,
114                            help='Entry point')
115
116        return parser.parse_args()
117
118
119def main():
120        args = get_args()
121        source_file = args.source
122        destination_file = args.dest
123        load_address = args.load
124        entry_point = args.entry
125
126        stm32image_create_header_file(source_file,
127                                      destination_file,
128                                      load_address,
129                                      entry_point)
130
131
132if __name__ == "__main__":
133        main()
134