[PATCH v7 08/11] binman: capsule: Add support for generating EFI capsules

Sughosh Ganu sughosh.ganu at linaro.org
Sat Aug 5 13:34:55 CEST 2023


Add support in binman for generating EFI capsules. The capsule
parameters can be specified through the capsule binman entry. Also add
test cases in binman for testing capsule generation.

Signed-off-by: Sughosh Ganu <sughosh.ganu at linaro.org>
---
Changes since V6:
* Add macros for the GUID strings in sandbox_efi_capsule.h
* Highlight that the private and public keys are mandatory for capsule
  signing.
* Add a URL link to the UEFI spec, as used in the rst files.
* Use local vars for private and public keys in BuildSectionData()
* Use local vars for input payload and capsule filenames in
  BuildSectionData().
* Drop the ProcessContents() and SetImagePos() as the superclass
  functions suffice.
* Use GUID macro names in the capsule test dts files.
* Rename efi_capsule_payload.bin to capsule_input.bin.


 include/sandbox_efi_capsule.h                 |  14 ++
 tools/binman/entries.rst                      |  62 ++++++++
 tools/binman/etype/efi_capsule.py             | 143 ++++++++++++++++++
 tools/binman/ftest.py                         | 121 +++++++++++++++
 tools/binman/test/307_capsule.dts             |  23 +++
 tools/binman/test/308_capsule_signed.dts      |  25 +++
 tools/binman/test/309_capsule_version.dts     |  24 +++
 tools/binman/test/310_capsule_signed_ver.dts  |  26 ++++
 tools/binman/test/311_capsule_oemflags.dts    |  24 +++
 tools/binman/test/312_capsule_missing_key.dts |  24 +++
 .../binman/test/313_capsule_missing_index.dts |  22 +++
 .../binman/test/314_capsule_missing_guid.dts  |  19 +++
 .../test/315_capsule_missing_payload.dts      |  19 +++
 13 files changed, 546 insertions(+)
 create mode 100644 include/sandbox_efi_capsule.h
 create mode 100644 tools/binman/etype/efi_capsule.py
 create mode 100644 tools/binman/test/307_capsule.dts
 create mode 100644 tools/binman/test/308_capsule_signed.dts
 create mode 100644 tools/binman/test/309_capsule_version.dts
 create mode 100644 tools/binman/test/310_capsule_signed_ver.dts
 create mode 100644 tools/binman/test/311_capsule_oemflags.dts
 create mode 100644 tools/binman/test/312_capsule_missing_key.dts
 create mode 100644 tools/binman/test/313_capsule_missing_index.dts
 create mode 100644 tools/binman/test/314_capsule_missing_guid.dts
 create mode 100644 tools/binman/test/315_capsule_missing_payload.dts

diff --git a/include/sandbox_efi_capsule.h b/include/sandbox_efi_capsule.h
new file mode 100644
index 0000000000..da71b87a18
--- /dev/null
+++ b/include/sandbox_efi_capsule.h
@@ -0,0 +1,14 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (c) 2023, Linaro Limited
+ */
+
+#if !defined(_SANDBOX_EFI_CAPSULE_H_)
+#define _SANDBOX_EFI_CAPSULE_H_
+
+#define SANDBOX_UBOOT_IMAGE_GUID	"09d7cf52-0720-4710-91d1-08469b7fe9c8"
+#define SANDBOX_UBOOT_ENV_IMAGE_GUID	"5a7021f5-fef2-48b4-aaba-832e777418c0"
+#define SANDBOX_FIT_IMAGE_GUID		"3673b45d-6a7c-46f3-9e60-adabb03f7937"
+#define SANDBOX_INCORRECT_GUID		"058b7d83-50d5-4c47-a195-60d86ad341c4"
+
+#endif /* _SANDBOX_EFI_CAPSULE_H_ */
diff --git a/tools/binman/entries.rst b/tools/binman/entries.rst
index f2376932be..fc094b9c08 100644
--- a/tools/binman/entries.rst
+++ b/tools/binman/entries.rst
@@ -468,6 +468,68 @@ updating the EC on startup via software sync.
 
 
 
+.. _etype_efi_capsule:
+
+Entry: capsule: Entry for generating EFI Capsule files
+------------------------------------------------------
+
+The parameters needed for generation of the capsules can
+be provided as properties in the entry.
+
+Properties / Entry arguments:
+    - image-index: Unique number for identifying corresponding
+      payload image. Number between 1 and descriptor count, i.e.
+      the total number of firmware images that can be updated.
+    - image-type-id: Image GUID which will be used for identifying the
+      updatable image on the board.
+    - hardware-instance: Optional number for identifying unique
+      hardware instance of a device in the system. Default value of 0
+      for images where value is not to be used.
+    - fw-version: Optional value of image version that can be put on
+      the capsule through the Firmware Management Protocol(FMP) header.
+    - monotonic-count: Count used when signing an image.
+    - private-key: Path to PEM formatted .key private key file. This property
+      is mandatory for generating signed capsules.
+    - public-key-cert: Path to PEM formatted .crt public key certificate
+      file. This property is mandatory for generating signed capsules.
+    - oem-flags - Optional OEM flags to be passed through capsule header.
+
+    Since this is a subclass of Entry_section, all properties of the parent
+    class also apply here.
+
+For more details on the description of the capsule format, and the capsule
+update functionality, refer Section 8.5 and Chapter 23 in the `UEFI
+specification`_.
+
+The capsule parameters like image index and image GUID are passed as
+properties in the entry. The payload to be used in the capsule is to be
+provided as a subnode of the capsule entry.
+
+A typical capsule entry node would then look something like this::
+
+    capsule {
+            type = "efi-capsule";
+            image-index = <0x1>;
+            /* Image GUID for testing capsule update */
+            image-type-id = SANDBOX_UBOOT_IMAGE_GUID;
+            hardware-instance = <0x0>;
+            private-key = "path/to/the/private/key";
+            public-key-cert = "path/to/the/public-key-cert";
+            oem-flags = <0x8000>;
+
+            u-boot {
+            };
+    };
+
+In the above example, the capsule payload is the U-Boot image. The
+capsule entry would read the contents of the payload and put them
+into the capsule. Any external file can also be specified as the
+payload using the blob-ext subnode.
+
+.. _`UEFI specification`: https://uefi.org/sites/default/files/resources/UEFI_Spec_2_10_Aug29.pdf
+
+
+
 .. _etype_encrypted:
 
 Entry: encrypted: Externally built encrypted binary blob
diff --git a/tools/binman/etype/efi_capsule.py b/tools/binman/etype/efi_capsule.py
new file mode 100644
index 0000000000..bfdca94e26
--- /dev/null
+++ b/tools/binman/etype/efi_capsule.py
@@ -0,0 +1,143 @@
+# SPDX-License-Identifier: GPL-2.0+
+# Copyright (c) 2023 Linaro Limited
+#
+# Entry-type module for producing a EFI capsule
+#
+
+import os
+
+from binman.entry import Entry
+from binman.etype.section import Entry_section
+from dtoc import fdt_util
+from u_boot_pylib import tools
+
+class Entry_efi_capsule(Entry_section):
+    """Generate EFI capsules
+
+    The parameters needed for generation of the capsules can
+    be provided as properties in the entry.
+
+    Properties / Entry arguments:
+    - image-index: Unique number for identifying corresponding
+      payload image. Number between 1 and descriptor count, i.e.
+      the total number of firmware images that can be updated.
+    - image-type-id: Image GUID which will be used for identifying the
+      updatable image on the board.
+    - hardware-instance: Optional number for identifying unique
+      hardware instance of a device in the system. Default value of 0
+      for images where value is not to be used.
+    - fw-version: Optional value of image version that can be put on
+      the capsule through the Firmware Management Protocol(FMP) header.
+    - monotonic-count: Count used when signing an image.
+    - private-key: Path to PEM formatted .key private key file. This property
+      is mandatory for generating signed capsules.
+    - public-key-cert: Path to PEM formatted .crt public key certificate
+      file. This property is mandatory for generating signed capsules.
+    - oem-flags - Optional OEM flags to be passed through capsule header.
+
+    Since this is a subclass of Entry_section, all properties of the parent
+    class also apply here.
+
+    For more details on the description of the capsule format, and the capsule
+    update functionality, refer Section 8.5 and Chapter 23 in the `UEFI
+    specification`_.
+
+    The capsule parameters like image index and image GUID are passed as
+    properties in the entry. The payload to be used in the capsule is to be
+    provided as a subnode of the capsule entry.
+
+    A typical capsule entry node would then look something like this
+
+    capsule {
+            type = "efi-capsule";
+            image-index = <0x1>;
+            /* Image GUID for testing capsule update */
+            image-type-id = SANDBOX_UBOOT_IMAGE_GUID;
+            hardware-instance = <0x0>;
+            private-key = "path/to/the/private/key";
+            public-key-cert = "path/to/the/public-key-cert";
+            oem-flags = <0x8000>;
+
+            u-boot {
+            };
+    };
+
+    In the above example, the capsule payload is the U-Boot image. The
+    capsule entry would read the contents of the payload and put them
+    into the capsule. Any external file can also be specified as the
+    payload using the blob-ext subnode.
+
+    .. _`UEFI specification`: https://uefi.org/sites/default/files/resources/UEFI_Spec_2_10_Aug29.pdf
+    """
+    def __init__(self, section, etype, node):
+        super().__init__(section, etype, node)
+        self.required_props = ['image-index', 'image-type-id']
+        self.image_index = 0
+        self.image_guid = ''
+        self.hardware_instance = 0
+        self.monotonic_count = 0
+        self.fw_version = 0
+        self.oem_flags = 0
+        self.private_key = ''
+        self.public_key_cert = ''
+        self.auth = 0
+
+    def ReadNode(self):
+        self.ReadEntries()
+        super().ReadNode()
+
+        self.image_index = fdt_util.GetInt(self._node, 'image-index')
+        self.image_guid = fdt_util.GetString(self._node, 'image-type-id')
+        self.fw_version = fdt_util.GetInt(self._node, 'fw-version')
+        self.hardware_instance = fdt_util.GetInt(self._node, 'hardware-instance')
+        self.monotonic_count = fdt_util.GetInt(self._node, 'monotonic-count')
+        self.oem_flags = fdt_util.GetInt(self._node, 'oem-flags')
+
+        self.private_key = fdt_util.GetString(self._node, 'private-key')
+        self.public_key_cert = fdt_util.GetString(self._node, 'public-key-cert')
+        if ((self.private_key and not self.public_key_cert) or (self.public_key_cert and not self.private_key)):
+            self.Raise('Both private key and public key certificate need to be provided')
+        elif not (self.private_key and self.public_key_cert):
+            self.auth = 0
+        else:
+            self.auth = 1
+
+    def ReadEntries(self):
+        """Read the subnode to get the payload for this capsule"""
+        # We can have a single payload per capsule
+        if len(self._node.subnodes) == 0:
+            self.Raise('The capsule entry expects at least one subnode for payload')
+
+        for node in self._node.subnodes:
+            entry = Entry.Create(self, node)
+            entry.ReadNode()
+            self._entries[entry.name] = entry
+
+    def BuildSectionData(self, required):
+        private_key = ''
+        public_key_cert = ''
+        if self.auth:
+            if not os.path.isabs(self.private_key):
+                private_key =  tools.get_input_filename(self.private_key)
+            if not os.path.isabs(self.public_key_cert):
+                public_key_cert = tools.get_input_filename(self.public_key_cert)
+        data, payload, _ = self.collect_contents_to_file(
+            self._entries.values(), 'capsule_payload')
+        outfile = self._filename if self._filename else self._node.name
+        capsule_fname = tools.get_output_filename(outfile)
+        ret = self.mkeficapsule.generate_capsule(self.image_index,
+                                                  self.image_guid,
+                                                  self.hardware_instance,
+                                                  payload,
+                                                  capsule_fname,
+                                                  private_key,
+                                                  public_key_cert,
+                                                  self.monotonic_count,
+                                                  self.fw_version,
+                                                  self.oem_flags)
+        if ret is not None:
+            os.remove(payload)
+            return tools.read_file(capsule_fname)
+
+    def AddBintools(self, btools):
+        self.mkeficapsule = self.AddBintool(btools, 'mkeficapsule')
diff --git a/tools/binman/ftest.py b/tools/binman/ftest.py
index 36428ec343..9bda0157f7 100644
--- a/tools/binman/ftest.py
+++ b/tools/binman/ftest.py
@@ -48,6 +48,7 @@ U_BOOT_VPL_DATA       = b'vpl76543210fedcbazywxyz_'
 BLOB_DATA             = b'89'
 ME_DATA               = b'0abcd'
 VGA_DATA              = b'vga'
+EFI_CAPSULE_DATA      = b'efi'
 U_BOOT_DTB_DATA       = b'udtb'
 U_BOOT_SPL_DTB_DATA   = b'spldtb'
 U_BOOT_TPL_DTB_DATA   = b'tpldtb'
@@ -119,6 +120,11 @@ COMP_BINTOOLS = ['bzip2', 'gzip', 'lz4', 'lzma_alone', 'lzop', 'xz', 'zstd']
 
 TEE_ADDR = 0x5678
 
+# Firmware Management Protocol(FMP) GUID
+FW_MGMT_GUID = 'edd5cb6d2de8444cbda17194199ad92a'
+# Image GUID specified in the DTS
+CAPSULE_IMAGE_GUID = '52cfd7092007104791d108469b7fe9c8'
+
 class TestFunctional(unittest.TestCase):
     """Functional tests for binman
 
@@ -215,6 +221,7 @@ class TestFunctional(unittest.TestCase):
         TestFunctional._MakeInputFile('scp.bin', SCP_DATA)
         TestFunctional._MakeInputFile('rockchip-tpl.bin', ROCKCHIP_TPL_DATA)
         TestFunctional._MakeInputFile('ti_unsecure.bin', TI_UNSECURE_DATA)
+        TestFunctional._MakeInputFile('capsule_input.bin', EFI_CAPSULE_DATA)
 
         # Add a few .dtb files for testing
         TestFunctional._MakeInputFile('%s/test-fdt1.dtb' % TEST_FDT_SUBDIR,
@@ -7139,5 +7146,119 @@ fdt         fdtmap                Extract the devicetree blob from the fdtmap
          self.assertEqual(fdt_util.GetString(key_node, "key-name-hint"),
                           "key")
 
+    def _CheckCapsule(self, data, signed_capsule=False, version_check=False,
+                      capoemflags=False):
+        fmp_signature = "4d535331" # 'M', 'S', 'S', '1'
+        fmp_size = "10"
+        fmp_fw_version = "02"
+        oemflag = "0080"
+
+        payload_data = EFI_CAPSULE_DATA
+
+        # Firmware Management Protocol(FMP) GUID - offset(0 - 32)
+        self.assertEqual(FW_MGMT_GUID, data.hex()[:32])
+        # Image GUID - offset(96 - 128)
+        self.assertEqual(CAPSULE_IMAGE_GUID, data.hex()[96:128])
+
+        if capoemflags:
+            # OEM Flags - offset(40 - 44)
+            self.assertEqual(oemflag, data.hex()[40:44])
+        if signed_capsule and version_check:
+            # FMP header signature - offset(4770 - 4778)
+            self.assertEqual(fmp_signature, data.hex()[4770:4778])
+            # FMP header size - offset(4778 - 4780)
+            self.assertEqual(fmp_size, data.hex()[4778:4780])
+            # firmware version - offset(4786 - 4788)
+            self.assertEqual(fmp_fw_version, data.hex()[4786:4788])
+            # payload offset signed capsule(4802 - 4808)
+            self.assertEqual(payload_data.hex(), data.hex()[4802:4808])
+        elif signed_capsule:
+            # payload offset signed capsule(4770 - 4776)
+            self.assertEqual(payload_data.hex(), data.hex()[4770:4776])
+        elif version_check:
+            # FMP header signature - offset(184 - 192)
+            self.assertEqual(fmp_signature, data.hex()[184:192])
+            # FMP header size - offset(192 - 194)
+            self.assertEqual(fmp_size, data.hex()[192:194])
+            # firmware version - offset(200 - 202)
+            self.assertEqual(fmp_fw_version, data.hex()[200:202])
+            # payload offset for non-signed capsule with version header(216 - 222)
+            self.assertEqual(payload_data.hex(), data.hex()[216:222])
+        else:
+            # payload offset for non-signed capsule with no version header(184 - 190)
+            self.assertEqual(payload_data.hex(), data.hex()[184:190])
+
+    def testCapsuleGen(self):
+        """Test generation of EFI capsule"""
+        data = self._DoReadFile('307_capsule.dts')
+
+        self._CheckCapsule(data)
+
+    def testSignedCapsuleGen(self):
+        """Test generation of EFI capsule"""
+        data = tools.read_file(self.TestFile("key.key"))
+        self._MakeInputFile("key.key", data)
+        data = tools.read_file(self.TestFile("key.pem"))
+        self._MakeInputFile("key.crt", data)
+
+        data = self._DoReadFile('308_capsule_signed.dts')
+
+        self._CheckCapsule(data, signed_capsule=True)
+
+    def testCapsuleGenVersionSupport(self):
+        """Test generation of EFI capsule with version support"""
+        data = self._DoReadFile('309_capsule_version.dts')
+
+        self._CheckCapsule(data, version_check=True)
+
+    def testCapsuleGenSignedVer(self):
+        """Test generation of signed EFI capsule with version information"""
+        data = tools.read_file(self.TestFile("key.key"))
+        self._MakeInputFile("key.key", data)
+        data = tools.read_file(self.TestFile("key.pem"))
+        self._MakeInputFile("key.crt", data)
+
+        data = self._DoReadFile('310_capsule_signed_ver.dts')
+
+        self._CheckCapsule(data, signed_capsule=True, version_check=True)
+
+    def testCapsuleGenCapOemFlags(self):
+        """Test generation of EFI capsule with OEM Flags set"""
+        data = self._DoReadFile('311_capsule_oemflags.dts')
+
+        self._CheckCapsule(data, capoemflags=True)
+
+    def testCapsuleGenKeyMissing(self):
+        """Test that binman errors out on missing key"""
+        with self.assertRaises(ValueError) as e:
+            self._DoReadFile('312_capsule_missing_key.dts')
+
+        self.assertIn("Both private key and public key certificate need to be provided",
+                      str(e.exception))
+
+    def testCapsuleGenIndexMissing(self):
+        """Test that binman errors out on missing image index"""
+        with self.assertRaises(ValueError) as e:
+            self._DoReadFile('313_capsule_missing_index.dts')
+
+        self.assertIn("entry is missing properties: image-index",
+                      str(e.exception))
+
+    def testCapsuleGenGuidMissing(self):
+        """Test that binman errors out on missing image GUID"""
+        with self.assertRaises(ValueError) as e:
+            self._DoReadFile('314_capsule_missing_guid.dts')
+
+        self.assertIn("entry is missing properties: image-type-id",
+                      str(e.exception))
+
+    def testCapsuleGenPayloadMissing(self):
+        """Test that binman errors out on missing input(payload)image"""
+        with self.assertRaises(ValueError) as e:
+            self._DoReadFile('315_capsule_missing_payload.dts')
+
+        self.assertIn("The capsule entry expects at least one subnode for payload",
+                      str(e.exception))
+
 if __name__ == "__main__":
     unittest.main()
diff --git a/tools/binman/test/307_capsule.dts b/tools/binman/test/307_capsule.dts
new file mode 100644
index 0000000000..86552ff83f
--- /dev/null
+++ b/tools/binman/test/307_capsule.dts
@@ -0,0 +1,23 @@
+// SPDX-License-Identifier: GPL-2.0+
+
+/dts-v1/;
+
+#include <sandbox_efi_capsule.h>
+
+/ {
+	#address-cells = <1>;
+	#size-cells = <1>;
+
+	binman {
+		efi-capsule {
+			image-index = <0x1>;
+			/* Image GUID for testing capsule update */
+			image-type-id = SANDBOX_UBOOT_IMAGE_GUID;
+			hardware-instance = <0x0>;
+
+			blob {
+				filename = "capsule_input.bin";
+			};
+		};
+	};
+};
diff --git a/tools/binman/test/308_capsule_signed.dts b/tools/binman/test/308_capsule_signed.dts
new file mode 100644
index 0000000000..37d2f35e71
--- /dev/null
+++ b/tools/binman/test/308_capsule_signed.dts
@@ -0,0 +1,25 @@
+// SPDX-License-Identifier: GPL-2.0+
+
+/dts-v1/;
+
+#include <sandbox_efi_capsule.h>
+
+/ {
+	#address-cells = <1>;
+	#size-cells = <1>;
+
+	binman {
+		efi-capsule {
+			image-index = <0x1>;
+			/* Image GUID for testing capsule update */
+			image-type-id = SANDBOX_UBOOT_IMAGE_GUID;
+			hardware-instance = <0x0>;
+			private-key = "key.key";
+			public-key-cert = "key.crt";
+
+			blob {
+				filename = "capsule_input.bin";
+			};
+		};
+	};
+};
diff --git a/tools/binman/test/309_capsule_version.dts b/tools/binman/test/309_capsule_version.dts
new file mode 100644
index 0000000000..a3d2f96f5c
--- /dev/null
+++ b/tools/binman/test/309_capsule_version.dts
@@ -0,0 +1,24 @@
+// SPDX-License-Identifier: GPL-2.0+
+
+/dts-v1/;
+
+#include <sandbox_efi_capsule.h>
+
+/ {
+	#address-cells = <1>;
+	#size-cells = <1>;
+
+	binman {
+		efi-capsule {
+			image-index = <0x1>;
+			fw-version = <0x2>;
+			/* Image GUID for testing capsule update */
+			image-type-id = SANDBOX_UBOOT_IMAGE_GUID;
+			hardware-instance = <0x0>;
+
+			blob {
+				filename = "capsule_input.bin";
+			};
+		};
+	};
+};
diff --git a/tools/binman/test/310_capsule_signed_ver.dts b/tools/binman/test/310_capsule_signed_ver.dts
new file mode 100644
index 0000000000..01c9c01222
--- /dev/null
+++ b/tools/binman/test/310_capsule_signed_ver.dts
@@ -0,0 +1,26 @@
+// SPDX-License-Identifier: GPL-2.0+
+
+/dts-v1/;
+
+#include <sandbox_efi_capsule.h>
+
+/ {
+	#address-cells = <1>;
+	#size-cells = <1>;
+
+	binman {
+		efi-capsule {
+			image-index = <0x1>;
+			fw-version = <0x2>;
+			/* Image GUID for testing capsule update */
+			image-type-id = SANDBOX_UBOOT_IMAGE_GUID;
+			hardware-instance = <0x0>;
+			private-key = "key.key";
+			public-key-cert = "key.crt";
+
+			blob {
+				filename = "capsule_input.bin";
+			};
+		};
+	};
+};
diff --git a/tools/binman/test/311_capsule_oemflags.dts b/tools/binman/test/311_capsule_oemflags.dts
new file mode 100644
index 0000000000..cfc41c7b55
--- /dev/null
+++ b/tools/binman/test/311_capsule_oemflags.dts
@@ -0,0 +1,24 @@
+// SPDX-License-Identifier: GPL-2.0+
+
+/dts-v1/;
+
+#include <sandbox_efi_capsule.h>
+
+/ {
+	#address-cells = <1>;
+	#size-cells = <1>;
+
+	binman {
+		efi-capsule {
+			image-index = <0x1>;
+			/* Image GUID for testing capsule update */
+			image-type-id = SANDBOX_UBOOT_IMAGE_GUID;
+			hardware-instance = <0x0>;
+			oem-flags = <0x8000>;
+
+			blob {
+				filename = "capsule_input.bin";
+			};
+		};
+	};
+};
diff --git a/tools/binman/test/312_capsule_missing_key.dts b/tools/binman/test/312_capsule_missing_key.dts
new file mode 100644
index 0000000000..1a08d0e991
--- /dev/null
+++ b/tools/binman/test/312_capsule_missing_key.dts
@@ -0,0 +1,24 @@
+// SPDX-License-Identifier: GPL-2.0+
+
+/dts-v1/;
+
+#include <sandbox_efi_capsule.h>
+
+/ {
+	#address-cells = <1>;
+	#size-cells = <1>;
+
+	binman {
+		efi-capsule {
+			image-index = <0x1>;
+			/* Image GUID for testing capsule update */
+			image-type-id = SANDBOX_UBOOT_IMAGE_GUID;
+			hardware-instance = <0x0>;
+			private-key = "tools/binman/test/key.key";
+
+			blob {
+				filename = "capsule_input.bin";
+			};
+		};
+	};
+};
diff --git a/tools/binman/test/313_capsule_missing_index.dts b/tools/binman/test/313_capsule_missing_index.dts
new file mode 100644
index 0000000000..c6aa899211
--- /dev/null
+++ b/tools/binman/test/313_capsule_missing_index.dts
@@ -0,0 +1,22 @@
+// SPDX-License-Identifier: GPL-2.0+
+
+/dts-v1/;
+
+#include <sandbox_efi_capsule.h>
+
+/ {
+	#address-cells = <1>;
+	#size-cells = <1>;
+
+	binman {
+		efi-capsule {
+			/* Image GUID for testing capsule update */
+			image-type-id = SANDBOX_UBOOT_IMAGE_GUID;
+			hardware-instance = <0x0>;
+
+			blob {
+				filename = "capsule_input.bin";
+			};
+		};
+	};
+};
diff --git a/tools/binman/test/314_capsule_missing_guid.dts b/tools/binman/test/314_capsule_missing_guid.dts
new file mode 100644
index 0000000000..d76afba853
--- /dev/null
+++ b/tools/binman/test/314_capsule_missing_guid.dts
@@ -0,0 +1,19 @@
+// SPDX-License-Identifier: GPL-2.0+
+
+/dts-v1/;
+
+/ {
+	#address-cells = <1>;
+	#size-cells = <1>;
+
+	binman {
+		efi-capsule {
+			image-index = <0x1>;
+			hardware-instance = <0x0>;
+
+			blob {
+				filename = "capsule_input.bin";
+			};
+		};
+	};
+};
diff --git a/tools/binman/test/315_capsule_missing_payload.dts b/tools/binman/test/315_capsule_missing_payload.dts
new file mode 100644
index 0000000000..7d7b9e2ea0
--- /dev/null
+++ b/tools/binman/test/315_capsule_missing_payload.dts
@@ -0,0 +1,19 @@
+// SPDX-License-Identifier: GPL-2.0+
+
+/dts-v1/;
+
+#include <sandbox_efi_capsule.h>
+
+/ {
+	#address-cells = <1>;
+	#size-cells = <1>;
+
+	binman {
+		efi-capsule {
+			image-index = <0x1>;
+			/* Image GUID for testing capsule update */
+			image-type-id = SANDBOX_UBOOT_IMAGE_GUID;
+			hardware-instance = <0x0>;
+		};
+	};
+};
-- 
2.34.1



More information about the U-Boot mailing list