1 # SPDX-License-Identifier: GPL-2.0+
2 # Copyright (c) 2016 Google, Inc
3 # Written by Simon Glass <sjg@chromium.org>
5 # Creates binary images from input files controlled by a description
8 from __future__ import print_function
10 from collections import OrderedDict
18 from image import Image
22 # List of images we plan to create
23 # Make this global so that it can be referenced from tests
24 images = OrderedDict()
26 def _ReadImageDesc(binman_node):
27 """Read the image descriptions from the /binman node
29 This normally produces a single Image object called 'image'. But if
30 multiple images are present, they will all be returned.
33 binman_node: Node object of the /binman node
35 OrderedDict of Image objects, each of which describes an image
37 images = OrderedDict()
38 if 'multiple-images' in binman_node.props:
39 for node in binman_node.subnodes:
40 images[node.name] = Image(node.name, node)
42 images['image'] = Image('image', binman_node)
45 def _FindBinmanNode(dtb):
46 """Find the 'binman' node in the device tree
49 dtb: Fdt object to scan
51 Node object of /binman node, or None if not found
53 for node in dtb.GetRoot().subnodes:
54 if node.name == 'binman':
58 def WriteEntryDocs(modules, test_missing=None):
59 """Write out documentation for all entries
62 modules: List of Module objects to get docs for
63 test_missing: Used for testing only, to force an entry's documeentation
64 to show as missing even if it is present. Should be set to None in
67 from entry import Entry
68 Entry.WriteDocs(modules, test_missing)
71 """The main control code for binman
73 This assumes that help and test options have already been dealt with. It
74 deals with the core task of building images.
77 args: Command line arguments Namespace object
82 pager = os.getenv('PAGER')
85 fname = os.path.join(os.path.dirname(os.path.realpath(sys.argv[0])),
87 command.Run(pager, fname)
90 # Try to figure out which device tree contains our image description
96 raise ValueError('Must provide a board to process (use -b <board>)')
97 board_pathname = os.path.join(args.build_dir, board)
98 dtb_fname = os.path.join(board_pathname, 'u-boot.dtb')
101 args.indir.append(board_pathname)
104 # Import these here in case libfdt.py is not available, in which case
105 # the above help option still works.
109 tout.Init(args.verbosity)
110 elf.debug = args.debug
111 cbfs_util.VERBOSE = args.verbosity > 2
112 state.use_fake_dtb = args.fake_dtb
114 tools.SetInputDirs(args.indir)
115 tools.PrepareOutputDir(args.outdir, args.preserve)
116 tools.SetToolPaths(args.toolpath)
117 state.SetEntryArgs(args.entry_arg)
119 # Get the device tree ready by compiling it and copying the compiled
120 # output into a file in our output directly. Then scan it for use
122 dtb_fname = fdt_util.EnsureCompiled(dtb_fname)
123 fname = tools.GetOutputFilename('u-boot.dtb.out')
124 tools.WriteFile(fname, tools.ReadFile(dtb_fname))
125 dtb = fdt.FdtScan(fname)
127 node = _FindBinmanNode(dtb)
129 raise ValueError("Device tree '%s' does not have a 'binman' "
132 images = _ReadImageDesc(node)
136 new_images = OrderedDict()
137 for name, image in images.items():
138 if name in args.image:
139 new_images[name] = image
143 if skip and args.verbosity >= 2:
144 print('Skipping images: %s' % ', '.join(skip))
146 state.Prepare(images, dtb)
148 # Prepare the device tree by making sure that any missing
149 # properties are added (e.g. 'pos' and 'size'). The values of these
150 # may not be correct yet, but we add placeholders so that the
151 # size of the device tree is correct. Later, in
152 # SetCalculatedProperties() we will insert the correct values
153 # without changing the device-tree size, thus ensuring that our
154 # entry offsets remain the same.
155 for image in images.values():
156 image.ExpandEntries()
158 image.AddMissingProperties()
159 image.ProcessFdt(dtb)
161 for dtb_item in state.GetFdts():
162 dtb_item.Sync(auto_resize=True)
166 for image in images.values():
167 # Perform all steps for this image, including checking and
168 # writing it. This means that errors found with a later
169 # image will be reported after earlier images are already
170 # completed and written, but that does not seem important.
171 image.GetEntryContents()
172 image.GetEntryOffsets()
177 except Exception as e:
179 fname = image.WriteMap()
180 print("Wrote map file '%s' to show errors" % fname)
184 image.SetCalculatedProperties()
185 for dtb_item in state.GetFdts():
187 image.ProcessEntryContents()
193 # Write the updated FDTs to our output files
194 for dtb_item in state.GetFdts():
195 tools.WriteFile(dtb_item._fname, dtb_item.GetContents())
198 tools.FinaliseOutputDir()