1bf7fd50bSSimon Glass# Copyright (c) 2016 Google, Inc 2bf7fd50bSSimon Glass# Written by Simon Glass <sjg@chromium.org> 3bf7fd50bSSimon Glass# 4bf7fd50bSSimon Glass# SPDX-License-Identifier: GPL-2.0+ 5bf7fd50bSSimon Glass# 6bf7fd50bSSimon Glass# Creates binary images from input files controlled by a description 7bf7fd50bSSimon Glass# 8bf7fd50bSSimon Glass 9bf7fd50bSSimon Glassfrom collections import OrderedDict 10bf7fd50bSSimon Glassimport os 11bf7fd50bSSimon Glassimport sys 12bf7fd50bSSimon Glassimport tools 13bf7fd50bSSimon Glass 14bf7fd50bSSimon Glassimport command 15*99ed4a2eSSimon Glassimport fdt 16bf7fd50bSSimon Glassimport fdt_util 17bf7fd50bSSimon Glassfrom image import Image 18bf7fd50bSSimon Glassimport tout 19bf7fd50bSSimon Glass 20bf7fd50bSSimon Glass# List of images we plan to create 21bf7fd50bSSimon Glass# Make this global so that it can be referenced from tests 22bf7fd50bSSimon Glassimages = OrderedDict() 23bf7fd50bSSimon Glass 24bf7fd50bSSimon Glassdef _ReadImageDesc(binman_node): 25bf7fd50bSSimon Glass """Read the image descriptions from the /binman node 26bf7fd50bSSimon Glass 27bf7fd50bSSimon Glass This normally produces a single Image object called 'image'. But if 28bf7fd50bSSimon Glass multiple images are present, they will all be returned. 29bf7fd50bSSimon Glass 30bf7fd50bSSimon Glass Args: 31bf7fd50bSSimon Glass binman_node: Node object of the /binman node 32bf7fd50bSSimon Glass Returns: 33bf7fd50bSSimon Glass OrderedDict of Image objects, each of which describes an image 34bf7fd50bSSimon Glass """ 35bf7fd50bSSimon Glass images = OrderedDict() 36bf7fd50bSSimon Glass if 'multiple-images' in binman_node.props: 37bf7fd50bSSimon Glass for node in binman_node.subnodes: 38bf7fd50bSSimon Glass images[node.name] = Image(node.name, node) 39bf7fd50bSSimon Glass else: 40bf7fd50bSSimon Glass images['image'] = Image('image', binman_node) 41bf7fd50bSSimon Glass return images 42bf7fd50bSSimon Glass 43ec3f378aSSimon Glassdef _FindBinmanNode(dtb): 44bf7fd50bSSimon Glass """Find the 'binman' node in the device tree 45bf7fd50bSSimon Glass 46bf7fd50bSSimon Glass Args: 47ec3f378aSSimon Glass dtb: Fdt object to scan 48bf7fd50bSSimon Glass Returns: 49bf7fd50bSSimon Glass Node object of /binman node, or None if not found 50bf7fd50bSSimon Glass """ 51ec3f378aSSimon Glass for node in dtb.GetRoot().subnodes: 52bf7fd50bSSimon Glass if node.name == 'binman': 53bf7fd50bSSimon Glass return node 54bf7fd50bSSimon Glass return None 55bf7fd50bSSimon Glass 56bf7fd50bSSimon Glassdef Binman(options, args): 57bf7fd50bSSimon Glass """The main control code for binman 58bf7fd50bSSimon Glass 59bf7fd50bSSimon Glass This assumes that help and test options have already been dealt with. It 60bf7fd50bSSimon Glass deals with the core task of building images. 61bf7fd50bSSimon Glass 62bf7fd50bSSimon Glass Args: 63bf7fd50bSSimon Glass options: Command line options object 64bf7fd50bSSimon Glass args: Command line arguments (list of strings) 65bf7fd50bSSimon Glass """ 66bf7fd50bSSimon Glass global images 67bf7fd50bSSimon Glass 68bf7fd50bSSimon Glass if options.full_help: 69bf7fd50bSSimon Glass pager = os.getenv('PAGER') 70bf7fd50bSSimon Glass if not pager: 71bf7fd50bSSimon Glass pager = 'more' 72bf7fd50bSSimon Glass fname = os.path.join(os.path.dirname(os.path.realpath(sys.argv[0])), 73bf7fd50bSSimon Glass 'README') 74bf7fd50bSSimon Glass command.Run(pager, fname) 75bf7fd50bSSimon Glass return 0 76bf7fd50bSSimon Glass 77bf7fd50bSSimon Glass # Try to figure out which device tree contains our image description 78bf7fd50bSSimon Glass if options.dt: 79bf7fd50bSSimon Glass dtb_fname = options.dt 80bf7fd50bSSimon Glass else: 81bf7fd50bSSimon Glass board = options.board 82bf7fd50bSSimon Glass if not board: 83bf7fd50bSSimon Glass raise ValueError('Must provide a board to process (use -b <board>)') 84bf7fd50bSSimon Glass board_pathname = os.path.join(options.build_dir, board) 85bf7fd50bSSimon Glass dtb_fname = os.path.join(board_pathname, 'u-boot.dtb') 86bf7fd50bSSimon Glass if not options.indir: 87bf7fd50bSSimon Glass options.indir = ['.'] 88bf7fd50bSSimon Glass options.indir.append(board_pathname) 89bf7fd50bSSimon Glass 90bf7fd50bSSimon Glass try: 91bf7fd50bSSimon Glass tout.Init(options.verbosity) 92bf7fd50bSSimon Glass try: 93bf7fd50bSSimon Glass tools.SetInputDirs(options.indir) 94bf7fd50bSSimon Glass tools.PrepareOutputDir(options.outdir, options.preserve) 95ec3f378aSSimon Glass dtb = fdt.FdtScan(dtb_fname) 96ec3f378aSSimon Glass node = _FindBinmanNode(dtb) 97bf7fd50bSSimon Glass if not node: 98bf7fd50bSSimon Glass raise ValueError("Device tree '%s' does not have a 'binman' " 99bf7fd50bSSimon Glass "node" % dtb_fname) 100bf7fd50bSSimon Glass images = _ReadImageDesc(node) 101bf7fd50bSSimon Glass for image in images.values(): 102bf7fd50bSSimon Glass # Perform all steps for this image, including checking and 103bf7fd50bSSimon Glass # writing it. This means that errors found with a later 104bf7fd50bSSimon Glass # image will be reported after earlier images are already 105bf7fd50bSSimon Glass # completed and written, but that does not seem important. 106bf7fd50bSSimon Glass image.GetEntryContents() 107bf7fd50bSSimon Glass image.GetEntryPositions() 108bf7fd50bSSimon Glass image.PackEntries() 109bf7fd50bSSimon Glass image.CheckSize() 110bf7fd50bSSimon Glass image.CheckEntries() 111bf7fd50bSSimon Glass image.ProcessEntryContents() 112bf7fd50bSSimon Glass image.BuildImage() 113bf7fd50bSSimon Glass finally: 114bf7fd50bSSimon Glass tools.FinaliseOutputDir() 115bf7fd50bSSimon Glass finally: 116bf7fd50bSSimon Glass tout.Uninit() 117bf7fd50bSSimon Glass 118bf7fd50bSSimon Glass return 0 119