1# SPDX-License-Identifier: GPL-2.0+
2# Copyright (c) 2016 Google, Inc
3# Written by Simon Glass <sjg@chromium.org>
4#
5# Entry-type module for producing an image using mkimage
6#
7
8from collections import OrderedDict
9
10from binman.entry import Entry
11from dtoc import fdt_util
12from patman import tools
13
14class Entry_mkimage(Entry):
15    """Entry containing a binary produced by mkimage
16
17    Properties / Entry arguments:
18        - datafile: Filename for -d argument
19        - args: Other arguments to pass
20
21    The data passed to mkimage is collected from subnodes of the mkimage node,
22    e.g.:
23
24        mkimage {
25            args = "-n test -T imximage";
26
27            u-boot-spl {
28            };
29        };
30
31    This calls mkimage to create an imximage with u-boot-spl.bin as the input
32    file. The output from mkimage then becomes part of the image produced by
33    binman.
34    """
35    def __init__(self, section, etype, node):
36        super().__init__(section, etype, node)
37        self._args = fdt_util.GetString(self._node, 'args').split(' ')
38        self._mkimage_entries = OrderedDict()
39        self._ReadSubnodes()
40
41    def ObtainContents(self):
42        data = b''
43        for entry in self._mkimage_entries.values():
44            # First get the input data and put it in a file. If not available,
45            # try later.
46            if not entry.ObtainContents():
47                return False
48            data += entry.GetData()
49        uniq = self.GetUniqueName()
50        input_fname = tools.GetOutputFilename('mkimage.%s' % uniq)
51        tools.WriteFile(input_fname, data)
52        output_fname = tools.GetOutputFilename('mkimage-out.%s' % uniq)
53        tools.Run('mkimage', '-d', input_fname, *self._args, output_fname)
54        self.SetContents(tools.ReadFile(output_fname))
55        return True
56
57    def _ReadSubnodes(self):
58        """Read the subnodes to find out what should go in this image"""
59        for node in self._node.subnodes:
60            entry = Entry.Create(self, node)
61            entry.ReadNode()
62            self._mkimage_entries[entry.name] = entry
63