This test verifies the implementation of the 'bootm' extension that
handles UEFI binaries inside FIT images (enabled via CONFIG_BOOTM_EFI).

Signed-off-by: Cristian Ciocaltea <cristian.ciocal...@gmail.com>
---
 test/py/tests/test_efi_fit.py | 233 ++++++++++++++++++++++++++++++++++
 1 file changed, 233 insertions(+)
 create mode 100644 test/py/tests/test_efi_fit.py

diff --git a/test/py/tests/test_efi_fit.py b/test/py/tests/test_efi_fit.py
new file mode 100644
index 0000000000..52b415b198
--- /dev/null
+++ b/test/py/tests/test_efi_fit.py
@@ -0,0 +1,233 @@
+# SPDX-License-Identifier: GPL-2.0
+# Copyright (c) 2019, Cristian Ciocaltea <cristian.ciocal...@gmail.com>
+
+# Test launching UEFI binaries from FIT images.
+
+import os
+import pytest
+import u_boot_utils as util
+
+# Define the parametrized ITS data to be used for FIT image generation.
+its_data = '''
+/dts-v1/;
+
+/ {
+    description = "EFI image with FDT blob";
+    #address-cells = <1>;
+
+    images {
+        efi {
+            description = "Sandbox EFI";
+            data = /incbin/("%(efi-bin)s");
+            type = "%(kernel-type)s";
+            arch = "sandbox";
+            os = "efi";
+            compression = "%(efi-comp)s";
+            load = <0x0>;
+            entry = <0x0>;
+        };
+        fdt {
+            description = "Sandbox FDT";
+            data = /incbin/("%(fdt-bin)s");
+            type = "flat_dt";
+            arch = "sandbox";
+            compression = "%(fdt-comp)s";
+        };
+    };
+
+    configurations {
+        default = "config-efi-fdt";
+        config-efi-fdt {
+            description = "EFI FIT w/ FDT";
+            kernel = "efi";
+            fdt = "fdt";
+        };
+        config-efi-nofdt {
+            description = "EFI FIT w/o FDT";
+            kernel = "efi";
+        };
+    };
+};
+'''
+
+# Define the parametrized FDT data.
+fdt_data = '''
+/dts-v1/;
+
+/ {
+    model = "Sandbox %(fdt_type) EFI FIT Boot Test ";
+    compatible = "sandbox";
+
+    reset@0 {
+        compatible = "sandbox,reset";
+    };
+};
+'''
+
+@pytest.mark.boardspec('sandbox')
+@pytest.mark.buildconfigspec('bootm_efi')
+@pytest.mark.buildconfigspec('cmd_bootefi_hello_compile')
+@pytest.mark.requiredtool('dtc')
+def test_efi_fit(u_boot_console):
+    """Test handling of UEFI binaries inside FIT images.
+
+    The tests are trying to launch U-Boot's helloworld.efi embedded into
+    FIT images, in uncompressed or gzip compressed format.
+
+    Additionally, a sample FDT blob is created and embedded into the above
+    mentioned FIT images, in uncompressed or gzip compressed format.
+
+    The following test cases are currently defined and enabled:
+    - Launch uncompressed FIT EFI & FIT FDT
+    - Launch compressed FIT EFI & FIT FDT
+    - Launch uncompressed FIT EFI & internal FDT
+    - Launch compressed FIT EFI & internal FDT
+    """
+
+    def make_fpath(fname):
+        """Compute the path of a given (temporary) file.
+
+        Args:
+            fname: The name of a file within U-Boot build dir.
+        Return:
+            The computed file path.
+        """
+        return os.path.join(u_boot_console.config.build_dir, fname)
+
+    def make_efi(fname, comp):
+        """Create an UEFI binary.
+
+        This simply copies lib/efi_loader/helloworld.efi into U-Boot
+        build dir and, optionally, compresses the file using gzip.
+
+        Args:
+            fname: The target file name within U-Boot build dir.
+            comp: Flag to enable gzip compression.
+        Return:
+            The path of the created file.
+        """
+        bin_path = make_fpath(fname)
+        os.system('cp %s %s' % (make_fpath('lib/efi_loader/helloworld.efi'), 
bin_path))
+        if comp:
+            util.run_and_log(u_boot_console, ['gzip', '-f', bin_path])
+            bin_path += '.gz'
+        return bin_path
+
+    def make_dtb(fdt_type, comp):
+        """Create a sample DTB file.
+
+        Creates a DTS file and compiles it to a DTB.
+
+        Args:
+            fdt_type: The type of the FDT, i.e. internal, user.
+            comp: Flag to enable gzip compression.
+        Returns:
+            The path of the created file.
+        """
+        dts = make_fpath('test-efi-fit-sandbox-%s.dts' % fdt_type)
+        dtb = make_fpath('test-efi-fit-sandbox-%s.dtb' % fdt_type)
+        with open(dts, 'w') as fd:
+            fd.write(fdt_data)
+        util.run_and_log(u_boot_console, ['dtc', dts, '-O', 'dtb', '-o', dtb])
+        if comp:
+            util.run_and_log(u_boot_console, ['gzip', '-f', dtb])
+            dtb += '.gz'
+        return dtb
+
+    def make_fit(efi_comp, fdt_comp):
+        """Create a sample FIT image.
+
+        Runs 'mkimage' to create a FIT image within U-Boot build dir.
+        Args:
+            efi_comp: Enable gzip compression for the EFI binary.
+            fdt_comp: Enable gzip compression for the FDT blob.
+        Return:
+            The path of the created file.
+        """
+        # Generate resources referenced by ITS.
+        its_params = {
+            'efi-bin' : os.path.basename(
+                            make_efi('test-efi-fit-sandbox.efi', efi_comp)),
+            'kernel-type' : 'kernel' if efi_comp else 'kernel_noload',
+            'efi-comp' : 'gzip' if efi_comp else 'none',
+            'fdt-bin' : os.path.basename(make_dtb('user', fdt_comp)),
+            'fdt-comp' : 'gzip' if fdt_comp else 'none',
+        }
+
+        # Generate a test ITS file.
+        its_path = make_fpath('test-efi-fit.its')
+        with open(its_path, 'w') as fd:
+            fd.write(its_data % its_params)
+
+        # Build the test ITS.
+        fit_path = make_fpath('test-efi-fit.fit')
+        util.run_and_log(u_boot_console,
+            [make_fpath('tools/mkimage'), '-f', its_path, fit_path])
+        return fit_path
+
+    def file_size(fpath):
+        """Get the size of a file.
+
+        Args:
+            fname: Path of the file to check.
+        Return:
+            The size of file in bytes.
+        """
+        return os.stat(fpath).st_size
+
+    def launch_efi(enable_fdt, enable_comp):
+        """Launch a UEFI binary from a FIT image.
+
+        Creates a test FIT image containing a fake UEFI binary and tries
+        to run it via the 'bootm' command in the U-Boot console.
+
+        Args:
+            enable_fdt: Flag to enable using the FDT blob inside FIT image.
+            enable_comp: Flag to enable gzip compression on EFI and FDT 
content.
+        """
+        # Create test FIT image.
+        fit_img_path = make_fit(enable_comp, enable_comp)
+
+        # Select boot configuration.
+        fit_config = 'config-efi-fdt' if enable_fdt else 'config-efi-nofdt'
+
+        # Run U-Boot commands.
+        with u_boot_console.log.section('Boot EFI FIT %s' % fit_config):
+            output = u_boot_console.run_command(
+                'host load hostfs - $kernel_addr_r %s' % fit_img_path)
+
+            expected_text = '%d bytes read' % file_size(fit_img_path)
+            assert(expected_text in output)
+
+            output = u_boot_console.run_command(
+                'bootm ${kernel_addr_r}#%s' % fit_config)
+
+            if enable_fdt:
+                expected_text = 'Booting using the fdt blob'
+                assert(expected_text in output)
+
+            expected_text = 'Hello, world'
+            assert expected_text in output
+            expected_text = '## Application terminated, r = 0'
+            assert expected_text in output
+
+    try:
+        # Use our own device tree file, will be restored afterwards.
+        control_dtb = make_dtb('internal', False)
+        old_dtb = u_boot_console.config.dtb
+        u_boot_console.config.dtb = control_dtb
+
+        # Run tests
+        # - fdt ON, gzip OFF
+        launch_efi(True, False)
+        # - fdt ON, gzip ON
+        launch_efi(True, True)
+        # - fdt OFF, gzip OFF
+        launch_efi(False, False)
+        # - fdt OFF, gzip ON
+        launch_efi(False, True)
+
+    finally:
+        # Go back to the original U-Boot with the correct dtb.
+        u_boot_console.config.dtb = old_dtb
+        u_boot_console.restart_uboot()
-- 
2.17.1

Reply via email to