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.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'. > > reset@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@0 { > compatible = "sandbox,reset"; > reg = <0>; > }; > };
Yes, that's a much better approach. It works fine, thanks! > Best regards > > Heinrich > > > > > > > + }; > > > > +}; > > > > +''' > > > > + > > > > +@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() > > > > > > > > > >