def ObtainContents(self): gbb = 'gbb.bin' fname = tools.GetOutputFilename(gbb) if not self.size: self.Raise('GBB must have a fixed size') gbb_size = self.size bmpfv_size = gbb_size - 0x2180 if bmpfv_size < 0: self.Raise('GBB is too small (minimum 0x2180 bytes)') sizes = [0x100, 0x1000, bmpfv_size, 0x1000] sizes = ['%#x' % size for size in sizes] keydir = tools.GetInputFilename(self.keydir) gbb_set_command = [ 'gbb_utility', '-s', '--hwid=%s' % self.hardware_id, '--rootkey=%s/root_key.vbpubk' % keydir, '--recoverykey=%s/recovery_key.vbpubk' % keydir, '--flags=%d' % self.gbb_flags, '--bmpfv=%s' % tools.GetInputFilename(self.bmpblk), fname ] tools.Run('futility', 'gbb_utility', '-c', ','.join(sizes), fname) tools.Run('futility', *gbb_set_command) self.SetContents(tools.ReadFile(fname)) return True
def build_from_git(cls, git_repo, make_target, bintool_path): """Build a bintool from a git repo This clones the repo in a temporary directory, builds it with 'make', then returns the filename of the resulting executable bintool Args: git_repo (str): URL of git repo make_target (str): Target to pass to 'make' to build the tool bintool_path (str): Relative path of the tool in the repo, after build is complete Returns: tuple: str: Filename of fetched file to copy to a suitable directory str: Name of temp directory to remove, or None or None on error """ tmpdir = tempfile.mkdtemp(prefix='binmanf.') print(f"- clone git repo '{git_repo}' to '{tmpdir}'") tools.Run('git', 'clone', '--depth', '1', git_repo, tmpdir) print(f"- build target '{make_target}'") tools.Run('make', '-C', tmpdir, '-j', f'{multiprocessing.cpu_count()}', make_target) fname = os.path.join(tmpdir, bintool_path) if not os.path.exists(fname): print(f"- File '{fname}' was not produced") return None return fname, tmpdir
def setUpClass(cls): # Create a temporary directory for test files cls._indir = tempfile.mkdtemp(prefix='cbfs_util.') tools.SetInputDirs([cls._indir]) # Set up some useful data files TestCbfs._make_input_file('u-boot.bin', U_BOOT_DATA) TestCbfs._make_input_file('u-boot.dtb', U_BOOT_DTB_DATA) TestCbfs._make_input_file('compress', COMPRESS_DATA) # Set up a temporary output directory, used by the tools library when # compressing files tools.PrepareOutputDir(None) cls.have_cbfstool = True try: tools.Run('which', 'cbfstool') except: cls.have_cbfstool = False cls.have_lz4 = True try: tools.Run('lz4', '--no-frame-crc', '-c', tools.GetInputFilename('u-boot.bin'), binary=True) except: cls.have_lz4 = False
def GetVblock(self): # Join up the data files to be signed input_data = b'' for entry_phandle in self.content: data = self.section.GetContentsByPhandle(entry_phandle, self) if data is None: # Data not available yet return False input_data += data uniq = self.GetUniqueName() output_fname = tools.GetOutputFilename('vblock.%s' % uniq) input_fname = tools.GetOutputFilename('input.%s' % uniq) tools.WriteFile(input_fname, input_data) prefix = self.keydir + '/' args = [ 'vbutil_firmware', '--vblock', output_fname, '--keyblock', prefix + self.keyblock, '--signprivate', prefix + self.signprivate, '--version', '%d' % self.version, '--fv', input_fname, '--kernelkey', prefix + self.kernelkey, '--flags', '%d' % self.preamble_flags, ] #out.Notice("Sign '%s' into %s" % (', '.join(self.value), self.label)) stdout = tools.Run('futility', *args) return tools.ReadFile(output_fname)
def ObtainContents(self): """Obtain the contents of the FIT This adds the 'data' properties to the input ITB (Image-tree Binary) then runs mkimage to process it. """ # self._BuildInput() either returns bytes or raises an exception. data = self._BuildInput(self._fdt) uniq = self.GetUniqueName() input_fname = tools.GetOutputFilename('%s.itb' % uniq) output_fname = tools.GetOutputFilename('%s.fit' % uniq) tools.WriteFile(input_fname, data) tools.WriteFile(output_fname, data) args = [] ext_offset = self._fit_props.get('fit,external-offset') if ext_offset is not None: args += [ '-E', '-p', '%x' % fdt_util.fdt32_to_cpu(ext_offset.value) ] tools.Run('mkimage', '-t', '-F', output_fname, *args) self.SetContents(tools.ReadFile(output_fname)) return True
def ReadBlobContents(self): if self._strip: uniq = self.GetUniqueName() out_fname = tools.GetOutputFilename('%s.stripped' % uniq) tools.WriteFile(out_fname, tools.ReadFile(self._pathname)) tools.Run('strip', out_fname) self._pathname = out_fname super().ReadBlobContents() return True
def fetch_from_url(cls, url): """Fetch a bintool from a URL Args: url (str): URL to fetch from Returns: tuple: str: Filename of fetched file to copy to a suitable directory str: Name of temp directory to remove, or None """ fname, tmpdir = tools.Download(url) tools.Run('chmod', 'a+x', fname) return fname, tmpdir
def ObtainContents(self): data = b'' for entry in self._mkimage_entries.values(): # First get the input data and put it in a file. If not available, # try later. if not entry.ObtainContents(): return False data += entry.GetData() uniq = self.GetUniqueName() input_fname = tools.GetOutputFilename('mkimage.%s' % uniq) tools.WriteFile(input_fname, data) output_fname = tools.GetOutputFilename('mkimage-out.%s' % uniq) tools.Run('mkimage', '-d', input_fname, *self._args, output_fname) self.SetContents(tools.ReadFile(output_fname)) return True
def apt_install(cls, package): """Install a bintool using the 'aot' tool This requires use of servo so may request a password Args: package (str): Name of package to install Returns: True, assuming it completes without error """ args = ['sudo', 'apt', 'install', '-y', package] print('- %s' % ' '.join(args)) tools.Run(*args) return True
def BuildElfTestFiles(target_dir): """Build ELF files used for testing in binman This compiles and links the test files into the specified directory. It the Makefile and source files in the binman test/ directory. Args: target_dir: Directory to put the files into """ if not os.path.exists(target_dir): os.mkdir(target_dir) testdir = os.path.join(binman_dir, 'test') # If binman is involved from the main U-Boot Makefile the -r and -R # flags are set in MAKEFLAGS. This prevents this Makefile from working # correctly. So drop any make flags here. if 'MAKEFLAGS' in os.environ: del os.environ['MAKEFLAGS'] tools.Run('make', '-C', target_dir, '-f', os.path.join(testdir, 'Makefile'), 'SRC=%s/' % testdir)
def GetSymbols(fname, patterns): """Get the symbols from an ELF file Args: fname: Filename of the ELF file to read patterns: List of regex patterns to search for, each a string Returns: None, if the file does not exist, or Dict: key: Name of symbol value: Hex value of symbol """ stdout = tools.Run('objdump', '-t', fname) lines = stdout.splitlines() if patterns: re_syms = re.compile('|'.join(patterns)) else: re_syms = None syms = {} syms_started = False for line in lines: if not line or not syms_started: if 'SYMBOL TABLE' in line: syms_started = True line = None # Otherwise code coverage complains about 'continue' continue if re_syms and not re_syms.search(line): continue space_pos = line.find(' ') value, rest = line[:space_pos], line[space_pos + 1:] flags = rest[:7] parts = rest[7:].split() section, size = parts[:2] if len(parts) > 2: name = parts[2] if parts[2] != '.hidden' else parts[3] syms[name] = Symbol(section, int(value, 16), int(size, 16), flags[1] == 'w') # Sort dict by address return OrderedDict(sorted(syms.items(), key=lambda x: x[1].address))
def GetVblock(self, required): """Get the contents of this entry Args: required: True if the data must be present, False if it is OK to return None Returns: bytes content of the entry, which is the signed vblock for the provided data """ # Join up the data files to be signed input_data = self.GetContents(required) if input_data is None: return None uniq = self.GetUniqueName() output_fname = tools.GetOutputFilename('vblock.%s' % uniq) input_fname = tools.GetOutputFilename('input.%s' % uniq) tools.WriteFile(input_fname, input_data) prefix = self.keydir + '/' args = [ 'vbutil_firmware', '--vblock', output_fname, '--keyblock', prefix + self.keyblock, '--signprivate', prefix + self.signprivate, '--version', '%d' % self.version, '--fv', input_fname, '--kernelkey', prefix + self.kernelkey, '--flags', '%d' % self.preamble_flags, ] #out.Notice("Sign '%s' into %s" % (', '.join(self.value), self.label)) stdout = tools.Run('futility', *args) return tools.ReadFile(output_fname)
import tempfile import unittest # Bring in the patman and dtoc libraries (but don't override the first path # in PYTHONPATH) OUR_PATH = os.path.dirname(os.path.realpath(__file__)) sys.path.insert(2, os.path.join(OUR_PATH, '..')) # pylint: disable=C0413 from patman import test_util from patman import tools import fip_util HAVE_FIPTOOL = True try: tools.Run('which', 'fiptool') except ValueError: HAVE_FIPTOOL = False # pylint: disable=R0902,R0904 class TestFip(unittest.TestCase): """Test of fip_util classes""" #pylint: disable=W0212 def setUp(self): # Create a temporary directory for test files self._indir = tempfile.mkdtemp(prefix='fip_util.') tools.SetInputDirs([self._indir]) # Set up a temporary output directory, used by the tools library when