[U-Boot] [PATCH 21/29] binman: Add support for Chromium GBB
Simon Glass
sjg at chromium.org
Tue Jul 17 19:25:44 UTC 2018
This entry contains a Google Binary Block, used to store keys and bitmaps
in a Chromium image.
Signed-off-by: Simon Glass <sjg at chromium.org>
---
tools/binman/README.entries | 19 +++++
tools/binman/etype/gbb.py | 96 ++++++++++++++++++++++++++
tools/binman/ftest.py | 56 +++++++++++++++
tools/binman/test/71_gbb.dts | 31 +++++++++
tools/binman/test/72_gbb_too_small.dts | 10 +++
tools/binman/test/73_gbb_no_size.dts | 9 +++
6 files changed, 221 insertions(+)
create mode 100644 tools/binman/etype/gbb.py
create mode 100644 tools/binman/test/71_gbb.dts
create mode 100644 tools/binman/test/72_gbb_too_small.dts
create mode 100644 tools/binman/test/73_gbb_no_size.dts
diff --git a/tools/binman/README.entries b/tools/binman/README.entries
index 6f09626b24..41b70192c0 100644
--- a/tools/binman/README.entries
+++ b/tools/binman/README.entries
@@ -91,6 +91,25 @@ FMAP does not support this.
+Entry: gbb: An entry which contains a Chromium OS Google Binary Block
+---------------------------------------------------------------------
+
+Properties / Entry arguments:
+ - hardware-id: Hardware ID to use for this build (a string)
+ - keydir: Directory containing the public keys to use
+ - bmpblk: Filename containing images used by recovery
+
+Chromium OS uses a GBB to store various pieces of information, in particular
+the root and recovery keys that are used to verify the boot process. Some
+more details are here:
+
+ https://www.chromium.org/chromium-os/firmware-porting-guide/2-concepts
+
+but note that the page dates from 2013 so is quite out of date. See
+README.chromium for how to obtain the required keys and tools.
+
+
+
Entry: intel-cmc: Entry containing an Intel Chipset Micro Code (CMC) file
-------------------------------------------------------------------------
diff --git a/tools/binman/etype/gbb.py b/tools/binman/etype/gbb.py
new file mode 100644
index 0000000000..8fe10f4713
--- /dev/null
+++ b/tools/binman/etype/gbb.py
@@ -0,0 +1,96 @@
+# SPDX-License-Identifier: GPL-2.0+
+# Copyright (c) 2018 Google, Inc
+# Written by Simon Glass <sjg at chromium.org>
+#
+
+# Support for a Chromium OS Google Binary Block, used to record read-only
+# information mostly used by firmware.
+
+from collections import OrderedDict
+
+import command
+from entry import Entry, EntryArg
+
+import fdt_util
+import tools
+
+# Build GBB flags.
+# (src/platform/vboot_reference/firmware/include/gbb_header.h)
+gbb_flag_properties = {
+ 'dev-screen-short-delay': 0x1,
+ 'load-option-roms': 0x2,
+ 'enable-alternate-os': 0x4,
+ 'force-dev-switch-on': 0x8,
+ 'force-dev-boot-usb': 0x10,
+ 'disable-fw-rollback-check': 0x20,
+ 'enter-triggers-tonorm': 0x40,
+ 'force-dev-boot-legacy': 0x80,
+ 'faft-key-override': 0x100,
+ 'disable-ec-software-sync': 0x200,
+ 'default-dev-boot-legacy': 0x400,
+ 'disable-pd-software-sync': 0x800,
+ 'disable-lid-shutdown': 0x1000,
+ 'force-dev-boot-fastboot-full-cap': 0x2000,
+ 'enable-serial': 0x4000,
+ 'disable-dwmp': 0x8000,
+}
+
+
+class Entry_gbb(Entry):
+ """An entry which contains a Chromium OS Google Binary Block
+
+ Properties / Entry arguments:
+ - hardware-id: Hardware ID to use for this build (a string)
+ - keydir: Directory containing the public keys to use
+ - bmpblk: Filename containing images used by recovery
+
+ Chromium OS uses a GBB to store various pieces of information, in particular
+ the root and recovery keys that are used to verify the boot process. Some
+ more details are here:
+
+ https://www.chromium.org/chromium-os/firmware-porting-guide/2-concepts
+
+ but note that the page dates from 2013 so is quite out of date. See
+ README.chromium for how to obtain the required keys and tools.
+ """
+ def __init__(self, section, etype, node):
+ Entry.__init__(self, section, etype, node)
+ self.hardware_id, self.keydir, self.bmpblk = self.GetEntryArgsOrProps(
+ [EntryArg('hardware-id', str),
+ EntryArg('keydir', str),
+ EntryArg('bmpblk', str)])
+
+ # Read in the GBB flags from the config
+ self.gbb_flags = 0
+ flags_node = node.FindNode('flags')
+ if flags_node:
+ for flag, value in gbb_flag_properties.iteritems():
+ if fdt_util.GetBool(flags_node, flag):
+ self.gbb_flags |= value
+
+ 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
diff --git a/tools/binman/ftest.py b/tools/binman/ftest.py
index 4e467145d7..f15b215c60 100644
--- a/tools/binman/ftest.py
+++ b/tools/binman/ftest.py
@@ -47,6 +47,8 @@ TEXT_DATA = 'text'
TEXT_DATA2 = 'text2'
TEXT_DATA3 = 'text3'
CROS_EC_RW_DATA = 'ecrw'
+GBB_DATA = 'gbbd'
+BMPBLK_DATA = 'bmp'
class TestFunctional(unittest.TestCase):
@@ -95,6 +97,8 @@ class TestFunctional(unittest.TestCase):
TestFunctional._MakeInputFile('vbt.bin', VBT_DATA)
TestFunctional._MakeInputFile('mrc.bin', MRC_DATA)
TestFunctional._MakeInputFile('ecrw.bin', CROS_EC_RW_DATA)
+ TestFunctional._MakeInputDir('devkeys')
+ TestFunctional._MakeInputFile('bmpblk.bin', BMPBLK_DATA)
self._output_setup = False
# ELF file with a '_dt_ucode_base_size' symbol
@@ -287,6 +291,21 @@ class TestFunctional(unittest.TestCase):
fd.write(contents)
return pathname
+ @classmethod
+ def _MakeInputDir(self, dirname):
+ """Create a new test input directory, creating directories as needed
+
+ Args:
+ dirname: Directory name to create
+
+ Returns:
+ Full pathname of directory created
+ """
+ pathname = os.path.join(self._indir, dirname)
+ if not os.path.exists(pathname):
+ os.makedirs(pathname)
+ return pathname
+
@classmethod
def TestFile(self, fname):
return os.path.join(self._binman_dir, 'test', fname)
@@ -1248,6 +1267,43 @@ class TestFunctional(unittest.TestCase):
self.assertIn("'fill' entry must have a size property",
str(e.exception))
+ def _HandleGbbCommand(self, pipe_list):
+ """Fake calls to the futility utility"""
+ if pipe_list[0][0] == 'futility':
+ fname = pipe_list[0][-1]
+ # Append our GBB data to the file, which will happen every time the
+ # futility command is called.
+ with open(fname, 'a') as fd:
+ fd.write(GBB_DATA)
+ return command.CommandResult()
+
+ def testGbb(self):
+ """Test for the Chromium OS Google Binary Block"""
+ command.test_result = self._HandleGbbCommand
+ entry_args = {
+ 'keydir': 'devkeys',
+ 'bmpblk': 'bmpblk.bin',
+ }
+ data, _, _, _ = self._DoReadFileDtb('71_gbb.dts', entry_args=entry_args)
+
+ # Since futility
+ expected = GBB_DATA + GBB_DATA + 8 * chr(0) + (0x2180 - 16) * chr(0)
+ self.assertEqual(expected, data)
+
+ def testGbbTooSmall(self):
+ """Test for the Chromium OS Google Binary Block being large enough"""
+ with self.assertRaises(ValueError) as e:
+ self._DoReadFileDtb('72_gbb_too_small.dts')
+ self.assertIn("Node '/binman/gbb': GBB is too small",
+ str(e.exception))
+
+ def testGbbNoSize(self):
+ """Test for the Chromium OS Google Binary Block having a size"""
+ with self.assertRaises(ValueError) as e:
+ self._DoReadFileDtb('73_gbb_no_size.dts')
+ self.assertIn("Node '/binman/gbb': GBB must have a fixed size",
+ str(e.exception))
+
if __name__ == "__main__":
unittest.main()
diff --git a/tools/binman/test/71_gbb.dts b/tools/binman/test/71_gbb.dts
new file mode 100644
index 0000000000..551756372a
--- /dev/null
+++ b/tools/binman/test/71_gbb.dts
@@ -0,0 +1,31 @@
+// SPDX-License-Identifier: GPL-2.0+
+/dts-v1/;
+
+/ {
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ binman {
+ gbb {
+ size = <0x2180>;
+ flags {
+ dev-screen-short-delay;
+ load-option-roms;
+ enable-alternate-os;
+ force-dev-switch-on;
+ force-dev-boot-usb;
+ disable-fw-rollback-check;
+ enter-triggers-tonorm;
+ force-dev-boot-legacy;
+ faft-key-override;
+ disable-ec-software-sync;
+ default-dev-boot-legacy;
+ disable-pd-software-sync;
+ disable-lid-shutdown;
+ force-dev-boot-fastboot-full-cap;
+ enable-serial;
+ disable-dwmp;
+ };
+ };
+ };
+};
diff --git a/tools/binman/test/72_gbb_too_small.dts b/tools/binman/test/72_gbb_too_small.dts
new file mode 100644
index 0000000000..c088f36a1d
--- /dev/null
+++ b/tools/binman/test/72_gbb_too_small.dts
@@ -0,0 +1,10 @@
+// SPDX-License-Identifier: GPL-2.0+
+/dts-v1/;
+
+/ {
+ binman {
+ gbb {
+ size = <0x200>;
+ };
+ };
+};
diff --git a/tools/binman/test/73_gbb_no_size.dts b/tools/binman/test/73_gbb_no_size.dts
new file mode 100644
index 0000000000..83be403785
--- /dev/null
+++ b/tools/binman/test/73_gbb_no_size.dts
@@ -0,0 +1,9 @@
+// SPDX-License-Identifier: GPL-2.0+
+/dts-v1/;
+
+/ {
+ binman {
+ gbb {
+ };
+ };
+};
--
2.18.0.203.gfac676dfb9-goog
More information about the U-Boot
mailing list