Merge tag 'dm-pull-9jul19-take2' of https://gitlab.denx.de/u-boot/custodians/u-boot-dm
[oweals/u-boot.git] / tools / binman / etype / blob.py
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 blobs, which are binary objects read from files
6 #
7
8 from entry import Entry
9 import fdt_util
10 import state
11 import tools
12
13 class Entry_blob(Entry):
14     """Entry containing an arbitrary binary blob
15
16     Note: This should not be used by itself. It is normally used as a parent
17     class by other entry types.
18
19     Properties / Entry arguments:
20         - filename: Filename of file to read into entry
21         - compress: Compression algorithm to use:
22             none: No compression
23             lz4: Use lz4 compression (via 'lz4' command-line utility)
24
25     This entry reads data from a file and places it in the entry. The
26     default filename is often specified specified by the subclass. See for
27     example the 'u_boot' entry which provides the filename 'u-boot.bin'.
28
29     If compression is enabled, an extra 'uncomp-size' property is written to
30     the node (if enabled with -u) which provides the uncompressed size of the
31     data.
32     """
33     def __init__(self, section, etype, node):
34         Entry.__init__(self, section, etype, node)
35         self._filename = fdt_util.GetString(self._node, 'filename', self.etype)
36         self._compress = fdt_util.GetString(self._node, 'compress', 'none')
37         self._uncompressed_size = None
38
39     def ObtainContents(self):
40         self._filename = self.GetDefaultFilename()
41         self._pathname = tools.GetInputFilename(self._filename)
42         self.ReadBlobContents()
43         return True
44
45     def ReadBlobContents(self):
46         # We assume the data is small enough to fit into memory. If this
47         # is used for large filesystem image that might not be true.
48         # In that case, Image.BuildImage() could be adjusted to use a
49         # new Entry method which can read in chunks. Then we could copy
50         # the data in chunks and avoid reading it all at once. For now
51         # this seems like an unnecessary complication.
52         data = tools.ReadFile(self._pathname)
53         if self._compress == 'lz4':
54             self._uncompressed_size = len(data)
55             '''
56             import lz4  # Import this only if needed (python-lz4 dependency)
57
58             try:
59                 data = lz4.frame.compress(data)
60             except AttributeError:
61                 data = lz4.compress(data)
62             '''
63             data = tools.Run('lz4', '-c', self._pathname, binary=True)
64         self.SetContents(data)
65         return True
66
67     def GetDefaultFilename(self):
68         return self._filename
69
70     def AddMissingProperties(self):
71         Entry.AddMissingProperties(self)
72         if self._compress != 'none':
73             state.AddZeroProp(self._node, 'uncomp-size')
74
75     def SetCalculatedProperties(self):
76         Entry.SetCalculatedProperties(self)
77         if self._uncompressed_size is not None:
78             state.SetInt(self._node, 'uncomp-size', self._uncompressed_size)