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 collections import OrderedDict
15 from image import Image
19 # List of images we plan to create
20 # Make this global so that it can be referenced from tests
21 images = OrderedDict()
23 def _ReadImageDesc(binman_node):
24 """Read the image descriptions from the /binman node
26 This normally produces a single Image object called 'image'. But if
27 multiple images are present, they will all be returned.
30 binman_node: Node object of the /binman node
32 OrderedDict of Image objects, each of which describes an image
34 images = OrderedDict()
35 if 'multiple-images' in binman_node.props:
36 for node in binman_node.subnodes:
37 images[node.name] = Image(node.name, node)
39 images['image'] = Image('image', binman_node)
42 def _FindBinmanNode(dtb):
43 """Find the 'binman' node in the device tree
46 dtb: Fdt object to scan
48 Node object of /binman node, or None if not found
50 for node in dtb.GetRoot().subnodes:
51 if node.name == 'binman':
55 def WriteEntryDocs(modules, test_missing=None):
56 """Write out documentation for all entries
59 modules: List of Module objects to get docs for
60 test_missing: Used for testing only, to force an entry's documeentation
61 to show as missing even if it is present. Should be set to None in
64 from entry import Entry
65 Entry.WriteDocs(modules, test_missing)
67 def Binman(options, args):
68 """The main control code for binman
70 This assumes that help and test options have already been dealt with. It
71 deals with the core task of building images.
74 options: Command line options object
75 args: Command line arguments (list of strings)
80 pager = os.getenv('PAGER')
83 fname = os.path.join(os.path.dirname(os.path.realpath(sys.argv[0])),
85 command.Run(pager, fname)
88 # Try to figure out which device tree contains our image description
90 dtb_fname = options.dt
94 raise ValueError('Must provide a board to process (use -b <board>)')
95 board_pathname = os.path.join(options.build_dir, board)
96 dtb_fname = os.path.join(board_pathname, 'u-boot.dtb')
99 options.indir.append(board_pathname)
102 # Import these here in case libfdt.py is not available, in which case
103 # the above help option still works.
107 tout.Init(options.verbosity)
108 elf.debug = options.debug
109 state.use_fake_dtb = options.fake_dtb
111 tools.SetInputDirs(options.indir)
112 tools.PrepareOutputDir(options.outdir, options.preserve)
113 state.SetEntryArgs(options.entry_arg)
115 # Get the device tree ready by compiling it and copying the compiled
116 # output into a file in our output directly. Then scan it for use
118 dtb_fname = fdt_util.EnsureCompiled(dtb_fname)
119 fname = tools.GetOutputFilename('u-boot-out.dtb')
120 with open(dtb_fname) as infd:
121 with open(fname, 'wb') as outfd:
122 outfd.write(infd.read())
123 dtb = fdt.FdtScan(fname)
125 node = _FindBinmanNode(dtb)
127 raise ValueError("Device tree '%s' does not have a 'binman' "
130 images = _ReadImageDesc(node)
134 for name, image in images.iteritems():
135 if name not in options.image:
139 print 'Skipping images: %s\n' % ', '.join(skip)
141 state.Prepare(images, dtb)
143 # Prepare the device tree by making sure that any missing
144 # properties are added (e.g. 'pos' and 'size'). The values of these
145 # may not be correct yet, but we add placeholders so that the
146 # size of the device tree is correct. Later, in
147 # SetCalculatedProperties() we will insert the correct values
148 # without changing the device-tree size, thus ensuring that our
149 # entry offsets remain the same.
150 for image in images.values():
151 if options.update_fdt:
152 image.AddMissingProperties()
153 image.ProcessFdt(dtb)
155 for dtb_item in state.GetFdts():
156 dtb_item.Sync(auto_resize=True)
160 for image in images.values():
161 # Perform all steps for this image, including checking and
162 # writing it. This means that errors found with a later
163 # image will be reported after earlier images are already
164 # completed and written, but that does not seem important.
165 image.GetEntryContents()
166 image.GetEntryOffsets()
171 if options.update_fdt:
172 image.SetCalculatedProperties()
173 for dtb_item in state.GetFdts():
175 image.ProcessEntryContents()
181 # Write the updated FDTs to our output files
182 for dtb_item in state.GetFdts():
183 tools.WriteFile(dtb_item._fname, dtb_item.GetContents())
186 tools.FinaliseOutputDir()