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