diff options
Diffstat (limited to 'tools/binman/etype')
-rw-r--r-- | tools/binman/etype/_testing.py | 7 | ||||
-rw-r--r-- | tools/binman/etype/blob.py | 49 | ||||
-rw-r--r-- | tools/binman/etype/blob_dtb.py | 33 | ||||
-rw-r--r-- | tools/binman/etype/files.py | 57 | ||||
-rw-r--r-- | tools/binman/etype/fill.py | 2 | ||||
-rw-r--r-- | tools/binman/etype/fmap.py | 11 | ||||
-rw-r--r-- | tools/binman/etype/section.py | 14 | ||||
-rw-r--r-- | tools/binman/etype/text.py | 3 | ||||
-rw-r--r-- | tools/binman/etype/u_boot_dtb.py | 9 | ||||
-rw-r--r-- | tools/binman/etype/u_boot_dtb_with_ucode.py | 27 | ||||
-rw-r--r-- | tools/binman/etype/u_boot_elf.py | 39 | ||||
-rw-r--r-- | tools/binman/etype/u_boot_spl_dtb.py | 6 | ||||
-rw-r--r-- | tools/binman/etype/u_boot_spl_elf.py | 24 | ||||
-rw-r--r-- | tools/binman/etype/u_boot_spl_with_ucode_ptr.py | 2 | ||||
-rw-r--r-- | tools/binman/etype/u_boot_tpl_dtb.py | 6 | ||||
-rw-r--r-- | tools/binman/etype/u_boot_tpl_dtb_with_ucode.py | 25 | ||||
-rw-r--r-- | tools/binman/etype/u_boot_tpl_with_ucode_ptr.py | 27 | ||||
-rw-r--r-- | tools/binman/etype/u_boot_ucode.py | 26 | ||||
-rw-r--r-- | tools/binman/etype/u_boot_with_ucode_ptr.py | 24 | ||||
-rw-r--r-- | tools/binman/etype/vblock.py | 11 | ||||
-rw-r--r-- | tools/binman/etype/x86_start16_tpl.py | 30 |
21 files changed, 371 insertions, 61 deletions
diff --git a/tools/binman/etype/_testing.py b/tools/binman/etype/_testing.py index 02c165c0c3..3e345bd952 100644 --- a/tools/binman/etype/_testing.py +++ b/tools/binman/etype/_testing.py @@ -48,6 +48,8 @@ class Entry__testing(Entry): 'return-unknown-contents') self.bad_update_contents = fdt_util.GetBool(self._node, 'bad-update-contents') + self.return_contents_once = fdt_util.GetBool(self._node, + 'return-contents-once') # Set to True when the entry is ready to process the FDT. self.process_fdt_ready = False @@ -68,12 +70,15 @@ class Entry__testing(Entry): EntryArg('test-existing-prop', str)], self.require_args) if self.force_bad_datatype: self.GetEntryArgsOrProps([EntryArg('test-bad-datatype-arg', bool)]) + self.return_contents = True def ObtainContents(self): - if self.return_unknown_contents: + if self.return_unknown_contents or not self.return_contents: return False self.data = 'a' self.contents_size = len(self.data) + if self.return_contents_once: + self.return_contents = False return True def GetOffsets(self): diff --git a/tools/binman/etype/blob.py b/tools/binman/etype/blob.py index 3f46eecf30..642a0e482a 100644 --- a/tools/binman/etype/blob.py +++ b/tools/binman/etype/blob.py @@ -7,6 +7,7 @@ from entry import Entry import fdt_util +import state import tools class Entry_blob(Entry): @@ -17,14 +18,23 @@ class Entry_blob(Entry): Properties / Entry arguments: - filename: Filename of file to read into entry + - compress: Compression algorithm to use: + none: No compression + lz4: Use lz4 compression (via 'lz4' command-line utility) This entry reads data from a file and places it in the entry. The default filename is often specified specified by the subclass. See for example the 'u_boot' entry which provides the filename 'u-boot.bin'. + + If compression is enabled, an extra 'uncomp-size' property is written to + the node (if enabled with -u) which provides the uncompressed size of the + data. """ def __init__(self, section, etype, node): Entry.__init__(self, section, etype, node) - self._filename = fdt_util.GetString(self._node, "filename", self.etype) + self._filename = fdt_util.GetString(self._node, 'filename', self.etype) + self._compress = fdt_util.GetString(self._node, 'compress', 'none') + self._uncompressed_size = None def ObtainContents(self): self._filename = self.GetDefaultFilename() @@ -33,15 +43,36 @@ class Entry_blob(Entry): return True def ReadBlobContents(self): - with open(self._pathname) as fd: - # We assume the data is small enough to fit into memory. If this - # is used for large filesystem image that might not be true. - # In that case, Image.BuildImage() could be adjusted to use a - # new Entry method which can read in chunks. Then we could copy - # the data in chunks and avoid reading it all at once. For now - # this seems like an unnecessary complication. - self.SetContents(fd.read()) + # We assume the data is small enough to fit into memory. If this + # is used for large filesystem image that might not be true. + # In that case, Image.BuildImage() could be adjusted to use a + # new Entry method which can read in chunks. Then we could copy + # the data in chunks and avoid reading it all at once. For now + # this seems like an unnecessary complication. + data = tools.ReadFile(self._pathname) + if self._compress == 'lz4': + self._uncompressed_size = len(data) + ''' + import lz4 # Import this only if needed (python-lz4 dependency) + + try: + data = lz4.frame.compress(data) + except AttributeError: + data = lz4.compress(data) + ''' + data = tools.Run('lz4', '-c', self._pathname, ) + self.SetContents(data) return True def GetDefaultFilename(self): return self._filename + + def AddMissingProperties(self): + Entry.AddMissingProperties(self) + if self._compress != 'none': + state.AddZeroProp(self._node, 'uncomp-size') + + def SetCalculatedProperties(self): + Entry.SetCalculatedProperties(self) + if self._uncompressed_size is not None: + state.SetInt(self._node, 'uncomp-size', self._uncompressed_size) diff --git a/tools/binman/etype/blob_dtb.py b/tools/binman/etype/blob_dtb.py new file mode 100644 index 0000000000..cc5b4a3f76 --- /dev/null +++ b/tools/binman/etype/blob_dtb.py @@ -0,0 +1,33 @@ +# SPDX-License-Identifier: GPL-2.0+ +# Copyright (c) 2018 Google, Inc +# Written by Simon Glass <sjg@chromium.org> +# +# Entry-type module for U-Boot device tree files +# + +import state + +from entry import Entry +from blob import Entry_blob + +class Entry_blob_dtb(Entry_blob): + """A blob that holds a device tree + + This is a blob containing a device tree. The contents of the blob are + obtained from the list of available device-tree files, managed by the + 'state' module. + """ + def __init__(self, section, etype, node): + Entry_blob.__init__(self, section, etype, node) + + def ObtainContents(self): + """Get the device-tree from the list held by the 'state' module""" + self._filename = self.GetDefaultFilename() + self._pathname, data = state.GetFdtContents(self._filename) + self.SetContents(data) + return True + + def ProcessContents(self): + """Re-read the DTB contents so that we get any calculated properties""" + _, data = state.GetFdtContents(self._filename) + self.SetContents(data) diff --git a/tools/binman/etype/files.py b/tools/binman/etype/files.py new file mode 100644 index 0000000000..99f2f2f67f --- /dev/null +++ b/tools/binman/etype/files.py @@ -0,0 +1,57 @@ +# SPDX-License-Identifier: GPL-2.0+ +# Copyright (c) 2018 Google, Inc +# Written by Simon Glass <sjg@chromium.org> +# +# Entry-type module for a set of files which are placed in individual +# sub-entries +# + +import glob +import os + +from section import Entry_section +import fdt_util +import state +import tools + +import bsection + +class Entry_files(Entry_section): + """Entry containing a set of files + + Properties / Entry arguments: + - pattern: Filename pattern to match the files to include + - compress: Compression algorithm to use: + none: No compression + lz4: Use lz4 compression (via 'lz4' command-line utility) + + This entry reads a number of files and places each in a separate sub-entry + within this entry. To access these you need to enable device-tree updates + at run-time so you can obtain the file positions. + """ + def __init__(self, section, etype, node): + Entry_section.__init__(self, section, etype, node) + self._pattern = fdt_util.GetString(self._node, 'pattern') + if not self._pattern: + self.Raise("Missing 'pattern' property") + self._compress = fdt_util.GetString(self._node, 'compress', 'none') + self._require_matches = fdt_util.GetBool(self._node, + 'require-matches') + + def ExpandEntries(self): + files = tools.GetInputFilenameGlob(self._pattern) + if self._require_matches and not files: + self.Raise("Pattern '%s' matched no files" % self._pattern) + for fname in files: + if not os.path.isfile(fname): + continue + name = os.path.basename(fname) + subnode = self._node.FindNode(name) + if not subnode: + subnode = state.AddSubnode(self._node, name) + state.AddString(subnode, 'type', 'blob') + state.AddString(subnode, 'filename', fname) + state.AddString(subnode, 'compress', self._compress) + + # Read entries again, now that we have some + self._section._ReadEntries() diff --git a/tools/binman/etype/fill.py b/tools/binman/etype/fill.py index 7210a8324a..dcfe978a5b 100644 --- a/tools/binman/etype/fill.py +++ b/tools/binman/etype/fill.py @@ -23,7 +23,7 @@ class Entry_fill(Entry): """ def __init__(self, section, etype, node): Entry.__init__(self, section, etype, node) - if not self.size: + if self.size is None: self.Raise("'fill' entry must have a size property") self.fill_value = fdt_util.GetByte(self._node, 'fill-byte', 0) diff --git a/tools/binman/etype/fmap.py b/tools/binman/etype/fmap.py index f1dd81ec49..bf35a5bbf4 100644 --- a/tools/binman/etype/fmap.py +++ b/tools/binman/etype/fmap.py @@ -42,14 +42,17 @@ class Entry_fmap(Entry): for subentry in entries.values(): _AddEntries(areas, subentry) else: - areas.append(fmap_util.FmapArea(entry.image_pos or 0, - entry.size or 0, entry.name, 0)) + pos = entry.image_pos + if pos is not None: + pos -= entry.section.GetRootSkipAtStart() + areas.append(fmap_util.FmapArea(pos or 0, entry.size or 0, + entry.name, 0)) - entries = self.section.GetEntries() + entries = self.section._image.GetEntries() areas = [] for entry in entries.values(): _AddEntries(areas, entry) - return fmap_util.EncodeFmap(self.section.GetSize() or 0, self.name, + return fmap_util.EncodeFmap(self.section.GetImageSize() or 0, self.name, areas) def ObtainContents(self): diff --git a/tools/binman/etype/section.py b/tools/binman/etype/section.py index f5b2ed67cf..7f1b413604 100644 --- a/tools/binman/etype/section.py +++ b/tools/binman/etype/section.py @@ -32,11 +32,19 @@ class Entry_section(Entry): """ def __init__(self, section, etype, node): Entry.__init__(self, section, etype, node) - self._section = bsection.Section(node.name, node) + self._section = bsection.Section(node.name, section, node, + section._image) + + def GetFdtSet(self): + return self._section.GetFdtSet() def ProcessFdt(self, fdt): return self._section.ProcessFdt(fdt) + def ExpandEntries(self): + Entry.ExpandEntries(self) + self._section.ExpandEntries() + def AddMissingProperties(self): Entry.AddMissingProperties(self) self._section.AddMissingProperties() @@ -92,3 +100,7 @@ class Entry_section(Entry): def GetEntries(self): return self._section.GetEntries() + + def ExpandToLimit(self, limit): + super(Entry_section, self).ExpandToLimit(limit) + self._section.ExpandSize(self.size) diff --git a/tools/binman/etype/text.py b/tools/binman/etype/text.py index 7a1cddf4af..6e99819487 100644 --- a/tools/binman/etype/text.py +++ b/tools/binman/etype/text.py @@ -51,6 +51,9 @@ class Entry_text(Entry): self.text_label, = self.GetEntryArgsOrProps( [EntryArg('text-label', str)]) self.value, = self.GetEntryArgsOrProps([EntryArg(self.text_label, str)]) + if not self.value: + self.Raise("No value provided for text label '%s'" % + self.text_label) def ObtainContents(self): self.SetContents(self.value) diff --git a/tools/binman/etype/u_boot_dtb.py b/tools/binman/etype/u_boot_dtb.py index fb3dd1cf64..6263c4ebee 100644 --- a/tools/binman/etype/u_boot_dtb.py +++ b/tools/binman/etype/u_boot_dtb.py @@ -6,9 +6,9 @@ # from entry import Entry -from blob import Entry_blob +from blob_dtb import Entry_blob_dtb -class Entry_u_boot_dtb(Entry_blob): +class Entry_u_boot_dtb(Entry_blob_dtb): """U-Boot device tree Properties / Entry arguments: @@ -17,9 +17,12 @@ class Entry_u_boot_dtb(Entry_blob): This is the U-Boot device tree, containing configuration information for U-Boot. U-Boot needs this to know what devices are present and which drivers to activate. + + Note: This is mostly an internal entry type, used by others. This allows + binman to know which entries contain a device tree. """ def __init__(self, section, etype, node): - Entry_blob.__init__(self, section, etype, node) + Entry_blob_dtb.__init__(self, section, etype, node) def GetDefaultFilename(self): return 'u-boot.dtb' diff --git a/tools/binman/etype/u_boot_dtb_with_ucode.py b/tools/binman/etype/u_boot_dtb_with_ucode.py index 285a28dd1e..444c51b8b7 100644 --- a/tools/binman/etype/u_boot_dtb_with_ucode.py +++ b/tools/binman/etype/u_boot_dtb_with_ucode.py @@ -5,12 +5,12 @@ # Entry-type module for U-Boot device tree with the microcode removed # -import control from entry import Entry -from blob import Entry_blob +from blob_dtb import Entry_blob_dtb +import state import tools -class Entry_u_boot_dtb_with_ucode(Entry_blob): +class Entry_u_boot_dtb_with_ucode(Entry_blob_dtb): """A U-Boot device tree file, with the microcode removed Properties / Entry arguments: @@ -25,7 +25,7 @@ class Entry_u_boot_dtb_with_ucode(Entry_blob): it available to u_boot_ucode. """ def __init__(self, section, etype, node): - Entry_blob.__init__(self, section, etype, node) + Entry_blob_dtb.__init__(self, section, etype, node) self.ucode_data = '' self.collate = False self.ucode_offset = None @@ -45,13 +45,16 @@ class Entry_u_boot_dtb_with_ucode(Entry_blob): 'u-boot-spl-with-ucode-ptr') if not ucode_dest_entry or not ucode_dest_entry.target_offset: ucode_dest_entry = self.section.FindEntryType( + 'u-boot-tpl-with-ucode-ptr') + if not ucode_dest_entry or not ucode_dest_entry.target_offset: + ucode_dest_entry = self.section.FindEntryType( 'u-boot-with-ucode-ptr') if not ucode_dest_entry or not ucode_dest_entry.target_offset: return True # Remove the microcode fname = self.GetDefaultFilename() - fdt = control.GetFdt(fname) + fdt = state.GetFdt(fname) self.ucode = fdt.GetNode('/microcode') if not self.ucode: raise self.Raise("No /microcode node found in '%s'" % fname) @@ -69,15 +72,15 @@ class Entry_u_boot_dtb_with_ucode(Entry_blob): def ObtainContents(self): # Call the base class just in case it does something important. - Entry_blob.ObtainContents(self) - self._pathname = control.GetFdtPath(self._filename) - self.ReadBlobContents() - if self.ucode: + Entry_blob_dtb.ObtainContents(self) + if self.ucode and not self.collate: for node in self.ucode.subnodes: data_prop = node.props.get('data') - if data_prop and not self.collate: + if data_prop: # Find the offset in the device tree of the ucode data self.ucode_offset = data_prop.GetOffset() + 12 self.ucode_size = len(data_prop.bytes) - self.ready = True - return True + self.ready = True + else: + self.ready = True + return self.ready diff --git a/tools/binman/etype/u_boot_elf.py b/tools/binman/etype/u_boot_elf.py new file mode 100644 index 0000000000..134b6cc15b --- /dev/null +++ b/tools/binman/etype/u_boot_elf.py @@ -0,0 +1,39 @@ +# SPDX-License-Identifier: GPL-2.0+ +# Copyright (c) 2018 Google, Inc +# Written by Simon Glass <sjg@chromium.org> +# +# Entry-type module for U-Boot ELF image +# + +from entry import Entry +from blob import Entry_blob + +import fdt_util +import tools + +class Entry_u_boot_elf(Entry_blob): + """U-Boot ELF image + + Properties / Entry arguments: + - filename: Filename of u-boot (default 'u-boot') + + This is the U-Boot ELF image. It does not include a device tree but can be + relocated to any address for execution. + """ + def __init__(self, section, etype, node): + Entry_blob.__init__(self, section, etype, node) + self._strip = fdt_util.GetBool(self._node, 'strip') + + 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.SetContents(tools.ReadFile(out_fname)) + else: + self.SetContents(tools.ReadFile(self._pathname)) + return True + + def GetDefaultFilename(self): + return 'u-boot' diff --git a/tools/binman/etype/u_boot_spl_dtb.py b/tools/binman/etype/u_boot_spl_dtb.py index cb29ba3fd8..e7354646f1 100644 --- a/tools/binman/etype/u_boot_spl_dtb.py +++ b/tools/binman/etype/u_boot_spl_dtb.py @@ -6,9 +6,9 @@ # from entry import Entry -from blob import Entry_blob +from blob_dtb import Entry_blob_dtb -class Entry_u_boot_spl_dtb(Entry_blob): +class Entry_u_boot_spl_dtb(Entry_blob_dtb): """U-Boot SPL device tree Properties / Entry arguments: @@ -19,7 +19,7 @@ class Entry_u_boot_spl_dtb(Entry_blob): to activate. """ def __init__(self, section, etype, node): - Entry_blob.__init__(self, section, etype, node) + Entry_blob_dtb.__init__(self, section, etype, node) def GetDefaultFilename(self): return 'spl/u-boot-spl.dtb' diff --git a/tools/binman/etype/u_boot_spl_elf.py b/tools/binman/etype/u_boot_spl_elf.py new file mode 100644 index 0000000000..da328ae15e --- /dev/null +++ b/tools/binman/etype/u_boot_spl_elf.py @@ -0,0 +1,24 @@ +# SPDX-License-Identifier: GPL-2.0+ +# Copyright (c) 2018 Google, Inc +# Written by Simon Glass <sjg@chromium.org> +# +# Entry-type module for U-Boot SPL ELF image +# + +from entry import Entry +from blob import Entry_blob + +class Entry_u_boot_spl_elf(Entry_blob): + """U-Boot SPL ELF image + + Properties / Entry arguments: + - filename: Filename of SPL u-boot (default 'spl/u-boot') + + This is the U-Boot SPL ELF image. It does not include a device tree but can + be relocated to any address for execution. + """ + def __init__(self, section, etype, node): + Entry_blob.__init__(self, section, etype, node) + + def GetDefaultFilename(self): + return 'spl/u-boot-spl' diff --git a/tools/binman/etype/u_boot_spl_with_ucode_ptr.py b/tools/binman/etype/u_boot_spl_with_ucode_ptr.py index 0dfe268a56..b650cf0146 100644 --- a/tools/binman/etype/u_boot_spl_with_ucode_ptr.py +++ b/tools/binman/etype/u_boot_spl_with_ucode_ptr.py @@ -16,6 +16,8 @@ import tools class Entry_u_boot_spl_with_ucode_ptr(Entry_u_boot_with_ucode_ptr): """U-Boot SPL with embedded microcode pointer + This is used when SPL must set up the microcode for U-Boot. + See Entry_u_boot_ucode for full details of the entries involved in this process. """ diff --git a/tools/binman/etype/u_boot_tpl_dtb.py b/tools/binman/etype/u_boot_tpl_dtb.py index 9c4e668347..bdeb0f75a2 100644 --- a/tools/binman/etype/u_boot_tpl_dtb.py +++ b/tools/binman/etype/u_boot_tpl_dtb.py @@ -6,9 +6,9 @@ # from entry import Entry -from blob import Entry_blob +from blob_dtb import Entry_blob_dtb -class Entry_u_boot_tpl_dtb(Entry_blob): +class Entry_u_boot_tpl_dtb(Entry_blob_dtb): """U-Boot TPL device tree Properties / Entry arguments: @@ -19,7 +19,7 @@ class Entry_u_boot_tpl_dtb(Entry_blob): to activate. """ def __init__(self, section, etype, node): - Entry_blob.__init__(self, section, etype, node) + Entry_blob_dtb.__init__(self, section, etype, node) def GetDefaultFilename(self): return 'tpl/u-boot-tpl.dtb' diff --git a/tools/binman/etype/u_boot_tpl_dtb_with_ucode.py b/tools/binman/etype/u_boot_tpl_dtb_with_ucode.py new file mode 100644 index 0000000000..71e04fcd44 --- /dev/null +++ b/tools/binman/etype/u_boot_tpl_dtb_with_ucode.py @@ -0,0 +1,25 @@ +# SPDX-License-Identifier: GPL-2.0+ +# Copyright (c) 2016 Google, Inc +# Written by Simon Glass <sjg@chromium.org> +# +# Entry-type module for U-Boot device tree with the microcode removed +# + +import control +from entry import Entry +from u_boot_dtb_with_ucode import Entry_u_boot_dtb_with_ucode +import tools + +class Entry_u_boot_tpl_dtb_with_ucode(Entry_u_boot_dtb_with_ucode): + """U-Boot TPL with embedded microcode pointer + + This is used when TPL must set up the microcode for U-Boot. + + See Entry_u_boot_ucode for full details of the entries involved in this + process. + """ + def __init__(self, section, etype, node): + Entry_u_boot_dtb_with_ucode.__init__(self, section, etype, node) + + def GetDefaultFilename(self): + return 'tpl/u-boot-tpl.dtb' diff --git a/tools/binman/etype/u_boot_tpl_with_ucode_ptr.py b/tools/binman/etype/u_boot_tpl_with_ucode_ptr.py new file mode 100644 index 0000000000..8d94dded69 --- /dev/null +++ b/tools/binman/etype/u_boot_tpl_with_ucode_ptr.py @@ -0,0 +1,27 @@ +# SPDX-License-Identifier: GPL-2.0+ +# Copyright (c) 2016 Google, Inc +# Written by Simon Glass <sjg@chromium.org> +# +# Entry-type module for an TPL binary with an embedded microcode pointer +# + +import struct + +import command +from entry import Entry +from blob import Entry_blob +from u_boot_with_ucode_ptr import Entry_u_boot_with_ucode_ptr +import tools + +class Entry_u_boot_tpl_with_ucode_ptr(Entry_u_boot_with_ucode_ptr): + """U-Boot TPL with embedded microcode pointer + + See Entry_u_boot_ucode for full details of the entries involved in this + process. + """ + def __init__(self, section, etype, node): + Entry_u_boot_with_ucode_ptr.__init__(self, section, etype, node) + self.elf_fname = 'tpl/u-boot-tpl' + + def GetDefaultFilename(self): + return 'tpl/u-boot-tpl-nodtb.bin' diff --git a/tools/binman/etype/u_boot_ucode.py b/tools/binman/etype/u_boot_ucode.py index 6acf94d8cb..a00e530295 100644 --- a/tools/binman/etype/u_boot_ucode.py +++ b/tools/binman/etype/u_boot_ucode.py @@ -62,19 +62,24 @@ class Entry_u_boot_ucode(Entry_blob): def ObtainContents(self): # If the section does not need microcode, there is nothing to do - ucode_dest_entry = self.section.FindEntryType('u-boot-with-ucode-ptr') - ucode_dest_entry_spl = self.section.FindEntryType( - 'u-boot-spl-with-ucode-ptr') - if ((not ucode_dest_entry or not ucode_dest_entry.target_offset) and - (not ucode_dest_entry_spl or not ucode_dest_entry_spl.target_offset)): + 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 = '' 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. - fdt_entry = self.section.FindEntryType('u-boot-dtb-with-ucode') + 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: return True if not fdt_entry.ready: @@ -86,12 +91,9 @@ class Entry_u_boot_ucode(Entry_blob): return True # Write it out to a file - dtb_name = 'u-boot-ucode.bin' - fname = tools.GetOutputFilename(dtb_name) - with open(fname, 'wb') as fd: - fd.write(fdt_entry.ucode_data) + self._pathname = tools.GetOutputFilename('u-boot-ucode.bin') + tools.WriteFile(self._pathname, fdt_entry.ucode_data) - self._pathname = fname self.ReadBlobContents() return True diff --git a/tools/binman/etype/u_boot_with_ucode_ptr.py b/tools/binman/etype/u_boot_with_ucode_ptr.py index 51e7ba48f5..da0e12417b 100644 --- a/tools/binman/etype/u_boot_with_ucode_ptr.py +++ b/tools/binman/etype/u_boot_with_ucode_ptr.py @@ -19,6 +19,9 @@ class Entry_u_boot_with_ucode_ptr(Entry_blob): Properties / Entry arguments: - filename: Filename of u-boot-nodtb.dtb (default 'u-boot-nodtb.dtb') + - optional-ucode: boolean property to make microcode optional. If the + u-boot.bin image does not include microcode, no error will + be generated. See Entry_u_boot_ucode for full details of the three entries involved in this process. This entry updates U-Boot with the offset and size of the @@ -63,28 +66,31 @@ class Entry_u_boot_with_ucode_ptr(Entry_blob): # the U-Boot region must start at offset 7MB in the section. In this # case the ROM starts at 0xff800000, so the offset of the first # entry in the section corresponds to that. - if (self.target_offset < self.offset or - self.target_offset >= self.offset + self.size): - self.Raise('Microcode pointer _dt_ucode_base_size at %08x is ' - 'outside the section ranging from %08x to %08x' % - (self.target_offset, self.offset, self.offset + self.size)) + if (self.target_offset < self.image_pos or + self.target_offset >= self.image_pos + self.size): + self.Raise('Microcode pointer _dt_ucode_base_size at %08x is outside the section ranging from %08x to %08x' % + (self.target_offset, self.image_pos, + self.image_pos + self.size)) # Get the microcode, either from u-boot-ucode or u-boot-dtb-with-ucode. # If we have left the microcode in the device tree, then it will be - # in the former. If we extracted the microcode from the device tree - # and collated it in one place, it will be in the latter. + # in the latter. If we extracted the microcode from the device tree + # and collated it in one place, it will be in the former. if ucode_entry.size: offset, size = ucode_entry.offset, ucode_entry.size else: dtb_entry = self.section.FindEntryType('u-boot-dtb-with-ucode') - if not dtb_entry or not dtb_entry.ready: + if not dtb_entry: + dtb_entry = self.section.FindEntryType( + 'u-boot-tpl-dtb-with-ucode') + if not dtb_entry: self.Raise('Cannot find microcode region u-boot-dtb-with-ucode') offset = dtb_entry.offset + dtb_entry.ucode_offset size = dtb_entry.ucode_size # Write the microcode offset and size into the entry offset_and_size = struct.pack('<2L', offset, size) - self.target_offset -= self.offset + self.target_offset -= self.image_pos self.ProcessContentsUpdate(self.data[:self.target_offset] + offset_and_size + self.data[self.target_offset + 8:]) diff --git a/tools/binman/etype/vblock.py b/tools/binman/etype/vblock.py index 595af5456d..c4d970ed16 100644 --- a/tools/binman/etype/vblock.py +++ b/tools/binman/etype/vblock.py @@ -25,6 +25,11 @@ class Entry_vblock(Entry): - kernelkey: Name of the kernel key to use (inside keydir) - preamble-flags: Value of the vboot preamble flags (typically 0) + Output files: + - input.<unique_name> - input file passed to futility + - vblock.<unique_name> - output file generated by futility (which is + used as the entry contents) + Chromium OS signs the read-write firmware and kernel, writing the signature in this block. This allows U-Boot to verify that the next firmware stage and kernel are genuine. @@ -53,8 +58,9 @@ class Entry_vblock(Entry): return False input_data += data - output_fname = tools.GetOutputFilename('vblock.%s' % self.name) - input_fname = tools.GetOutputFilename('input.%s' % self.name) + 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 = [ @@ -69,6 +75,5 @@ class Entry_vblock(Entry): ] #out.Notice("Sign '%s' into %s" % (', '.join(self.value), self.label)) stdout = tools.Run('futility', *args) - #out.Debug(stdout) self.SetContents(tools.ReadFile(output_fname)) return True diff --git a/tools/binman/etype/x86_start16_tpl.py b/tools/binman/etype/x86_start16_tpl.py new file mode 100644 index 0000000000..46ce169ae0 --- /dev/null +++ b/tools/binman/etype/x86_start16_tpl.py @@ -0,0 +1,30 @@ +# SPDX-License-Identifier: GPL-2.0+ +# Copyright (c) 2018 Google, Inc +# Written by Simon Glass <sjg@chromium.org> +# +# Entry-type module for the 16-bit x86 start-up code for U-Boot TPL +# + +from entry import Entry +from blob import Entry_blob + +class Entry_x86_start16_tpl(Entry_blob): + """x86 16-bit start-up code for TPL + + Properties / Entry arguments: + - filename: Filename of tpl/u-boot-x86-16bit-tpl.bin (default + 'tpl/u-boot-x86-16bit-tpl.bin') + + x86 CPUs start up in 16-bit mode, even if they are 64-bit CPUs. This code + must be placed at a particular address. This entry holds that code. It is + typically placed at offset CONFIG_SYS_X86_START16. The code is responsible + for changing to 32-bit mode and starting TPL, which in turn jumps to SPL. + + If TPL is not being used, the 'x86_start16_spl or 'x86_start16' entry types + may be used instead. + """ + def __init__(self, section, etype, node): + Entry_blob.__init__(self, section, etype, node) + + def GetDefaultFilename(self): + return 'tpl/u-boot-x86-16bit-tpl.bin' |