]>
Commit | Line | Data |
---|---|---|
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 | ||
8 | from collections import OrderedDict | |
9 | ||
10 | from binman.entry import Entry | |
11 | from dtoc import fdt_util | |
4583c002 | 12 | from u_boot_pylib import tools |
0dc706fe SG |
13 | |
14 | class 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') |