예제 #1
0
    def BuildSectionData(self, required):
        """Build FIT entry contents

        This adds the 'data' properties to the input ITB (Image-tree Binary)
        then runs mkimage to process it.

        Args:
            required (bool): True if the data must be present, False if it is OK
                to return None

        Returns:
            bytes: Contents of the section
        """
        data = self._build_input()
        uniq = self.GetUniqueName()
        input_fname = tools.get_output_filename(f'{uniq}.itb')
        output_fname = tools.get_output_filename(f'{uniq}.fit')
        tools.write_file(input_fname, data)
        tools.write_file(output_fname, data)

        args = {}
        ext_offset = self._fit_props.get('fit,external-offset')
        if ext_offset is not None:
            args = {
                'external': True,
                'pad': fdt_util.fdt32_to_cpu(ext_offset.value)
            }
        if self.mkimage.run(reset_timestamp=True,
                            output_fname=output_fname,
                            **args) is None:
            # Bintool is missing; just use empty data as the output
            self.record_missing_bintool(self.mkimage)
            return tools.get_bytes(0, 1024)

        return tools.read_file(output_fname)
예제 #2
0
    def collect_contents_to_file(self, entries, prefix):
        """Put the contents of a list of entries into a file

        Args:
            entries (list of Entry): Entries to collect
            prefix (str): Filename prefix of file to write to

        If any entry does not have contents yet, this function returns False
        for the data.

        Returns:
            Tuple:
                bytes: Concatenated data from all the entries (or False)
                str: Filename of file written (or False if no data)
                str: Unique portion of filename (or False if no data)
        """
        data = b''
        for entry in entries:
            # First get the input data and put it in a file. If not available,
            # try later.
            if not entry.ObtainContents():
                return False, False, False
            data += entry.GetData()
        uniq = self.GetUniqueName()
        fname = tools.get_output_filename(f'{prefix}.{uniq}')
        tools.write_file(fname, data)
        return data, fname, uniq
예제 #3
0
    def ObtainContents(self):
        gbb = 'gbb.bin'
        fname = tools.get_output_filename(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)')
        keydir = tools.get_input_filename(self.keydir)

        stdout = self.futility.gbb_create(fname,
                                          [0x100, 0x1000, bmpfv_size, 0x1000])
        if stdout is not None:
            stdout = self.futility.gbb_set(
                fname,
                hwid=self.hardware_id,
                rootkey='%s/root_key.vbpubk' % keydir,
                recoverykey='%s/recovery_key.vbpubk' % keydir,
                flags=self.gbb_flags,
                bmpfv=tools.get_input_filename(self.bmpblk))

        if stdout is not None:
            self.SetContents(tools.read_file(fname))
        else:
            # Bintool is missing; just use the required amount of zero data
            self.record_missing_bintool(self.futility)
            self.SetContents(tools.get_bytes(0, gbb_size))

        return True
예제 #4
0
 def BuildImage(self):
     """Write the image to a file"""
     fname = tools.get_output_filename(self._filename)
     tout.info("Writing image to '%s'" % fname)
     with open(fname, 'wb') as fd:
         data = self.GetPaddedData()
         fd.write(data)
     tout.info("Wrote %#x bytes" % len(data))
예제 #5
0
def EnsureCompiled(fname, tmpdir=None, capture_stderr=False):
    """Compile an fdt .dts source file into a .dtb binary blob if needed.

    Args:
        fname: Filename (if .dts it will be compiled). It not it will be
            left alone
        tmpdir: Temporary directory for output files, or None to use the
            tools-module output directory

    Returns:
        Filename of resulting .dtb file
    """
    _, ext = os.path.splitext(fname)
    if ext != '.dts':
        return fname

    if tmpdir:
        dts_input = os.path.join(tmpdir, 'source.dts')
        dtb_output = os.path.join(tmpdir, 'source.dtb')
    else:
        dts_input = tools.get_output_filename('source.dts')
        dtb_output = tools.get_output_filename('source.dtb')

    search_paths = [os.path.join(os.getcwd(), 'include')]
    root, _ = os.path.splitext(fname)
    cc, args = tools.get_target_compile_tool('cc')
    args += ['-E', '-P', '-x', 'assembler-with-cpp', '-D__ASSEMBLY__']
    args += ['-Ulinux']
    for path in search_paths:
        args.extend(['-I', path])
    args += ['-o', dts_input, fname]
    command.run(cc, *args)

    # If we don't have a directory, put it in the tools tempdir
    search_list = []
    for path in search_paths:
        search_list.extend(['-i', path])
    dtc, args = tools.get_target_compile_tool('dtc')
    args += [
        '-I', 'dts', '-o', dtb_output, '-O', 'dtb', '-W',
        'no-unit_address_vs_reg'
    ]
    args.extend(search_list)
    args.append(dts_input)
    command.run(dtc, *args, capture_stderr=capture_stderr)
    return dtb_output
예제 #6
0
 def ReadBlobContents(self):
     if self._strip:
         uniq = self.GetUniqueName()
         out_fname = tools.get_output_filename('%s.stripped' % uniq)
         tools.write_file(out_fname, tools.read_file(self._pathname))
         tools.run('strip', out_fname)
         self._pathname = out_fname
     super().ReadBlobContents()
     return True
예제 #7
0
    def test_struct_scan_errors(self):
        """Test scanning a header file with an invalid unicode file"""
        output = tools.get_output_filename('output.h')
        tools.write_file(output, b'struct this is a test \x81 of bad unicode')

        scan = src_scan.Scanner(None, None)
        with test_util.capture_sys_output() as (stdout, _):
            scan.scan_header(output)
        self.assertIn('due to unicode error', stdout.getvalue())
예제 #8
0
    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.get_output_filename('mkimage.%s' % uniq)
        tools.write_file(input_fname, data)
        output_fname = tools.get_output_filename('mkimage-out.%s' % uniq)
        if self.mkimage.run_cmd('-d', input_fname, *self._args,
                                output_fname) is not None:
            self.SetContents(tools.read_file(output_fname))
        else:
            # Bintool is missing; just use the input data as the output
            self.record_missing_bintool(self.mkimage)
            self.SetContents(data)

        return True
예제 #9
0
파일: intel_ifwi.py 프로젝트: tmn505/u-boot
    def _BuildIfwi(self):
        """Build the contents of the IFWI and write it to the 'data' property"""
        # Create the IFWI file if needed
        if self._convert_fit:
            inname = self._pathname
            outname = tools.get_output_filename('ifwi.bin')
            if self.ifwitool.create_ifwi(inname, outname) is None:
                # Bintool is missing; just create a zeroed ifwi.bin
                self.record_missing_bintool(self.ifwitool)
                self.SetContents(tools.get_bytes(0, 1024))

            self._filename = 'ifwi.bin'
            self._pathname = outname
        else:
            # Provide a different code path here to ensure we have test coverage
            outname = self._pathname

        # Delete OBBP if it is there, then add the required new items
        if self.ifwitool.delete_subpart(outname, 'OBBP') is None:
            # Bintool is missing; just use zero data
            self.record_missing_bintool(self.ifwitool)
            self.SetContents(tools.get_bytes(0, 1024))
            return True

        for entry in self._ifwi_entries.values():
            # First get the input data and put it in a file
            data = entry.GetPaddedData()
            uniq = self.GetUniqueName()
            input_fname = tools.get_output_filename('input.%s' % uniq)
            tools.write_file(input_fname, data)

            # At this point we know that ifwitool is present, so we don't need
            # to check for None here
            self.ifwitool.add_subpart(outname, entry._ifwi_subpart,
                                      entry._ifwi_entry_name, input_fname,
                                      entry._ifwi_replace)

        self.ReadBlobContents()
        return True
예제 #10
0
    def WriteMap(self):
        """Write a map of the image to a .map file

        Returns:
            Filename of map file written
        """
        filename = '%s.map' % self.image_name
        fname = tools.get_output_filename(filename)
        with open(fname, 'w') as fd:
            print('%8s  %8s  %8s  %s' % ('ImagePos', 'Offset', 'Size', 'Name'),
                  file=fd)
            super().WriteMap(fd, 0)
        return fname
예제 #11
0
    def FromFile(cls, fname):
        """Convert an image file into an Image for use in binman

        Args:
            fname: Filename of image file to read

        Returns:
            Image object on success

        Raises:
            ValueError if something goes wrong
        """
        data = tools.read_file(fname)
        size = len(data)

        # First look for an image header
        pos = image_header.LocateHeaderOffset(data)
        if pos is None:
            # Look for the FDT map
            pos = fdtmap.LocateFdtmap(data)
        if pos is None:
            raise ValueError('Cannot find FDT map in image')

        # We don't know the FDT size, so check its header first
        probe_dtb = fdt.Fdt.FromData(data[pos + fdtmap.FDTMAP_HDR_LEN:pos +
                                          256])
        dtb_size = probe_dtb.GetFdtObj().totalsize()
        fdtmap_data = data[pos:pos + dtb_size + fdtmap.FDTMAP_HDR_LEN]
        fdt_data = fdtmap_data[fdtmap.FDTMAP_HDR_LEN:]
        out_fname = tools.get_output_filename('fdtmap.in.dtb')
        tools.write_file(out_fname, fdt_data)
        dtb = fdt.Fdt(out_fname)
        dtb.Scan()

        # Return an Image with the associated nodes
        root = dtb.GetRoot()
        image = Image('image',
                      root,
                      copy_to_orig=False,
                      ignore_missing=True,
                      missing_etype=True,
                      generate=False)

        image.image_node = fdt_util.GetString(root, 'image-node', 'image')
        image.fdtmap_dtb = dtb
        image.fdtmap_data = fdtmap_data
        image._data = data
        image._filename = fname
        image.image_name, _ = os.path.splitext(fname)
        return image
예제 #12
0
    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.get_output_filename('vblock.%s' % uniq)
        input_fname = tools.get_output_filename('input.%s' % uniq)
        tools.write_file(input_fname, input_data)
        prefix = self.keydir + '/'
        stdout = self.futility.sign_firmware(vblock=output_fname,
                                             keyblock=prefix + self.keyblock,
                                             signprivate=prefix +
                                             self.signprivate,
                                             version=f'{self.version,}',
                                             firmware=input_fname,
                                             kernelkey=prefix + self.kernelkey,
                                             flags=f'{self.preamble_flags}')
        if stdout is not None:
            data = tools.read_file(output_fname)
        else:
            # Bintool is missing; just use 4KB of zero data
            self.record_missing_bintool(self.futility)
            data = tools.get_bytes(0, 4096)
        return data
예제 #13
0
    def ObtainContents(self):
        data, input_fname, uniq = self.collect_contents_to_file(
            self._mkimage_entries.values(), 'mkimage')
        if data is False:
            return False
        output_fname = tools.get_output_filename('mkimage-out.%s' % uniq)
        if self.mkimage.run_cmd('-d', input_fname, *self._args,
                                output_fname) is not None:
            self.SetContents(tools.read_file(output_fname))
        else:
            # Bintool is missing; just use the input data as the output
            self.record_missing_bintool(self.mkimage)
            self.SetContents(data)

        return True
예제 #14
0
    def check_fake_fname(self, fname):
        """If the file is missing and the entry allows fake blobs, fake it

        Sets self.faked to True if faked

        Args:
            fname (str): Filename to check

        Returns:
            fname (str): Filename of faked file
        """
        if self.allow_fake and not pathlib.Path(fname).is_file():
            outfname = tools.get_output_filename(os.path.basename(fname))
            with open(outfname, "wb") as out:
                out.truncate(1024)
            self.faked = True
            return outfname
        return fname
예제 #15
0
    def test_fiptool_list(self):
        """Create a FIP and check that fiptool can read it"""
        fwu = b'my data'
        tb_fw = b'some more data'
        fip = fip_util.FipWriter(0x123, 0x10)
        fip.add_entry('fwu', fwu, 0x456)
        fip.add_entry('tb-fw', tb_fw, 0)
        fip.add_entry(bytes(range(16)), tb_fw, 0)
        data = fip.get_data()
        fname = tools.get_output_filename('data.fip')
        tools.write_file(fname, data)
        result = FIPTOOL.info(fname)
        self.assertEqual(
            '''Firmware Updater NS_BL2U: offset=0xB0, size=0x7, cmdline="--fwu"
Trusted Boot Firmware BL2: offset=0xC0, size=0xE, cmdline="--tb-fw"
00010203-0405-0607-0809-0A0B0C0D0E0F: offset=0xD0, size=0xE, cmdline="--blob"
''',
            result)
예제 #16
0
    def setUp(self):
        # Create a temporary directory for test files
        self._indir = tempfile.mkdtemp(prefix='fip_util.')
        tools.set_input_dirs([self._indir])

        # Set up a temporary output directory, used by the tools library when
        # compressing files
        tools.prepare_output_dir(None)

        self.src_file = os.path.join(self._indir, 'orig.py')
        self.outname = tools.get_output_filename('out.py')
        self.args = ['-D', '-s', self._indir, '-o', self.outname]
        self.readme = os.path.join(self._indir, 'readme.rst')
        self.macro_dir = os.path.join(self._indir, 'include/tools_share')
        self.macro_fname = os.path.join(self.macro_dir,
                                        'firmware_image_package.h')
        self.name_dir = os.path.join(self._indir, 'tools/fiptool')
        self.name_fname = os.path.join(self.name_dir, 'tbbr_config.c')
예제 #17
0
파일: state.py 프로젝트: petegriffin/u-boot
def PrepareFromLoadedData(image):
    """Get device tree files ready for use with a loaded image

    Loaded images are different from images that are being created by binman,
    since there is generally already an fdtmap and we read the description from
    that. This provides the position and size of every entry in the image with
    no calculation required.

    This function uses the same output_fdt_info[] as Prepare(). It finds the
    device tree files, adds a reference to the fdtmap and sets the FDT path
    prefix to translate from the fdtmap (where the root node is the image node)
    to the normal device tree (where the image node is under a /binman node).

    Args:
        images: List of images being used
    """
    global output_fdt_info, main_dtb, fdt_path_prefix

    tout.info('Preparing device trees')
    output_fdt_info.clear()
    fdt_path_prefix = ''
    output_fdt_info['fdtmap'] = [image.fdtmap_dtb, 'u-boot.dtb']
    main_dtb = None
    tout.info("   Found device tree type 'fdtmap' '%s'" %
              image.fdtmap_dtb.name)
    for etype, value in image.GetFdts().items():
        entry, fname = value
        out_fname = tools.get_output_filename('%s.dtb' % entry.etype)
        tout.info("   Found device tree type '%s' at '%s' path '%s'" %
                  (etype, out_fname, entry.GetPath()))
        entry._filename = entry.GetDefaultFilename()
        data = entry.ReadData()

        tools.write_file(out_fname, data)
        dtb = fdt.Fdt(out_fname)
        dtb.Scan()
        image_node = dtb.GetNode('/binman')
        if 'multiple-images' in image_node.props:
            image_node = dtb.GetNode('/binman/%s' % image.image_node)
        fdt_path_prefix = image_node.path
        output_fdt_info[etype] = [dtb, None]
    tout.info("   FDT path prefix '%s'" % fdt_path_prefix)
예제 #18
0
    def create_fiptool_image(self):
        """Create an image with fiptool which we can use for testing

        Returns:
            FipReader: reader for the image
        """
        fwu = os.path.join(self._indir, 'fwu')
        tools.write_file(fwu, self.fwu_data)

        tb_fw = os.path.join(self._indir, 'tb_fw')
        tools.write_file(tb_fw, self.tb_fw_data)

        other_fw = os.path.join(self._indir, 'other_fw')
        tools.write_file(other_fw, self.other_fw_data)

        fname = tools.get_output_filename('data.fip')
        uuid = 'e3b78d9e-4a64-11ec-b45c-fba2b9b49788'
        FIPTOOL.create_new(fname, 8, 0x123, fwu, tb_fw, uuid, other_fw)

        return fip_util.FipReader(tools.read_file(fname))
예제 #19
0
파일: entry.py 프로젝트: hanetzer/u-boot
    def check_fake_fname(self, fname, size=0):
        """If the file is missing and the entry allows fake blobs, fake it

        Sets self.faked to True if faked

        Args:
            fname (str): Filename to check
            size (int): Size of fake file to create

        Returns:
            tuple:
                fname (str): Filename of faked file
                bool: True if the blob was faked, False if not
        """
        if self.allow_fake and not pathlib.Path(fname).is_file():
            outfname = tools.get_output_filename(os.path.basename(fname))
            with open(outfname, "wb") as out:
                out.truncate(size)
            self.faked = True
            tout.info(f"Entry '{self._node.path}': Faked file '{outfname}'")
            return outfname, True
        return fname, False
예제 #20
0
파일: state.py 프로젝트: tmn505/u-boot
def Prepare(images, dtb):
    """Get device tree files ready for use

    This sets up a set of device tree files that can be retrieved by
    GetAllFdts(). This includes U-Boot proper and any SPL device trees.

    Args:
        images: List of images being used
        dtb: Main dtb
    """
    global output_fdt_info, main_dtb, fdt_path_prefix
    # Import these here in case libfdt.py is not available, in which case
    # the above help option still works.
    from dtoc import fdt
    from dtoc import fdt_util

    # If we are updating the DTBs we need to put these updated versions
    # where Entry_blob_dtb can find them. We can ignore 'u-boot.dtb'
    # since it is assumed to be the one passed in with options.dt, and
    # was handled just above.
    main_dtb = dtb
    output_fdt_info.clear()
    fdt_path_prefix = ''
    output_fdt_info['u-boot-dtb'] = [dtb, 'u-boot.dtb']
    if use_fake_dtb:
        for etype, fname in DTB_TYPE_FNAME.items():
            output_fdt_info[etype] = [dtb, fname]
    else:
        fdt_set = {}
        for etype, fname in DTB_TYPE_FNAME.items():
            infile = tools.get_input_filename(fname, allow_missing=True)
            if infile and os.path.exists(infile):
                fname_dtb = fdt_util.EnsureCompiled(infile)
                out_fname = tools.get_output_filename('%s.out' %
                        os.path.split(fname)[1])
                tools.write_file(out_fname, tools.read_file(fname_dtb))
                other_dtb = fdt.FdtScan(out_fname)
                output_fdt_info[etype] = [other_dtb, out_fname]
예제 #21
0
    def ObtainContents(self):
        # If the section does not need microcode, there is nothing to do
        found = False
        for suffix in ['', '-spl', '-tpl']:
            name = 'u-boot%s-with-ucode-ptr' % suffix
            entry = self.section.FindEntryType(name)
            if entry and entry.target_offset:
                found = True
        if not found:
            self.data = b''
            return True
        # Get the microcode from the device tree entry. If it is not available
        # yet, return False so we will be called later. If the section simply
        # doesn't exist, then we may as well return True, since we are going to
        # get an error anyway.
        for suffix in ['', '-spl', '-tpl']:
            name = 'u-boot%s-dtb-with-ucode' % suffix
            fdt_entry = self.section.FindEntryType(name)
            if fdt_entry:
                break
        if not fdt_entry:
            self.data = b''
            return True
        if not fdt_entry.ready:
            return False

        if not fdt_entry.collate:
            # This binary can be empty
            self.data = b''
            return True

        # Write it out to a file
        self._pathname = tools.get_output_filename('u-boot-ucode.bin')
        tools.write_file(self._pathname, fdt_entry.ucode_data)

        self.ReadBlobContents()

        return True
예제 #22
0
파일: test_fdt.py 프로젝트: tmn505/u-boot
 def testGetFilename(self):
     """Test the dtb filename can be provided"""
     self.assertEqual(tools.get_output_filename('source.dtb'),
                      self.dtb.GetFilename())
예제 #23
0
def PrepareImagesAndDtbs(dtb_fname, select_images, update_fdt, use_expanded):
    """Prepare the images to be processed and select the device tree

    This function:
    - reads in the device tree
    - finds and scans the binman node to create all entries
    - selects which images to build
    - Updates the device tress with placeholder properties for offset,
        image-pos, etc.

    Args:
        dtb_fname: Filename of the device tree file to use (.dts or .dtb)
        selected_images: List of images to output, or None for all
        update_fdt: True to update the FDT wth entry offsets, etc.
        use_expanded: True to use expanded versions of entries, if available.
            So if 'u-boot' is called for, we use 'u-boot-expanded' instead. This
            is needed if update_fdt is True (although tests may disable it)

    Returns:
        OrderedDict of images:
            key: Image name (str)
            value: Image object
    """
    # Import these here in case libfdt.py is not available, in which case
    # the above help option still works.
    from dtoc import fdt
    from dtoc import fdt_util
    global images

    # Get the device tree ready by compiling it and copying the compiled
    # output into a file in our output directly. Then scan it for use
    # in binman.
    dtb_fname = fdt_util.EnsureCompiled(dtb_fname)
    fname = tools.get_output_filename('u-boot.dtb.out')
    tools.write_file(fname, tools.read_file(dtb_fname))
    dtb = fdt.FdtScan(fname)

    node = _FindBinmanNode(dtb)
    if not node:
        raise ValueError("Device tree '%s' does not have a 'binman' "
                         "node" % dtb_fname)

    images = _ReadImageDesc(node, use_expanded)

    if select_images:
        skip = []
        new_images = OrderedDict()
        for name, image in images.items():
            if name in select_images:
                new_images[name] = image
            else:
                skip.append(name)
        images = new_images
        tout.notice('Skipping images: %s' % ', '.join(skip))

    state.Prepare(images, dtb)

    # Prepare the device tree by making sure that any missing
    # properties are added (e.g. 'pos' and 'size'). The values of these
    # may not be correct yet, but we add placeholders so that the
    # size of the device tree is correct. Later, in
    # SetCalculatedProperties() we will insert the correct values
    # without changing the device-tree size, thus ensuring that our
    # entry offsets remain the same.
    for image in images.values():
        image.CollectBintools()
        image.gen_entries()
        if update_fdt:
            image.AddMissingProperties(True)
        image.ProcessFdt(dtb)

    for dtb_item in state.GetAllFdts():
        dtb_item.Sync(auto_resize=True)
        dtb_item.Pack()
        dtb_item.Flush()
    return images