public inbox for u-boot@lists.denx.de
 help / color / mirror / Atom feed
From: Cristian Ciocaltea <cristian.ciocaltea@gmail.com>
To: u-boot@lists.denx.de
Subject: [PATCH v3 5/5] test/py: Create a test for launching UEFI binaries from FIT images
Date: Wed, 18 Dec 2019 17:07:45 +0200	[thread overview]
Message-ID: <20191218150745.GA16098@BV030612LT> (raw)
In-Reply-To: <d73cdba6-c6ce-6b49-2147-4902e92eef09@gmx.de>

On Wed, Dec 18, 2019 at 11:06:48AM +0100, Heinrich Schuchardt wrote:
> On 12/18/19 9:22 AM, Cristian Ciocaltea wrote:
> > On Tue, Dec 17, 2019 at 10:08:31PM +0100, Heinrich Schuchardt wrote:
> > > On 12/17/19 8:47 AM, Cristian Ciocaltea wrote:
> > > > 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.ciocaltea@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.ciocaltea@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 at 0 {
> > > > +        compatible = "sandbox,reset";
> > > 
> > > This produces a warning:
> > > 
> > > +dtc ./test-efi-fit-sandbox-internal.dts -O dtb -o
> > > ./test-efi-fit-sandbox-internal.dtb
> > > ./test-efi-fit-sandbox-internal.dts:8.13-10.7: Warning
> > > (unit_address_vs_reg): /reset at 0: node has a unit name, but no reg property
> > 
> > A similar sample is also used by test_fit.py and test_vboot.py, which
> > expose the same warning, that's why I initially ignored it.
> > If acceptable, I can suppress it via '-W no-unit_address_vs_reg'.
> 
> reset at 0 includes a unit-address. So a reg property is expected. How about:
> 
> /dts-v1/;
> 
> / {
> 	#address-cells = <1>;
> 	#size-cells = <0>;
> 
> 	model = "Sandbox %(fdt_type) EFI FIT Boot Test ";
> 	compatible = "sandbox";
> 
> 	reset at 0 {
> 		compatible = "sandbox,reset";
> 		reg = <0>;
> 	};
> };

Yes, that's a much better approach. It works fine, thanks!

> Best regards
> 
> Heinrich
> 
> > 
> > > > +    };
> > > > +};
> > > > +'''
> > > > +
> > > > + at pytest.mark.boardspec('sandbox')
> > > 
> > > This test looks ok in principal. But why should we restrict it to the
> > > sandbox?
> > 
> > Let me see how this should work on real hardware, I'm going to test
> > on qemu for the moment.
> > 
> > > Best regards
> > > 
> > > Heinrich
> > > 
> > > > + at pytest.mark.buildconfigspec('bootm_efi')
> > > > + at pytest.mark.buildconfigspec('cmd_bootefi_hello_compile')
> > > > + at 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()
> > > > 
> > > 
> > 
> 

  reply	other threads:[~2019-12-18 15:07 UTC|newest]

Thread overview: 15+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-12-17  7:46 [PATCH v3 0/5] Add support for booting EFI FIT images Cristian Ciocaltea
2019-12-17  7:46 ` [PATCH v3 1/5] image: Add IH_OS_EFI for EFI chain-load boot Cristian Ciocaltea
2019-12-17 20:30   ` Heinrich Schuchardt
2019-12-17  7:46 ` [PATCH v3 2/5] bootm: Add a bootm command for type IH_OS_EFI Cristian Ciocaltea
2019-12-17 20:34   ` Heinrich Schuchardt
2019-12-18  8:27     ` Cristian Ciocaltea
2019-12-17  7:47 ` [PATCH v3 3/5] doc: Add sample uefi.its image description file Cristian Ciocaltea
2019-12-17  7:47 ` [PATCH v3 4/5] doc: uefi.rst: Document launching UEFI binaries from FIT images Cristian Ciocaltea
2019-12-17  7:47 ` [PATCH v3 5/5] test/py: Create a test for " Cristian Ciocaltea
2019-12-17 21:08   ` Heinrich Schuchardt
2019-12-18  8:22     ` Cristian Ciocaltea
2019-12-18 10:06       ` Heinrich Schuchardt
2019-12-18 15:07         ` Cristian Ciocaltea [this message]
2019-12-18 10:56       ` Heinrich Schuchardt
2019-12-18 15:50         ` Cristian Ciocaltea

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20191218150745.GA16098@BV030612LT \
    --to=cristian.ciocaltea@gmail.com \
    --cc=u-boot@lists.denx.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox