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.dtb.out')
120 tools.WriteFile(fname, tools.ReadFile(dtb_fname))
121 dtb = fdt.FdtScan(fname)
123 node = _FindBinmanNode(dtb)
125 raise ValueError("Device tree '%s' does not have a 'binman' "
128 images = _ReadImageDesc(node)
132 for name, image in images.iteritems():
133 if name not in options.image:
137 print 'Skipping images: %s\n' % ', '.join(skip)
139 state.Prepare(images, dtb)
141 # Prepare the device tree by making sure that any missing
142 # properties are added (e.g. 'pos' and 'size'). The values of these
143 # may not be correct yet, but we add placeholders so that the
144 # size of the device tree is correct. Later, in
145 # SetCalculatedProperties() we will insert the correct values
146 # without changing the device-tree size, thus ensuring that our
147 # entry offsets remain the same.
148 for image in images.values():
149 image.ExpandEntries()
150 if options.update_fdt:
151 image.AddMissingProperties()
152 image.ProcessFdt(dtb)
154 for dtb_item in state.GetFdts():
155 dtb_item.Sync(auto_resize=True)
159 for image in images.values():
160 # Perform all steps for this image, including checking and
161 # writing it. This means that errors found with a later
162 # image will be reported after earlier images are already
163 # completed and written, but that does not seem important.
164 image.GetEntryContents()
165 image.GetEntryOffsets()
170 except Exception as e:
172 fname = image.WriteMap()
173 print "Wrote map file '%s' to show errors" % fname
176 if options.update_fdt:
177 image.SetCalculatedProperties()
178 for dtb_item in state.GetFdts():
180 image.ProcessEntryContents()
186 # Write the updated FDTs to our output files
187 for dtb_item in state.GetFdts():
188 tools.WriteFile(dtb_item._fname, dtb_item.GetContents())
191 tools.FinaliseOutputDir()