]> Git Repo - J-u-boot.git/blame - tools/binman/control.py
binman: Fix unique names having '/.' for images read from files
[J-u-boot.git] / tools / binman / control.py
CommitLineData
83d290c5 1# SPDX-License-Identifier: GPL-2.0+
bf7fd50b
SG
2# Copyright (c) 2016 Google, Inc
3# Written by Simon Glass <[email protected]>
4#
bf7fd50b
SG
5# Creates binary images from input files controlled by a description
6#
7
8from collections import OrderedDict
87d43329 9import glob
bf7fd50b 10import os
9fbfaba0 11import pkg_resources
b238143d 12import re
9fbfaba0 13
bf7fd50b 14import sys
bf776679 15from patman import tools
bf7fd50b 16
386c63cf 17from binman import bintool
16287933
SG
18from binman import cbfs_util
19from binman import elf
bf776679
SG
20from patman import command
21from patman import tout
bf7fd50b 22
8d2ef3e9
SG
23# These are imported if needed since they import libfdt
24state = None
25Image = None
26
bf7fd50b
SG
27# List of images we plan to create
28# Make this global so that it can be referenced from tests
29images = OrderedDict()
30
b238143d
SG
31# Help text for each type of missing blob, dict:
32# key: Value of the entry's 'missing-msg' or entry name
33# value: Text for the help
34missing_blob_help = {}
35
0b6023ee 36def _ReadImageDesc(binman_node, use_expanded):
bf7fd50b
SG
37 """Read the image descriptions from the /binman node
38
39 This normally produces a single Image object called 'image'. But if
40 multiple images are present, they will all be returned.
41
42 Args:
43 binman_node: Node object of the /binman node
0b6023ee 44 use_expanded: True if the FDT will be updated with the entry information
bf7fd50b
SG
45 Returns:
46 OrderedDict of Image objects, each of which describes an image
47 """
8d2ef3e9
SG
48 # For Image()
49 # pylint: disable=E1102
bf7fd50b
SG
50 images = OrderedDict()
51 if 'multiple-images' in binman_node.props:
52 for node in binman_node.subnodes:
0b6023ee
SG
53 images[node.name] = Image(node.name, node,
54 use_expanded=use_expanded)
bf7fd50b 55 else:
0b6023ee 56 images['image'] = Image('image', binman_node, use_expanded=use_expanded)
bf7fd50b
SG
57 return images
58
ec3f378a 59def _FindBinmanNode(dtb):
bf7fd50b
SG
60 """Find the 'binman' node in the device tree
61
62 Args:
ec3f378a 63 dtb: Fdt object to scan
bf7fd50b
SG
64 Returns:
65 Node object of /binman node, or None if not found
66 """
ec3f378a 67 for node in dtb.GetRoot().subnodes:
bf7fd50b
SG
68 if node.name == 'binman':
69 return node
70 return None
71
b238143d
SG
72def _ReadMissingBlobHelp():
73 """Read the missing-blob-help file
74
75 This file containins help messages explaining what to do when external blobs
76 are missing.
77
78 Returns:
79 Dict:
80 key: Message tag (str)
81 value: Message text (str)
82 """
83
84 def _FinishTag(tag, msg, result):
85 if tag:
86 result[tag] = msg.rstrip()
87 tag = None
88 msg = ''
89 return tag, msg
90
91 my_data = pkg_resources.resource_string(__name__, 'missing-blob-help')
92 re_tag = re.compile('^([-a-z0-9]+):$')
93 result = {}
94 tag = None
95 msg = ''
96 for line in my_data.decode('utf-8').splitlines():
97 if not line.startswith('#'):
98 m_tag = re_tag.match(line)
99 if m_tag:
100 _, msg = _FinishTag(tag, msg, result)
101 tag = m_tag.group(1)
102 elif tag:
103 msg += line + '\n'
104 _FinishTag(tag, msg, result)
105 return result
106
107def _ShowBlobHelp(path, text):
f3385a5b 108 tout.warning('\n%s:' % path)
b238143d 109 for line in text.splitlines():
f3385a5b 110 tout.warning(' %s' % line)
b238143d
SG
111
112def _ShowHelpForMissingBlobs(missing_list):
113 """Show help for each missing blob to help the user take action
114
115 Args:
116 missing_list: List of Entry objects to show help for
117 """
118 global missing_blob_help
119
120 if not missing_blob_help:
121 missing_blob_help = _ReadMissingBlobHelp()
122
123 for entry in missing_list:
124 tags = entry.GetHelpTags()
125
126 # Show the first match help message
127 for tag in tags:
128 if tag in missing_blob_help:
129 _ShowBlobHelp(entry._node.path, missing_blob_help[tag])
130 break
131
87d43329
SG
132def GetEntryModules(include_testing=True):
133 """Get a set of entry class implementations
134
135 Returns:
136 Set of paths to entry class filenames
137 """
9fbfaba0
SG
138 glob_list = pkg_resources.resource_listdir(__name__, 'etype')
139 glob_list = [fname for fname in glob_list if fname.endswith('.py')]
87d43329
SG
140 return set([os.path.splitext(os.path.basename(item))[0]
141 for item in glob_list
142 if include_testing or '_testing' not in item])
143
c55a50f5
SG
144def WriteEntryDocs(modules, test_missing=None):
145 """Write out documentation for all entries
ecab8973
SG
146
147 Args:
c55a50f5 148 modules: List of Module objects to get docs for
bc570646 149 test_missing: Used for testing only, to force an entry's documentation
c55a50f5
SG
150 to show as missing even if it is present. Should be set to None in
151 normal use.
ecab8973 152 """
16287933 153 from binman.entry import Entry
fd8d1f79
SG
154 Entry.WriteDocs(modules, test_missing)
155
61f564d1 156
bc570646
SG
157def write_bintool_docs(modules, test_missing=None):
158 """Write out documentation for all bintools
159
160 Args:
161 modules: List of Module objects to get docs for
162 test_missing: Used for testing only, to force an entry's documentation
163 to show as missing even if it is present. Should be set to None in
164 normal use.
165 """
166 bintool.Bintool.WriteDocs(modules, test_missing)
167
168
61f564d1
SG
169def ListEntries(image_fname, entry_paths):
170 """List the entries in an image
171
172 This decodes the supplied image and displays a table of entries from that
173 image, preceded by a header.
174
175 Args:
176 image_fname: Image filename to process
177 entry_paths: List of wildcarded paths (e.g. ['*dtb*', 'u-boot*',
178 'section/u-boot'])
179 """
180 image = Image.FromFile(image_fname)
181
182 entries, lines, widths = image.GetListEntries(entry_paths)
183
184 num_columns = len(widths)
185 for linenum, line in enumerate(lines):
186 if linenum == 1:
187 # Print header line
188 print('-' * (sum(widths) + num_columns * 2))
189 out = ''
190 for i, item in enumerate(line):
191 width = -widths[i]
192 if item.startswith('>'):
193 width = -width
194 item = item[1:]
195 txt = '%*s ' % (width, item)
196 out += txt
197 print(out.rstrip())
198
f667e45b
SG
199
200def ReadEntry(image_fname, entry_path, decomp=True):
201 """Extract an entry from an image
202
203 This extracts the data from a particular entry in an image
204
205 Args:
206 image_fname: Image filename to process
207 entry_path: Path to entry to extract
208 decomp: True to return uncompressed data, if the data is compress
209 False to return the raw data
210
211 Returns:
212 data extracted from the entry
213 """
8dbb7444 214 global Image
07237988 215 from binman.image import Image
8dbb7444 216
f667e45b
SG
217 image = Image.FromFile(image_fname)
218 entry = image.FindEntryPath(entry_path)
219 return entry.ReadData(decomp)
220
221
943bf78a
SG
222def ShowAltFormats(image):
223 """Show alternative formats available for entries in the image
224
225 This shows a list of formats available.
226
227 Args:
228 image (Image): Image to check
229 """
230 alt_formats = {}
231 image.CheckAltFormats(alt_formats)
232 print('%-10s %-20s %s' % ('Flag (-F)', 'Entry type', 'Description'))
233 for name, val in alt_formats.items():
234 entry, helptext = val
235 print('%-10s %-20s %s' % (name, entry.etype, helptext))
236
237
71ce0ba2 238def ExtractEntries(image_fname, output_fname, outdir, entry_paths,
943bf78a 239 decomp=True, alt_format=None):
71ce0ba2
SG
240 """Extract the data from one or more entries and write it to files
241
242 Args:
243 image_fname: Image filename to process
244 output_fname: Single output filename to use if extracting one file, None
245 otherwise
246 outdir: Output directory to use (for any number of files), else None
247 entry_paths: List of entry paths to extract
3ad804e6 248 decomp: True to decompress the entry data
71ce0ba2
SG
249
250 Returns:
251 List of EntryInfo records that were written
252 """
253 image = Image.FromFile(image_fname)
254
943bf78a
SG
255 if alt_format == 'list':
256 ShowAltFormats(image)
257 return
258
71ce0ba2
SG
259 # Output an entry to a single file, as a special case
260 if output_fname:
261 if not entry_paths:
bb5edc1d 262 raise ValueError('Must specify an entry path to write with -f')
71ce0ba2 263 if len(entry_paths) != 1:
bb5edc1d 264 raise ValueError('Must specify exactly one entry path to write with -f')
71ce0ba2 265 entry = image.FindEntryPath(entry_paths[0])
943bf78a 266 data = entry.ReadData(decomp, alt_format)
c1aa66e7 267 tools.write_file(output_fname, data)
f3385a5b 268 tout.notice("Wrote %#x bytes to file '%s'" % (len(data), output_fname))
71ce0ba2
SG
269 return
270
271 # Otherwise we will output to a path given by the entry path of each entry.
272 # This means that entries will appear in subdirectories if they are part of
273 # a sub-section.
274 einfos = image.GetListEntries(entry_paths)[0]
f3385a5b 275 tout.notice('%d entries match and will be written' % len(einfos))
71ce0ba2
SG
276 for einfo in einfos:
277 entry = einfo.entry
943bf78a 278 data = entry.ReadData(decomp, alt_format)
71ce0ba2
SG
279 path = entry.GetPath()[1:]
280 fname = os.path.join(outdir, path)
281
282 # If this entry has children, create a directory for it and put its
283 # data in a file called 'root' in that directory
284 if entry.GetEntries():
862ddf91 285 if fname and not os.path.exists(fname):
71ce0ba2
SG
286 os.makedirs(fname)
287 fname = os.path.join(fname, 'root')
f3385a5b 288 tout.notice("Write entry '%s' size %x to '%s'" %
5b378e4d 289 (entry.GetPath(), len(data), fname))
c1aa66e7 290 tools.write_file(fname, data)
71ce0ba2
SG
291 return einfos
292
293
d7fa4e4b
SG
294def BeforeReplace(image, allow_resize):
295 """Handle getting an image ready for replacing entries in it
296
297 Args:
298 image: Image to prepare
299 """
300 state.PrepareFromLoadedData(image)
301 image.LoadData()
302
303 # If repacking, drop the old offset/size values except for the original
304 # ones, so we are only left with the constraints.
305 if allow_resize:
306 image.ResetForPack()
307
308
309def ReplaceOneEntry(image, entry, data, do_compress, allow_resize):
310 """Handle replacing a single entry an an image
311
312 Args:
313 image: Image to update
314 entry: Entry to write
315 data: Data to replace with
316 do_compress: True to compress the data if needed, False if data is
317 already compressed so should be used as is
318 allow_resize: True to allow entries to change size (this does a re-pack
319 of the entries), False to raise an exception
320 """
321 if not entry.WriteData(data, do_compress):
322 if not image.allow_repack:
323 entry.Raise('Entry data size does not match, but allow-repack is not present for this image')
324 if not allow_resize:
325 entry.Raise('Entry data size does not match, but resize is disabled')
326
327
328def AfterReplace(image, allow_resize, write_map):
329 """Handle write out an image after replacing entries in it
330
331 Args:
332 image: Image to write
333 allow_resize: True to allow entries to change size (this does a re-pack
334 of the entries), False to raise an exception
335 write_map: True to write a map file
336 """
f3385a5b 337 tout.info('Processing image')
d7fa4e4b
SG
338 ProcessImage(image, update_fdt=True, write_map=write_map,
339 get_contents=False, allow_resize=allow_resize)
340
341
342def WriteEntryToImage(image, entry, data, do_compress=True, allow_resize=True,
343 write_map=False):
344 BeforeReplace(image, allow_resize)
f3385a5b 345 tout.info('Writing data to %s' % entry.GetPath())
d7fa4e4b
SG
346 ReplaceOneEntry(image, entry, data, do_compress, allow_resize)
347 AfterReplace(image, allow_resize=allow_resize, write_map=write_map)
348
349
3ad804e6
SG
350def WriteEntry(image_fname, entry_path, data, do_compress=True,
351 allow_resize=True, write_map=False):
22a76b74
SG
352 """Replace an entry in an image
353
354 This replaces the data in a particular entry in an image. This size of the
355 new data must match the size of the old data unless allow_resize is True.
356
357 Args:
358 image_fname: Image filename to process
359 entry_path: Path to entry to extract
360 data: Data to replace with
3ad804e6 361 do_compress: True to compress the data if needed, False if data is
22a76b74
SG
362 already compressed so should be used as is
363 allow_resize: True to allow entries to change size (this does a re-pack
364 of the entries), False to raise an exception
3ad804e6 365 write_map: True to write a map file
22a76b74
SG
366
367 Returns:
368 Image object that was updated
369 """
f3385a5b 370 tout.info("Write entry '%s', file '%s'" % (entry_path, image_fname))
22a76b74
SG
371 image = Image.FromFile(image_fname)
372 entry = image.FindEntryPath(entry_path)
d7fa4e4b
SG
373 WriteEntryToImage(image, entry, data, do_compress=do_compress,
374 allow_resize=allow_resize, write_map=write_map)
22a76b74 375
22a76b74
SG
376 return image
377
a6cb9950
SG
378
379def ReplaceEntries(image_fname, input_fname, indir, entry_paths,
380 do_compress=True, allow_resize=True, write_map=False):
381 """Replace the data from one or more entries from input files
382
383 Args:
384 image_fname: Image filename to process
89cc0520 385 input_fname: Single input filename to use if replacing one file, None
a6cb9950
SG
386 otherwise
387 indir: Input directory to use (for any number of files), else None
89cc0520 388 entry_paths: List of entry paths to replace
a6cb9950
SG
389 do_compress: True if the input data is uncompressed and may need to be
390 compressed if the entry requires it, False if the data is already
391 compressed.
392 write_map: True to write a map file
393
394 Returns:
395 List of EntryInfo records that were written
396 """
c700f109 397 image_fname = os.path.abspath(image_fname)
a6cb9950
SG
398 image = Image.FromFile(image_fname)
399
400 # Replace an entry from a single file, as a special case
401 if input_fname:
402 if not entry_paths:
403 raise ValueError('Must specify an entry path to read with -f')
404 if len(entry_paths) != 1:
405 raise ValueError('Must specify exactly one entry path to write with -f')
406 entry = image.FindEntryPath(entry_paths[0])
c1aa66e7 407 data = tools.read_file(input_fname)
f3385a5b 408 tout.notice("Read %#x bytes from file '%s'" % (len(data), input_fname))
a6cb9950
SG
409 WriteEntryToImage(image, entry, data, do_compress=do_compress,
410 allow_resize=allow_resize, write_map=write_map)
411 return
412
413 # Otherwise we will input from a path given by the entry path of each entry.
414 # This means that files must appear in subdirectories if they are part of
415 # a sub-section.
416 einfos = image.GetListEntries(entry_paths)[0]
f3385a5b 417 tout.notice("Replacing %d matching entries in image '%s'" %
a6cb9950
SG
418 (len(einfos), image_fname))
419
420 BeforeReplace(image, allow_resize)
421
422 for einfo in einfos:
423 entry = einfo.entry
424 if entry.GetEntries():
f3385a5b 425 tout.info("Skipping section entry '%s'" % entry.GetPath())
a6cb9950
SG
426 continue
427
428 path = entry.GetPath()[1:]
429 fname = os.path.join(indir, path)
430
431 if os.path.exists(fname):
f3385a5b 432 tout.notice("Write entry '%s' from file '%s'" %
a6cb9950 433 (entry.GetPath(), fname))
c1aa66e7 434 data = tools.read_file(fname)
a6cb9950
SG
435 ReplaceOneEntry(image, entry, data, do_compress, allow_resize)
436 else:
f3385a5b 437 tout.warning("Skipping entry '%s' from missing file '%s'" %
a6cb9950
SG
438 (entry.GetPath(), fname))
439
440 AfterReplace(image, allow_resize=allow_resize, write_map=write_map)
441 return image
442
443
0b6023ee 444def PrepareImagesAndDtbs(dtb_fname, select_images, update_fdt, use_expanded):
a8573c4c
SG
445 """Prepare the images to be processed and select the device tree
446
447 This function:
448 - reads in the device tree
449 - finds and scans the binman node to create all entries
450 - selects which images to build
451 - Updates the device tress with placeholder properties for offset,
452 image-pos, etc.
453
454 Args:
455 dtb_fname: Filename of the device tree file to use (.dts or .dtb)
456 selected_images: List of images to output, or None for all
457 update_fdt: True to update the FDT wth entry offsets, etc.
0b6023ee
SG
458 use_expanded: True to use expanded versions of entries, if available.
459 So if 'u-boot' is called for, we use 'u-boot-expanded' instead. This
460 is needed if update_fdt is True (although tests may disable it)
e9d336d8
SG
461
462 Returns:
463 OrderedDict of images:
464 key: Image name (str)
465 value: Image object
a8573c4c
SG
466 """
467 # Import these here in case libfdt.py is not available, in which case
468 # the above help option still works.
16287933
SG
469 from dtoc import fdt
470 from dtoc import fdt_util
a8573c4c
SG
471 global images
472
473 # Get the device tree ready by compiling it and copying the compiled
474 # output into a file in our output directly. Then scan it for use
475 # in binman.
476 dtb_fname = fdt_util.EnsureCompiled(dtb_fname)
c1aa66e7
SG
477 fname = tools.get_output_filename('u-boot.dtb.out')
478 tools.write_file(fname, tools.read_file(dtb_fname))
a8573c4c
SG
479 dtb = fdt.FdtScan(fname)
480
481 node = _FindBinmanNode(dtb)
482 if not node:
483 raise ValueError("Device tree '%s' does not have a 'binman' "
484 "node" % dtb_fname)
485
0b6023ee 486 images = _ReadImageDesc(node, use_expanded)
a8573c4c
SG
487
488 if select_images:
489 skip = []
490 new_images = OrderedDict()
491 for name, image in images.items():
492 if name in select_images:
493 new_images[name] = image
494 else:
495 skip.append(name)
496 images = new_images
f3385a5b 497 tout.notice('Skipping images: %s' % ', '.join(skip))
a8573c4c
SG
498
499 state.Prepare(images, dtb)
500
501 # Prepare the device tree by making sure that any missing
502 # properties are added (e.g. 'pos' and 'size'). The values of these
503 # may not be correct yet, but we add placeholders so that the
504 # size of the device tree is correct. Later, in
505 # SetCalculatedProperties() we will insert the correct values
506 # without changing the device-tree size, thus ensuring that our
507 # entry offsets remain the same.
508 for image in images.values():
386c63cf 509 image.CollectBintools()
c9ee33ac 510 image.gen_entries()
a8573c4c 511 if update_fdt:
a9fad07d 512 image.AddMissingProperties(True)
a8573c4c
SG
513 image.ProcessFdt(dtb)
514
4bdd1159 515 for dtb_item in state.GetAllFdts():
a8573c4c
SG
516 dtb_item.Sync(auto_resize=True)
517 dtb_item.Pack()
518 dtb_item.Flush()
519 return images
520
521
51014aab 522def ProcessImage(image, update_fdt, write_map, get_contents=True,
a89c8f21
HT
523 allow_resize=True, allow_missing=False,
524 allow_fake_blobs=False):
b88e81c6
SG
525 """Perform all steps for this image, including checking and # writing it.
526
527 This means that errors found with a later image will be reported after
528 earlier images are already completed and written, but that does not seem
529 important.
530
531 Args:
532 image: Image to process
533 update_fdt: True to update the FDT wth entry offsets, etc.
534 write_map: True to write a map file
10f9d006
SG
535 get_contents: True to get the image contents from files, etc., False if
536 the contents is already present
51014aab
SG
537 allow_resize: True to allow entries to change size (this does a re-pack
538 of the entries), False to raise an exception
4f9f1056 539 allow_missing: Allow blob_ext objects to be missing
a89c8f21 540 allow_fake_blobs: Allow blob_ext objects to be faked with dummy files
b1cca955
SG
541
542 Returns:
a89c8f21
HT
543 True if one or more external blobs are missing or faked,
544 False if all are present
b88e81c6 545 """
10f9d006 546 if get_contents:
4f9f1056 547 image.SetAllowMissing(allow_missing)
a89c8f21 548 image.SetAllowFakeBlob(allow_fake_blobs)
10f9d006 549 image.GetEntryContents()
b88e81c6
SG
550 image.GetEntryOffsets()
551
552 # We need to pack the entries to figure out where everything
553 # should be placed. This sets the offset/size of each entry.
554 # However, after packing we call ProcessEntryContents() which
555 # may result in an entry changing size. In that case we need to
556 # do another pass. Since the device tree often contains the
557 # final offset/size information we try to make space for this in
558 # AddMissingProperties() above. However, if the device is
559 # compressed we cannot know this compressed size in advance,
560 # since changing an offset from 0x100 to 0x104 (for example) can
561 # alter the compressed size of the device tree. So we need a
562 # third pass for this.
eb0f4a4c 563 passes = 5
b88e81c6
SG
564 for pack_pass in range(passes):
565 try:
566 image.PackEntries()
b88e81c6
SG
567 except Exception as e:
568 if write_map:
569 fname = image.WriteMap()
570 print("Wrote map file '%s' to show errors" % fname)
571 raise
572 image.SetImagePos()
573 if update_fdt:
574 image.SetCalculatedProperties()
4bdd1159 575 for dtb_item in state.GetAllFdts():
b88e81c6 576 dtb_item.Sync()
51014aab 577 dtb_item.Flush()
261cbe0b 578 image.WriteSymbols()
b88e81c6
SG
579 sizes_ok = image.ProcessEntryContents()
580 if sizes_ok:
581 break
582 image.ResetForPack()
f3385a5b 583 tout.info('Pack completed after %d pass(es)' % (pack_pass + 1))
b88e81c6 584 if not sizes_ok:
61ec04f9 585 image.Raise('Entries changed size after packing (tried %s passes)' %
b88e81c6
SG
586 passes)
587
b88e81c6
SG
588 image.BuildImage()
589 if write_map:
590 image.WriteMap()
b1cca955
SG
591 missing_list = []
592 image.CheckMissing(missing_list)
593 if missing_list:
f3385a5b 594 tout.warning("Image '%s' is missing external blobs and is non-functional: %s" %
b1cca955 595 (image.name, ' '.join([e.name for e in missing_list])))
b238143d 596 _ShowHelpForMissingBlobs(missing_list)
a89c8f21
HT
597 faked_list = []
598 image.CheckFakedBlobs(faked_list)
599 if faked_list:
f3385a5b 600 tout.warning(
2cc8c1fb
SG
601 "Image '%s' has faked external blobs and is non-functional: %s" %
602 (image.name, ' '.join([os.path.basename(e.GetDefaultFilename())
603 for e in faked_list])))
4f9ee83b
SG
604 missing_bintool_list = []
605 image.check_missing_bintools(missing_bintool_list)
606 if missing_bintool_list:
f3385a5b 607 tout.warning(
4f9ee83b
SG
608 "Image '%s' has missing bintools and is non-functional: %s" %
609 (image.name, ' '.join([os.path.basename(bintool.name)
610 for bintool in missing_bintool_list])))
611 return any([missing_list, faked_list, missing_bintool_list])
b88e81c6
SG
612
613
53cd5d92 614def Binman(args):
bf7fd50b
SG
615 """The main control code for binman
616
617 This assumes that help and test options have already been dealt with. It
618 deals with the core task of building images.
619
620 Args:
53cd5d92 621 args: Command line arguments Namespace object
bf7fd50b 622 """
8dbb7444
SG
623 global Image
624 global state
625
53cd5d92 626 if args.full_help:
c1aa66e7 627 tools.print_full_help(
5fe50f9a
PB
628 os.path.join(os.path.dirname(os.path.realpath(sys.argv[0])), 'README.rst')
629 )
bf7fd50b
SG
630 return 0
631
8dbb7444 632 # Put these here so that we can import this module without libfdt
07237988 633 from binman.image import Image
16287933 634 from binman import state
8dbb7444 635
386c63cf 636 if args.cmd in ['ls', 'extract', 'replace', 'tool']:
96b6c506 637 try:
f3385a5b 638 tout.init(args.verbosity)
c1aa66e7 639 tools.prepare_output_dir(None)
7bc4f0f8
SG
640 if args.cmd == 'ls':
641 ListEntries(args.image, args.paths)
642
643 if args.cmd == 'extract':
644 ExtractEntries(args.image, args.filename, args.outdir, args.paths,
943bf78a 645 not args.uncompressed, args.format)
7bc4f0f8
SG
646
647 if args.cmd == 'replace':
648 ReplaceEntries(args.image, args.filename, args.indir, args.paths,
649 do_compress=not args.compressed,
650 allow_resize=not args.fix_size, write_map=args.map)
386c63cf
SG
651
652 if args.cmd == 'tool':
c1aa66e7 653 tools.set_tool_paths(args.toolpath)
386c63cf
SG
654 if args.list:
655 bintool.Bintool.list_all()
656 elif args.fetch:
657 if not args.bintools:
658 raise ValueError(
659 "Please specify bintools to fetch or 'all' or 'missing'")
660 bintool.Bintool.fetch_tools(bintool.FETCH_ANY,
661 args.bintools)
662 else:
663 raise ValueError("Invalid arguments to 'tool' subcommand")
7bc4f0f8
SG
664 except:
665 raise
a6cb9950 666 finally:
c1aa66e7 667 tools.finalise_output_dir()
a6cb9950
SG
668 return 0
669
0427bed6
SG
670 elf_params = None
671 if args.update_fdt_in_elf:
672 elf_params = args.update_fdt_in_elf.split(',')
673 if len(elf_params) != 4:
674 raise ValueError('Invalid args %s to --update-fdt-in-elf: expected infile,outfile,begin_sym,end_sym' %
675 elf_params)
676
bf7fd50b 677 # Try to figure out which device tree contains our image description
53cd5d92
SG
678 if args.dt:
679 dtb_fname = args.dt
bf7fd50b 680 else:
53cd5d92 681 board = args.board
bf7fd50b
SG
682 if not board:
683 raise ValueError('Must provide a board to process (use -b <board>)')
53cd5d92 684 board_pathname = os.path.join(args.build_dir, board)
bf7fd50b 685 dtb_fname = os.path.join(board_pathname, 'u-boot.dtb')
53cd5d92
SG
686 if not args.indir:
687 args.indir = ['.']
688 args.indir.append(board_pathname)
bf7fd50b
SG
689
690 try:
f3385a5b 691 tout.init(args.verbosity)
53cd5d92
SG
692 elf.debug = args.debug
693 cbfs_util.VERBOSE = args.verbosity > 2
694 state.use_fake_dtb = args.fake_dtb
0b6023ee
SG
695
696 # Normally we replace the 'u-boot' etype with 'u-boot-expanded', etc.
697 # When running tests this can be disabled using this flag. When not
698 # updating the FDT in image, it is not needed by binman, but we use it
699 # for consistency, so that the images look the same to U-Boot at
700 # runtime.
701 use_expanded = not args.no_expanded
bf7fd50b 702 try:
c1aa66e7
SG
703 tools.set_input_dirs(args.indir)
704 tools.prepare_output_dir(args.outdir, args.preserve)
705 tools.set_tool_paths(args.toolpath)
53cd5d92 706 state.SetEntryArgs(args.entry_arg)
c69d19c8 707 state.SetThreads(args.threads)
ecab8973 708
a8573c4c 709 images = PrepareImagesAndDtbs(dtb_fname, args.image,
0b6023ee 710 args.update_fdt, use_expanded)
a89c8f21 711
c69d19c8
SG
712 if args.test_section_timeout:
713 # Set the first image to timeout, used in testThreadTimeout()
714 images[list(images.keys())[0]].test_section_timeout = True
a89c8f21 715 invalid = False
4f9ee83b
SG
716 bintool.Bintool.set_missing_list(
717 args.force_missing_bintools.split(',') if
718 args.force_missing_bintools else None)
bf7fd50b 719 for image in images.values():
a89c8f21
HT
720 invalid |= ProcessImage(image, args.update_fdt, args.map,
721 allow_missing=args.allow_missing,
722 allow_fake_blobs=args.fake_ext_blobs)
2a72cc72
SG
723
724 # Write the updated FDTs to our output files
4bdd1159 725 for dtb_item in state.GetAllFdts():
c1aa66e7 726 tools.write_file(dtb_item._fname, dtb_item.GetContents())
2a72cc72 727
0427bed6
SG
728 if elf_params:
729 data = state.GetFdtForEtype('u-boot-dtb').GetContents()
730 elf.UpdateFile(*elf_params, data)
731
a89c8f21 732 if invalid:
f3385a5b 733 tout.warning("\nSome images are invalid")
03ebc20d
SG
734
735 # Use this to debug the time take to pack the image
736 #state.TimingShow()
bf7fd50b 737 finally:
c1aa66e7 738 tools.finalise_output_dir()
bf7fd50b 739 finally:
f3385a5b 740 tout.uninit()
bf7fd50b
SG
741
742 return 0
This page took 0.352592 seconds and 4 git commands to generate.