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