]> git.ipfire.org Git - thirdparty/u-boot.git/blame - tools/binman/etype/mkimage.py
Merge branch 'next'
[thirdparty/u-boot.git] / tools / binman / etype / mkimage.py
CommitLineData
0dc706fe
SG
1# SPDX-License-Identifier: GPL-2.0+
2# Copyright (c) 2016 Google, Inc
3# Written by Simon Glass <sjg@chromium.org>
4#
5# Entry-type module for producing an image using mkimage
6#
7
8from collections import OrderedDict
9
10from binman.entry import Entry
11from dtoc import fdt_util
4583c002 12from u_boot_pylib import tools
0dc706fe
SG
13
14class Entry_mkimage(Entry):
96d340e9 15 """Binary produced by mkimage
0dc706fe
SG
16
17 Properties / Entry arguments:
e9b5e31a 18 - args: Arguments to pass
dfe1db40
SG
19 - data-to-imagename: Indicates that the -d data should be passed in as
20 the image name also (-n)
4d91df05
QS
21 - multiple-data-files: boolean to tell binman to pass all files as
22 datafiles to mkimage instead of creating a temporary file the result
23 of datafiles concatenation
6cc29dc8 24 - filename: filename of output binary generated by mkimage
0dc706fe 25
e9b5e31a
SG
26 The data passed to mkimage via the -d flag is collected from subnodes of the
27 mkimage node, e.g.::
0dc706fe
SG
28
29 mkimage {
6cc29dc8 30 filename = "imximage.bin";
0dc706fe
SG
31 args = "-n test -T imximage";
32
33 u-boot-spl {
34 };
35 };
36
e9b5e31a
SG
37 This calls mkimage to create an imximage with `u-boot-spl.bin` as the data
38 file, with mkimage being called like this::
39
40 mkimage -d <data_file> -n test -T imximage <output_file>
41
42 The output from mkimage then becomes part of the image produced by
6cc29dc8
QS
43 binman but also is written into `imximage.bin` file. If you need to put
44 multiple things in the data file, you can use a section, or just multiple
45 subnodes like this::
e9b5e31a
SG
46
47 mkimage {
48 args = "-n test -T imximage";
49
50 u-boot-spl {
51 };
52
53 u-boot-tpl {
54 };
55 };
56
57 Note that binman places the contents (here SPL and TPL) into a single file
58 and passes that to mkimage using the -d option.
5c044ff5 59
237ac96a 60 To pass all datafiles untouched to mkimage::
4d91df05 61
237ac96a
SG
62 mkimage {
63 args = "-n rk3399 -T rkspi";
64 multiple-data-files;
4d91df05 65
237ac96a
SG
66 u-boot-tpl {
67 };
4d91df05 68
237ac96a
SG
69 u-boot-spl {
70 };
71 };
4d91df05 72
237ac96a
SG
73 This calls mkimage to create a Rockchip RK3399-specific first stage
74 bootloader, made of TPL+SPL. Since this first stage bootloader requires to
75 align the TPL and SPL but also some weird hacks that is handled by mkimage
76 directly, binman is told to not perform the concatenation of datafiles prior
77 to passing the data to mkimage.
4d91df05 78
5c044ff5
SG
79 To use CONFIG options in the arguments, use a string list instead, as in
80 this example which also produces four arguments::
81
82 mkimage {
83 args = "-n", CONFIG_SYS_SOC, "-T imximage";
84
85 u-boot-spl {
86 };
87 };
88
dfe1db40
SG
89 If you need to pass the input data in with the -n argument as well, then use
90 the 'data-to-imagename' property::
91
92 mkimage {
93 args = "-T imximage";
94 data-to-imagename;
95
96 u-boot-spl {
97 };
98 };
99
100 That will pass the data to mkimage both as the data file (with -d) and as
101 the image name (with -n). In both cases, a filename is passed as the
102 argument, with the actual data being in that file.
9db9e932
SG
103
104 If need to pass different data in with -n, then use an `imagename` subnode::
105
106 mkimage {
107 args = "-T imximage";
108
109 imagename {
110 blob {
111 filename = "spl/u-boot-spl.cfgout"
112 };
113 };
114
115 u-boot-spl {
116 };
117 };
118
119 This will pass in u-boot-spl as the input data and the .cfgout file as the
120 -n data.
0dc706fe
SG
121 """
122 def __init__(self, section, etype, node):
34861d50 123 super().__init__(section, etype, node)
4d91df05 124 self._multiple_data_files = fdt_util.GetBool(self._node, 'multiple-data-files')
0dc706fe 125 self._mkimage_entries = OrderedDict()
9db9e932 126 self._imagename = None
6cc29dc8 127 self._filename = fdt_util.GetString(self._node, 'filename')
5ff9fedc 128 self.align_default = None
1c65a54d
SG
129
130 def ReadNode(self):
131 super().ReadNode()
132 self._args = fdt_util.GetArgs(self._node, 'args')
dfe1db40
SG
133 self._data_to_imagename = fdt_util.GetBool(self._node,
134 'data-to-imagename')
9db9e932
SG
135 if self._data_to_imagename and self._node.FindNode('imagename'):
136 self.Raise('Cannot use both imagename node and data-to-imagename')
5bf81216 137 self.ReadEntries()
0dc706fe 138
1c65a54d
SG
139 def ReadEntries(self):
140 """Read the subnodes to find out what should go in this image"""
141 for node in self._node.subnodes:
142 entry = Entry.Create(self, node)
143 entry.ReadNode()
9db9e932
SG
144 if entry.name == 'imagename':
145 self._imagename = entry
146 else:
147 self._mkimage_entries[entry.name] = entry
1c65a54d 148
0dc706fe 149 def ObtainContents(self):
72e423c6 150 # Use a non-zero size for any fake files to keep mkimage happy
dfe1db40 151 # Note that testMkimageImagename() relies on this 'mkimage' parameter
4d91df05
QS
152 fake_size = 1024
153 if self._multiple_data_files:
154 fnames = []
155 uniq = self.GetUniqueName()
156 for entry in self._mkimage_entries.values():
157 if not entry.ObtainContents(fake_size=fake_size):
158 return False
40389c2a
JK
159 if entry._pathname:
160 fnames.append(entry._pathname)
4d91df05
QS
161 input_fname = ":".join(fnames)
162 else:
163 data, input_fname, uniq = self.collect_contents_to_file(
164 self._mkimage_entries.values(), 'mkimage', fake_size)
165 if data is None:
166 return False
9db9e932
SG
167 if self._imagename:
168 image_data, imagename_fname, _ = self.collect_contents_to_file(
169 [self._imagename], 'mkimage-n', 1024)
170 if image_data is None:
171 return False
6cc29dc8
QS
172 outfile = self._filename if self._filename else 'mkimage-out.%s' % uniq
173 output_fname = tools.get_output_filename(outfile)
dfe1db40 174
40389c2a
JK
175 missing_list = []
176 self.CheckMissing(missing_list)
177 self.missing = bool(missing_list)
178 if self.missing:
179 self.SetContents(b'')
180 return self.allow_missing
181
dfe1db40
SG
182 args = ['-d', input_fname]
183 if self._data_to_imagename:
184 args += ['-n', input_fname]
9db9e932
SG
185 elif self._imagename:
186 args += ['-n', imagename_fname]
dfe1db40
SG
187 args += self._args + [output_fname]
188 if self.mkimage.run_cmd(*args) is not None:
c1aa66e7 189 self.SetContents(tools.read_file(output_fname))
f75db1e9
SG
190 else:
191 # Bintool is missing; just use the input data as the output
192 self.record_missing_bintool(self.mkimage)
193 self.SetContents(data)
194
0dc706fe
SG
195 return True
196
d626e825
SG
197 def GetEntries(self):
198 # Make a copy so we don't change the original
199 entries = OrderedDict(self._mkimage_entries)
200 if self._imagename:
201 entries['imagename'] = self._imagename
202 return entries
203
72e423c6
SG
204 def SetAllowMissing(self, allow_missing):
205 """Set whether a section allows missing external blobs
206
207 Args:
208 allow_missing: True if allowed, False if not allowed
209 """
210 self.allow_missing = allow_missing
211 for entry in self._mkimage_entries.values():
212 entry.SetAllowMissing(allow_missing)
9db9e932
SG
213 if self._imagename:
214 self._imagename.SetAllowMissing(allow_missing)
72e423c6 215
a89c8f21
HT
216 def SetAllowFakeBlob(self, allow_fake):
217 """Set whether the sub nodes allows to create a fake blob
218
219 Args:
220 allow_fake: True if allowed, False if not allowed
221 """
222 for entry in self._mkimage_entries.values():
223 entry.SetAllowFakeBlob(allow_fake)
9db9e932
SG
224 if self._imagename:
225 self._imagename.SetAllowFakeBlob(allow_fake)
a89c8f21 226
40389c2a
JK
227 def CheckMissing(self, missing_list):
228 """Check if any entries in this section have missing external blobs
229
230 If there are missing (non-optional) blobs, the entries are added to the
231 list
232
233 Args:
234 missing_list: List of Entry objects to be added to
235 """
236 for entry in self._mkimage_entries.values():
237 entry.CheckMissing(missing_list)
238 if self._imagename:
239 self._imagename.CheckMissing(missing_list)
240
a89c8f21
HT
241 def CheckFakedBlobs(self, faked_blobs_list):
242 """Check if any entries in this section have faked external blobs
243
244 If there are faked blobs, the entries are added to the list
245
246 Args:
247 faked_blobs_list: List of Entry objects to be added to
248 """
249 for entry in self._mkimage_entries.values():
250 entry.CheckFakedBlobs(faked_blobs_list)
9db9e932
SG
251 if self._imagename:
252 self._imagename.CheckFakedBlobs(faked_blobs_list)
f75db1e9 253
ae9a4570 254 def AddBintools(self, btools):
a5559651 255 super().AddBintools(btools)
ae9a4570 256 self.mkimage = self.AddBintool(btools, 'mkimage')