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
110 tools.SetInputDirs(options.indir)
111 tools.PrepareOutputDir(options.outdir, options.preserve)
112 state.SetEntryArgs(options.entry_arg)
114 # Get the device tree ready by compiling it and copying the compiled
115 # output into a file in our output directly. Then scan it for use
117 dtb_fname = fdt_util.EnsureCompiled(dtb_fname)
118 fname = tools.GetOutputFilename('u-boot-out.dtb')
119 with open(dtb_fname) as infd:
120 with open(fname, 'wb') as outfd:
121 outfd.write(infd.read())
122 dtb = fdt.FdtScan(fname)
124 # Note the file so that GetFdt() can find it
125 state.fdt_files['u-boot.dtb'] = dtb
126 node = _FindBinmanNode(dtb)
128 raise ValueError("Device tree '%s' does not have a 'binman' "
131 images = _ReadImageDesc(node)
135 for name, image in images.iteritems():
136 if name not in options.image:
140 print 'Skipping images: %s\n' % ', '.join(skip)
142 # Prepare the device tree by making sure that any missing
143 # properties are added (e.g. 'pos' and 'size'). The values of these
144 # may not be correct yet, but we add placeholders so that the
145 # size of the device tree is correct. Later, in
146 # SetCalculatedProperties() we will insert the correct values
147 # without changing the device-tree size, thus ensuring that our
148 # entry offsets remain the same.
149 for image in images.values():
150 if options.update_fdt:
151 image.AddMissingProperties()
152 image.ProcessFdt(dtb)
154 dtb.Sync(auto_resize=True)
158 for image in images.values():
159 # Perform all steps for this image, including checking and
160 # writing it. This means that errors found with a later
161 # image will be reported after earlier images are already
162 # completed and written, but that does not seem important.
163 image.GetEntryContents()
164 image.GetEntryOffsets()
169 if options.update_fdt:
170 image.SetCalculatedProperties()
172 image.ProcessEntryContents()
177 with open(fname, 'wb') as outfd:
178 outfd.write(dtb.GetContents())
180 tools.FinaliseOutputDir()