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.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"; > > 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@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'. > > + }; > > +}; > > +''' > > + > > +@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 > > > +@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() > > >