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 8from binman.entry import Entry 9from binman import state 10from dtoc import fdt_util 11from u_boot_pylib import tools 12from u_boot_pylib import tout 13 14class Entry_blob(Entry): 15 """Arbitrary binary blob 16 17 Note: This should not be used by itself. It is normally used as a parent 18 class by other entry types. 19 20 Properties / Entry arguments: 21 - filename: Filename of file to read into entry 22 - compress: Compression algorithm to use: 23 none: No compression 24 lz4: Use lz4 compression (via 'lz4' command-line utility) 25 26 This entry reads data from a file and places it in the entry. The 27 default filename is often specified specified by the subclass. See for 28 example the 'u-boot' entry which provides the filename 'u-boot.bin'. 29 30 If compression is enabled, an extra 'uncomp-size' property is written to 31 the node (if enabled with -u) which provides the uncompressed size of the 32 data. 33 """ 34 def __init__(self, section, etype, node, auto_write_symbols=False): 35 super().__init__(section, etype, node, 36 auto_write_symbols=auto_write_symbols) 37 self._filename = fdt_util.GetString(self._node, 'filename', self.etype) 38 self.elf_fname = fdt_util.GetString(self._node, 'elf-filename', 39 self.elf_fname) 40 self.elf_base_sym = fdt_util.GetString(self._node, 'elf-base-sym') 41 if not self.auto_write_symbols: 42 if fdt_util.GetBool(self._node, 'write-symbols'): 43 self.auto_write_symbols = True 44 45 def ObtainContents(self, fake_size: int = 0) -> bool: 46 self._filename = self.GetDefaultFilename() 47 self._pathname = tools.get_input_filename(self._filename, 48 self.external and (self.optional or self.section.GetAllowMissing())) 49 # Allow the file to be missing 50 if not self._pathname: 51 if not fake_size and self.assume_size: 52 fake_size = self.assume_size 53 self._pathname = self.check_fake_fname(self._filename, fake_size) 54 self.missing = True 55 if self.optional: 56 self.mark_absent("missing but optional") 57 if not self.faked: 58 content_size = 0 59 if self.assume_size: # Ensure we get test coverage on next line 60 content_size = self.assume_size 61 self.SetContents(tools.get_bytes(0, content_size)) 62 return True 63 64 self.ReadBlobContents() 65 return True 66 67 def ReadFileContents(self, pathname): 68 """Read blob contents into memory 69 70 This function compresses the data before returning if needed. 71 72 We assume the data is small enough to fit into memory. If this 73 is used for large filesystem image that might not be true. 74 In that case, Image.BuildImage() could be adjusted to use a 75 new Entry method which can read in chunks. Then we could copy 76 the data in chunks and avoid reading it all at once. For now 77 this seems like an unnecessary complication. 78 79 Args: 80 pathname (str): Pathname to read from 81 82 Returns: 83 bytes: Data read 84 """ 85 state.TimingStart('read') 86 indata = tools.read_file(pathname) 87 state.TimingAccum('read') 88 state.TimingStart('compress') 89 data = self.CompressData(indata) 90 state.TimingAccum('compress') 91 return data 92 93 def ReadBlobContents(self): 94 data = self.ReadFileContents(self._pathname) 95 self.SetContents(data) 96 return True 97 98 def GetDefaultFilename(self): 99 return self._filename 100 101 def ProcessContents(self): 102 # The blob may have changed due to WriteSymbols() 103 return self.ProcessContentsUpdate(self.data) 104 105 def CheckFakedBlobs(self, faked_blobs_list): 106 """Check if any entries in this section have faked external blobs 107 108 If there are faked blobs, the entries are added to the list 109 110 Args: 111 faked_blobs_list: List of Entry objects to be added to 112 """ 113 if self.faked: 114 faked_blobs_list.append(self) 115