From f7ee9f3d362a05cc3f7e04d0ceb373c2aea80de6 Mon Sep 17 00:00:00 2001 From: Heinrich Schuchardt Date: Mon, 31 Jul 2023 22:01:21 +0200 Subject: test: unit test for semihosting Provide a unit test for semihosting testing reading and writing a file. Signed-off-by: Heinrich Schuchardt Reviewed-by: Sean Anderson --- test/py/tests/test_semihosting/conftest.py | 23 +++++++++++++++++++ test/py/tests/test_semihosting/test_hostfs.py | 33 +++++++++++++++++++++++++++ 2 files changed, 56 insertions(+) create mode 100644 test/py/tests/test_semihosting/conftest.py create mode 100644 test/py/tests/test_semihosting/test_hostfs.py (limited to 'test/py') diff --git a/test/py/tests/test_semihosting/conftest.py b/test/py/tests/test_semihosting/conftest.py new file mode 100644 index 00000000000..b00d8f4ea9c --- /dev/null +++ b/test/py/tests/test_semihosting/conftest.py @@ -0,0 +1,23 @@ +# SPDX-License-Identifier: GPL-2.0-or-later + +"""Fixture for semihosting command test +""" + +import os +import pytest + +@pytest.fixture(scope='session') +def semihosting_data(u_boot_config): + """Set up a file system to be used in semihosting tests + + Args: + u_boot_config -- U-Boot configuration. + """ + image_path = u_boot_config.persistent_data_dir + '/semihosting.txt' + + with open(image_path, 'w', encoding = 'utf-8') as file: + file.write('Das U-Boot\n') + + yield image_path + + os.remove(image_path) diff --git a/test/py/tests/test_semihosting/test_hostfs.py b/test/py/tests/test_semihosting/test_hostfs.py new file mode 100644 index 00000000000..51f6fa7702c --- /dev/null +++ b/test/py/tests/test_semihosting/test_hostfs.py @@ -0,0 +1,33 @@ +# SPDX-License-Identifier: GPL-2.0+ + +""" Unit test for semihosting +""" + +import pytest + +@pytest.mark.buildconfigspec('semihosting') +def test_semihosting_hostfs(u_boot_console, semihosting_data): + """ Unit test for semihosting + + Args: + u_boot_console -- U-Boot console + semihosting_data -- Path to the disk image used for testing. + """ + response = u_boot_console.run_command( + f'load hostfs - $loadaddr {semihosting_data}') + assert '11 bytes read' in response + + response = u_boot_console.run_command( + 'crc32 $loadaddr $filesize') + assert '==> 60cfccfc' in response + + u_boot_console.run_command( + f'save hostfs - $loadaddr {semihosting_data} 11 11') + + response = u_boot_console.run_command( + f'load hostfs - $loadaddr {semihosting_data} 4 13') + assert '4 bytes read' in response + + response = u_boot_console.run_command( + 'crc32 $loadaddr $filesize') + assert '==> e29063ea' in response -- cgit v1.2.3 From d5737b3f6a0239caf2dd5578a4bc8ebfccfdee3b Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Mon, 14 Aug 2023 16:40:28 -0600 Subject: expo: Tidy up the expo.py tool and usage Tidy up this tool a little: - define which arguments are needed - split the enum values out into a header file - warn if no enum values are found - display the dtc error if something goes wrong - avoid a Python traceback on error Signed-off-by: Simon Glass --- test/py/tests/test_ut.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'test/py') diff --git a/test/py/tests/test_ut.py b/test/py/tests/test_ut.py index aa1d477cd56..6a59c306322 100644 --- a/test/py/tests/test_ut.py +++ b/test/py/tests/test_ut.py @@ -285,10 +285,12 @@ label Fedora-Workstation-armhfp-31-1.9 (5.3.7-301.fc31.armv7hl) def setup_cedit_file(cons): infname = os.path.join(cons.config.source_dir, 'test/boot/files/expo_layout.dts') + inhname = os.path.join(cons.config.source_dir, + 'test/boot/files/expo_ids.h') expo_tool = os.path.join(cons.config.source_dir, 'tools/expo.py') outfname = 'cedit.dtb' u_boot_utils.run_and_log( - cons, f'{expo_tool} -e {infname} -l {infname} -o {outfname}') + cons, f'{expo_tool} -e {inhname} -l {infname} -o {outfname}') @pytest.mark.buildconfigspec('ut_dm') -- cgit v1.2.3 From 00613bc19af01b3ef37aeb836630bae8d11e7991 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Thu, 24 Aug 2023 13:55:38 -0600 Subject: test: Move 1MB.fat32.img and 2MB.ext2.img These are currently created in the source directory, which is not ideal. Move them to the persistent-data directory instead. Update the test so skip validating the filename, since it now includes a full path. Signed-off-by: Simon Glass --- test/py/tests/fs_helper.py | 6 ++---- test/py/tests/test_ut.py | 6 ++---- 2 files changed, 4 insertions(+), 8 deletions(-) (limited to 'test/py') diff --git a/test/py/tests/fs_helper.py b/test/py/tests/fs_helper.py index 17151bcd08e..9882ddb1daa 100644 --- a/test/py/tests/fs_helper.py +++ b/test/py/tests/fs_helper.py @@ -9,7 +9,7 @@ import re import os from subprocess import call, check_call, check_output, CalledProcessError -def mk_fs(config, fs_type, size, prefix, use_src_dir=False): +def mk_fs(config, fs_type, size, prefix): """Create a file system volume Args: @@ -17,14 +17,12 @@ def mk_fs(config, fs_type, size, prefix, use_src_dir=False): fs_type (str): File system type, e.g. 'ext4' size (int): Size of file system in bytes prefix (str): Prefix string of volume's file name - use_src_dir (bool): true to put the file in the source directory Raises: CalledProcessError: if any error occurs when creating the filesystem """ fs_img = f'{prefix}.{fs_type}.img' - fs_img = os.path.join(config.source_dir if use_src_dir - else config.persistent_data_dir, fs_img) + fs_img = os.path.join(config.persistent_data_dir, fs_img) if fs_type == 'fat16': mkfs_opt = '-F 16' diff --git a/test/py/tests/test_ut.py b/test/py/tests/test_ut.py index 6a59c306322..640129018c1 100644 --- a/test/py/tests/test_ut.py +++ b/test/py/tests/test_ut.py @@ -319,10 +319,8 @@ def test_ut_dm_init(u_boot_console): u_boot_utils.run_and_log( u_boot_console, f'sfdisk {fn}', stdin=b'type=83') - fs_helper.mk_fs(u_boot_console.config, 'ext2', 0x200000, '2MB', - use_src_dir=True) - fs_helper.mk_fs(u_boot_console.config, 'fat32', 0x100000, '1MB', - use_src_dir=True) + fs_helper.mk_fs(u_boot_console.config, 'ext2', 0x200000, '2MB') + fs_helper.mk_fs(u_boot_console.config, 'fat32', 0x100000, '1MB') @pytest.mark.buildconfigspec('cmd_bootflow') def test_ut_dm_init_bootstd(u_boot_console): -- cgit v1.2.3 From d08db02d2d3d5ccf365e423b0c3dfb6fe311abd6 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Thu, 24 Aug 2023 13:55:41 -0600 Subject: bootstd: Add a test for bootmeth_cros The ChromiumOS bootmeth has no tests at present. Before adding more features. add a basic test. This creates a disk which can be scanned by the bootmeth, so make sure things work. It is quite rudimentary, since the kernel is faked, the root disk is missing and there is no cmdline stored. Enable the bootmeth for snow so it can build the unit test. Signed-off-by: Simon Glass --- test/py/tests/test_ut.py | 142 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 142 insertions(+) (limited to 'test/py') diff --git a/test/py/tests/test_ut.py b/test/py/tests/test_ut.py index 640129018c1..82932a662bf 100644 --- a/test/py/tests/test_ut.py +++ b/test/py/tests/test_ut.py @@ -1,6 +1,7 @@ # SPDX-License-Identifier: GPL-2.0 # Copyright (c) 2016, NVIDIA CORPORATION. All rights reserved. +import collections import getpass import gzip import os @@ -282,6 +283,146 @@ label Fedora-Workstation-armhfp-31-1.9 (5.3.7-301.fc31.armv7hl) copy_prepared_image(cons, mmc_dev, fname) +def setup_cros_image(cons): + """Create a 20MB disk image with ChromiumOS partitions""" + Partition = collections.namedtuple('part', 'start,size,name') + parts = {} + disk_data = None + + def pack_kernel(cons, arch, kern, dummy): + """Pack a kernel containing some fake data + + Args: + cons (ConsoleBase): Console to use + arch (str): Architecture to use ('x86' or 'arm') + kern (str): Filename containing kernel + dummy (str): Dummy filename to use for config and bootloader + + Return: + bytes: Packed-kernel data + """ + kern_part = os.path.join(cons.config.result_dir, 'kern-part-{arch}.bin') + u_boot_utils.run_and_log( + cons, + f'futility vbutil_kernel --pack {kern_part} ' + '--keyblock doc/chromium/files/devkeys/kernel.keyblock ' + '--signprivate doc/chromium/files/devkeys/kernel_data_key.vbprivk ' + f'--version 1 --config {dummy} --bootloader {dummy} ' + f'--vmlinuz {kern}') + + with open(kern_part, 'rb') as inf: + kern_part_data = inf.read() + return kern_part_data + + def set_part_data(partnum, data): + """Set the contents of a disk partition + + This updates disk_data by putting data in the right place + + Args: + partnum (int): Partition number to set + data (bytes): Data for that partition + """ + nonlocal disk_data + + start = parts[partnum].start * sect_size + disk_data = disk_data[:start] + data + disk_data[start + len(data):] + + mmc_dev = 5 + fname = os.path.join(cons.config.source_dir, f'mmc{mmc_dev}.img') + u_boot_utils.run_and_log(cons, 'qemu-img create %s 20M' % fname) + #mnt = os.path.join(cons.config.persistent_data_dir, 'mnt') + #mkdir_cond(mnt) + u_boot_utils.run_and_log(cons, f'cgpt create {fname}') + + uuid_state = 'ebd0a0a2-b9e5-4433-87c0-68b6b72699c7' + uuid_kern = 'fe3a2a5d-4f32-41a7-b725-accc3285a309' + uuid_root = '3cb8e202-3b7e-47dd-8a3c-7ff2a13cfcec' + uuid_rwfw = 'cab6e88e-abf3-4102-a07a-d4bb9be3c1d3' + uuid_reserved = '2e0a753d-9e48-43b0-8337-b15192cb1b5e' + uuid_efi = 'c12a7328-f81f-11d2-ba4b-00a0c93ec93b' + + ptr = 40 + + # Number of sectors in 1MB + sect_size = 512 + sect_1mb = (1 << 20) // sect_size + + required_parts = [ + {'num': 0xb, 'label':'RWFW', 'type': uuid_rwfw, 'size': '1'}, + {'num': 6, 'label':'KERN_C', 'type': uuid_kern, 'size': '1'}, + {'num': 7, 'label':'ROOT_C', 'type': uuid_root, 'size': '1'}, + {'num': 9, 'label':'reserved', 'type': uuid_reserved, 'size': '1'}, + {'num': 0xa, 'label':'reserved', 'type': uuid_reserved, 'size': '1'}, + + {'num': 2, 'label':'KERN_A', 'type': uuid_kern, 'size': '1M'}, + {'num': 4, 'label':'KERN_B', 'type': uuid_kern, 'size': '1M'}, + + {'num': 8, 'label':'OEM', 'type': uuid_state, 'size': '1M'}, + {'num': 0xc, 'label':'EFI-SYSTEM', 'type': uuid_efi, 'size': '1M'}, + + {'num': 5, 'label':'ROOT_B', 'type': uuid_root, 'size': '1'}, + {'num': 3, 'label':'ROOT_A', 'type': uuid_root, 'size': '1'}, + {'num': 1, 'label':'STATE', 'type': uuid_state, 'size': '1M'}, + ] + + for part in required_parts: + size_str = part['size'] + if 'M' in size_str: + size = int(size_str[:-1]) * sect_1mb + else: + size = int(size_str) + u_boot_utils.run_and_log( + cons, + f"cgpt add -i {part['num']} -b {ptr} -s {size} -t {part['type']} {fname}") + ptr += size + + u_boot_utils.run_and_log(cons, f'cgpt boot -p {fname}') + out = u_boot_utils.run_and_log(cons, f'cgpt show -q {fname}') + '''We expect something like this: + 8239 2048 1 Basic data + 45 2048 2 ChromeOS kernel + 8238 1 3 ChromeOS rootfs + 2093 2048 4 ChromeOS kernel + 8237 1 5 ChromeOS rootfs + 41 1 6 ChromeOS kernel + 42 1 7 ChromeOS rootfs + 4141 2048 8 Basic data + 43 1 9 ChromeOS reserved + 44 1 10 ChromeOS reserved + 40 1 11 ChromeOS firmware + 6189 2048 12 EFI System Partition + ''' + + # Create a dict (indexed by partition number) containing the above info + for line in out.splitlines(): + start, size, num, name = line.split(maxsplit=3) + parts[int(num)] = Partition(int(start), int(size), name) + + dummy = os.path.join(cons.config.result_dir, 'dummy.txt') + with open(dummy, 'wb') as outf: + outf.write(b'dummy\n') + + # For now we just use dummy kernels. This limits testing to just detecting + # a signed kernel. We could add support for the x86 data structures so that + # testing could cover getting the cmdline, setup.bin and other pieces. + kern = os.path.join(cons.config.result_dir, 'kern.bin') + with open(kern, 'wb') as outf: + outf.write(b'kernel\n') + + with open(fname, 'rb') as inf: + disk_data = inf.read() + + # put x86 kernel in partition 2 and arm one in partition 4 + set_part_data(2, pack_kernel(cons, 'x86', kern, dummy)) + set_part_data(4, pack_kernel(cons, 'arm', kern, dummy)) + + with open(fname, 'wb') as outf: + outf.write(disk_data) + + return fname + + def setup_cedit_file(cons): infname = os.path.join(cons.config.source_dir, 'test/boot/files/expo_layout.dts') @@ -329,6 +470,7 @@ def test_ut_dm_init_bootstd(u_boot_console): setup_bootflow_image(u_boot_console) setup_bootmenu_image(u_boot_console) setup_cedit_file(u_boot_console) + setup_cros_image(u_boot_console) # Restart so that the new mmc1.img is picked up u_boot_console.restart_uboot() -- cgit v1.2.3 From 56f243dcbe55c62e183ddf76b44a4393714d1694 Mon Sep 17 00:00:00 2001 From: Sughosh Ganu Date: Tue, 22 Aug 2023 23:10:00 +0530 Subject: test: capsule: Generate EFI capsules through binman Support has been added for generating the EFI capsules through binman. Make changes in the EFI capsule update testing feature to generate capsules through binman. Signed-off-by: Sughosh Ganu --- .../tests/test_efi_capsule/capsule_gen_binman.dts | 321 +++++++++++++++++++++ test/py/tests/test_efi_capsule/conftest.py | 163 ++--------- test/py/tests/test_efi_capsule/uboot_bin_env.its | 36 --- 3 files changed, 346 insertions(+), 174 deletions(-) create mode 100644 test/py/tests/test_efi_capsule/capsule_gen_binman.dts delete mode 100644 test/py/tests/test_efi_capsule/uboot_bin_env.its (limited to 'test/py') diff --git a/test/py/tests/test_efi_capsule/capsule_gen_binman.dts b/test/py/tests/test_efi_capsule/capsule_gen_binman.dts new file mode 100644 index 00000000000..e8a18585092 --- /dev/null +++ b/test/py/tests/test_efi_capsule/capsule_gen_binman.dts @@ -0,0 +1,321 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Devicetree for capsule generation through binman + */ + +/dts-v1/; + +#include + +/ { + binman: binman { + multiple-images; + }; +}; + +&binman { + itb { + filename = UBOOT_FIT_IMAGE; + + fit { + description = "Automatic U-Boot environment update"; + #address-cells = <2>; + + images { + u-boot-bin { + description = "U-Boot binary on SPI Flash"; + compression = "none"; + type = "firmware"; + arch = "sandbox"; + load = <0>; + text { + text = "u-boot:New"; + }; + + hash-1 { + algo = "sha1"; + }; + }; + u-boot-env { + description = "U-Boot environment on SPI Flash"; + compression = "none"; + type = "firmware"; + arch = "sandbox"; + load = <0>; + text { + text = "u-boot-env:New"; + }; + + hash-1 { + algo = "sha1"; + }; + }; + }; + }; + }; + + capsule1 { + filename = "Test01"; + efi-capsule { + image-index = <0x1>; + image-guid = SANDBOX_UBOOT_IMAGE_GUID; + + text { + text = "u-boot:New"; + }; + }; + }; + + capsule2 { + filename = "Test02"; + efi-capsule { + image-index = <0x2>; + image-guid = SANDBOX_UBOOT_ENV_IMAGE_GUID; + + text { + text = "u-boot-env:New"; + }; + }; + }; + + capsule3 { + filename = "Test03"; + efi-capsule { + image-index = <0x1>; + image-guid = SANDBOX_INCORRECT_GUID; + + text { + text = "u-boot:New"; + }; + }; + }; + + capsule4 { + filename = "Test04"; + efi-capsule { + image-index = <0x1>; + image-guid = SANDBOX_FIT_IMAGE_GUID; + + blob { + filename = UBOOT_FIT_IMAGE; + }; + }; + }; + + capsule5 { + filename = "Test05"; + efi-capsule { + image-index = <0x1>; + image-guid = SANDBOX_INCORRECT_GUID; + + blob { + filename = UBOOT_FIT_IMAGE; + }; + }; + }; + + capsule6 { + filename = "Test101"; + efi-capsule { + image-index = <0x1>; + fw-version = <0x5>; + image-guid = SANDBOX_UBOOT_IMAGE_GUID; + + text { + text = "u-boot:New"; + }; + }; + }; + + capsule7 { + filename = "Test102"; + efi-capsule { + image-index = <0x2>; + fw-version = <0xa>; + image-guid = SANDBOX_UBOOT_ENV_IMAGE_GUID; + + text { + text = "u-boot-env:New"; + }; + }; + }; + + capsule8 { + filename = "Test103"; + efi-capsule { + image-index = <0x1>; + fw-version = <0x2>; + image-guid = SANDBOX_UBOOT_IMAGE_GUID; + + text { + text = "u-boot:New"; + }; + }; + }; + + capsule9 { + filename = "Test104"; + efi-capsule { + image-index = <0x1>; + fw-version = <0x5>; + image-guid = SANDBOX_FIT_IMAGE_GUID; + + blob { + filename = UBOOT_FIT_IMAGE; + }; + }; + }; + + capsule10 { + filename = "Test105"; + efi-capsule { + image-index = <0x1>; + fw-version = <0x2>; + image-guid = SANDBOX_FIT_IMAGE_GUID; + + blob { + filename = UBOOT_FIT_IMAGE; + }; + }; + }; + + capsule11 { + filename = "Test11"; + efi-capsule { + image-index = <0x1>; + image-guid = SANDBOX_UBOOT_IMAGE_GUID; + private-key = CAPSULE_PRIV_KEY; + public-key-cert = CAPSULE_PUB_KEY; + monotonic-count = <0x1>; + + text { + text = "u-boot:New"; + }; + }; + }; + + capsule12 { + filename = "Test12"; + efi-capsule { + image-index = <0x1>; + image-guid = SANDBOX_UBOOT_IMAGE_GUID; + private-key = CAPSULE_INVAL_KEY; + public-key-cert = CAPSULE_INVAL_PUB_KEY; + monotonic-count = <0x1>; + + text { + text = "u-boot:New"; + }; + }; + }; + + capsule13 { + filename = "Test13"; + efi-capsule { + image-index = <0x1>; + image-guid = SANDBOX_FIT_IMAGE_GUID; + private-key = CAPSULE_PRIV_KEY; + public-key-cert = CAPSULE_PUB_KEY; + monotonic-count = <0x1>; + + blob { + filename = UBOOT_FIT_IMAGE; + }; + }; + }; + + capsule14 { + filename = "Test14"; + efi-capsule { + image-index = <0x1>; + image-guid = SANDBOX_FIT_IMAGE_GUID; + private-key = CAPSULE_INVAL_KEY; + public-key-cert = CAPSULE_INVAL_PUB_KEY; + monotonic-count = <0x1>; + + blob { + filename = UBOOT_FIT_IMAGE; + }; + }; + }; + + capsule15 { + filename = "Test111"; + efi-capsule { + image-index = <0x1>; + fw-version = <0x5>; + image-guid = SANDBOX_UBOOT_IMAGE_GUID; + private-key = CAPSULE_PRIV_KEY; + public-key-cert = CAPSULE_PUB_KEY; + monotonic-count = <0x1>; + + text { + text = "u-boot:New"; + }; + }; + }; + + capsule16 { + filename = "Test112"; + efi-capsule { + image-index = <0x2>; + fw-version = <0xa>; + image-guid = SANDBOX_UBOOT_ENV_IMAGE_GUID; + private-key = CAPSULE_PRIV_KEY; + public-key-cert = CAPSULE_PUB_KEY; + monotonic-count = <0x1>; + + text { + text = "u-boot-env:New"; + }; + }; + }; + + capsule17 { + filename = "Test113"; + efi-capsule { + image-index = <0x1>; + fw-version = <0x2>; + image-guid = SANDBOX_UBOOT_IMAGE_GUID; + private-key = CAPSULE_PRIV_KEY; + public-key-cert = CAPSULE_PUB_KEY; + monotonic-count = <0x1>; + + text { + text = "u-boot:New"; + }; + }; + }; + + capsule18 { + filename = "Test114"; + efi-capsule { + image-index = <0x1>; + fw-version = <0x5>; + image-guid = SANDBOX_FIT_IMAGE_GUID; + private-key = CAPSULE_PRIV_KEY; + public-key-cert = CAPSULE_PUB_KEY; + monotonic-count = <0x1>; + + blob { + filename = UBOOT_FIT_IMAGE; + }; + }; + }; + + capsule19 { + filename = "Test115"; + efi-capsule { + image-index = <0x1>; + fw-version = <0x2>; + image-guid = SANDBOX_FIT_IMAGE_GUID; + private-key = CAPSULE_PRIV_KEY; + public-key-cert = CAPSULE_PUB_KEY; + monotonic-count = <0x1>; + + blob { + filename = UBOOT_FIT_IMAGE; + }; + }; + }; +}; diff --git a/test/py/tests/test_efi_capsule/conftest.py b/test/py/tests/test_efi_capsule/conftest.py index 054be1ee971..9160f294e60 100644 --- a/test/py/tests/test_efi_capsule/conftest.py +++ b/test/py/tests/test_efi_capsule/conftest.py @@ -4,6 +4,8 @@ """Fixture for UEFI capsule test.""" +import os + from subprocess import call, check_call, CalledProcessError import pytest from capsule_defs import CAPSULE_DATA_DIR, CAPSULE_INSTALL_DIR, EFITOOLS_PATH @@ -34,15 +36,20 @@ def efi_capsule_data(request, u_boot_config): capsule_auth_enabled = u_boot_config.buildconfig.get( 'config_efi_capsule_authenticate') + key_dir = u_boot_config.source_dir + '/board/sandbox' if capsule_auth_enabled: - # Create private key (SIGNER.key) and certificate (SIGNER.crt) - check_call('cd %s; ' - 'openssl req -x509 -sha256 -newkey rsa:2048 ' - '-subj /CN=TEST_SIGNER/ -keyout SIGNER.key ' - '-out SIGNER.crt -nodes -days 365' - % data_dir, shell=True) - check_call('cd %s; %scert-to-efi-sig-list SIGNER.crt SIGNER.esl' - % (data_dir, EFITOOLS_PATH), shell=True) + # Get the keys from the board directory + check_call('cp %s/capsule_priv_key_good.key %s/SIGNER.key' + % (key_dir, data_dir), shell=True) + check_call('cp %s/capsule_pub_key_good.crt %s/SIGNER.crt' + % (key_dir, data_dir), shell=True) + check_call('cp %s/capsule_pub_esl_good.esl %s/SIGNER.esl' + % (key_dir, data_dir), shell=True) + + check_call('cp %s/capsule_priv_key_bad.key %s/SIGNER2.key' + % (key_dir, data_dir), shell=True) + check_call('cp %s/capsule_pub_key_bad.crt %s/SIGNER2.crt' + % (key_dir, data_dir), shell=True) # Update dtb adding capsule certificate check_call('cd %s; ' @@ -54,14 +61,6 @@ def efi_capsule_data(request, u_boot_config): '-o test_sig.dtb signature.dtbo' % (data_dir, u_boot_config.build_dir), shell=True) - # Create *malicious* private key (SIGNER2.key) and certificate - # (SIGNER2.crt) - check_call('cd %s; ' - 'openssl req -x509 -sha256 -newkey rsa:2048 ' - '-subj /CN=TEST_SIGNER/ -keyout SIGNER2.key ' - '-out SIGNER2.crt -nodes -days 365' - % data_dir, shell=True) - # Update dtb to add the version information check_call('cd %s; ' 'cp %s/test/py/tests/test_efi_capsule/version.dts .' @@ -79,132 +78,20 @@ def efi_capsule_data(request, u_boot_config): '-o test_ver.dtb version.dtbo' % (data_dir, u_boot_config.build_dir), shell=True) - # Create capsule files # two regions: one for u-boot.bin and the other for u-boot.env check_call('cd %s; echo -n u-boot:Old > u-boot.bin.old; echo -n u-boot:New > u-boot.bin.new; echo -n u-boot-env:Old > u-boot.env.old; echo -n u-boot-env:New > u-boot.env.new' % data_dir, shell=True) - check_call('sed -e \"s?BINFILE1?u-boot.bin.new?\" -e \"s?BINFILE2?u-boot.env.new?\" %s/test/py/tests/test_efi_capsule/uboot_bin_env.its > %s/uboot_bin_env.its' % - (u_boot_config.source_dir, data_dir), - shell=True) - check_call('cd %s; %s/tools/mkimage -f uboot_bin_env.its uboot_bin_env.itb' % - (data_dir, u_boot_config.build_dir), - shell=True) - check_call('cd %s; %s/tools/mkeficapsule --index 1 --guid 09D7CF52-0720-4710-91D1-08469B7FE9C8 u-boot.bin.new Test01' % - (data_dir, u_boot_config.build_dir), - shell=True) - check_call('cd %s; %s/tools/mkeficapsule --index 2 --guid 5A7021F5-FEF2-48B4-AABA-832E777418C0 u-boot.env.new Test02' % - (data_dir, u_boot_config.build_dir), - shell=True) - check_call('cd %s; %s/tools/mkeficapsule --index 1 --guid 058B7D83-50D5-4C47-A195-60D86AD341C4 u-boot.bin.new Test03' % - (data_dir, u_boot_config.build_dir), - shell=True) - check_call('cd %s; %s/tools/mkeficapsule --index 1 --guid 3673B45D-6A7C-46F3-9E60-ADABB03F7937 uboot_bin_env.itb Test04' % - (data_dir, u_boot_config.build_dir), - shell=True) - check_call('cd %s; %s/tools/mkeficapsule --index 1 --guid 058B7D83-50D5-4C47-A195-60D86AD341C4 uboot_bin_env.itb Test05' % - (data_dir, u_boot_config.build_dir), - shell=True) - check_call('cd %s; %s/tools/mkeficapsule --index 1 --fw-version 5 ' - '--guid 09D7CF52-0720-4710-91D1-08469B7FE9C8 u-boot.bin.new Test101' % - (data_dir, u_boot_config.build_dir), - shell=True) - check_call('cd %s; %s/tools/mkeficapsule --index 2 --fw-version 10 ' - '--guid 5A7021F5-FEF2-48B4-AABA-832E777418C0 u-boot.env.new Test102' % - (data_dir, u_boot_config.build_dir), - shell=True) - check_call('cd %s; %s/tools/mkeficapsule --index 1 --fw-version 2 ' - '--guid 09D7CF52-0720-4710-91D1-08469B7FE9C8 u-boot.bin.new Test103' % - (data_dir, u_boot_config.build_dir), - shell=True) - check_call('cd %s; %s/tools/mkeficapsule --index 1 --fw-version 5 ' - '--guid 3673B45D-6A7C-46F3-9E60-ADABB03F7937 uboot_bin_env.itb Test104' % - (data_dir, u_boot_config.build_dir), - shell=True) - check_call('cd %s; %s/tools/mkeficapsule --index 1 --fw-version 2 ' - '--guid 3673B45D-6A7C-46F3-9E60-ADABB03F7937 uboot_bin_env.itb Test105' % - (data_dir, u_boot_config.build_dir), - shell=True) - if capsule_auth_enabled: - # raw firmware signed with proper key - check_call('cd %s; ' - '%s/tools/mkeficapsule --index 1 --monotonic-count 1 ' - '--private-key SIGNER.key --certificate SIGNER.crt ' - '--guid 09D7CF52-0720-4710-91D1-08469B7FE9C8 ' - 'u-boot.bin.new Test11' - % (data_dir, u_boot_config.build_dir), - shell=True) - # raw firmware signed with *mal* key - check_call('cd %s; ' - '%s/tools/mkeficapsule --index 1 --monotonic-count 1 ' - '--private-key SIGNER2.key ' - '--certificate SIGNER2.crt ' - '--guid 09D7CF52-0720-4710-91D1-08469B7FE9C8 ' - 'u-boot.bin.new Test12' - % (data_dir, u_boot_config.build_dir), - shell=True) - # FIT firmware signed with proper key - check_call('cd %s; ' - '%s/tools/mkeficapsule --index 1 --monotonic-count 1 ' - '--private-key SIGNER.key --certificate SIGNER.crt ' - '--guid 3673B45D-6A7C-46F3-9E60-ADABB03F7937 ' - 'uboot_bin_env.itb Test13' - % (data_dir, u_boot_config.build_dir), - shell=True) - # FIT firmware signed with *mal* key - check_call('cd %s; ' - '%s/tools/mkeficapsule --index 1 --monotonic-count 1 ' - '--private-key SIGNER2.key ' - '--certificate SIGNER2.crt ' - '--guid 3673B45D-6A7C-46F3-9E60-ADABB03F7937 ' - 'uboot_bin_env.itb Test14' - % (data_dir, u_boot_config.build_dir), - shell=True) - # raw firmware signed with proper key with version information - check_call('cd %s; ' - '%s/tools/mkeficapsule --index 1 --monotonic-count 1 ' - '--fw-version 5 ' - '--private-key SIGNER.key --certificate SIGNER.crt ' - '--guid 09D7CF52-0720-4710-91D1-08469B7FE9C8 ' - 'u-boot.bin.new Test111' - % (data_dir, u_boot_config.build_dir), - shell=True) - # raw firmware signed with proper key with version information - check_call('cd %s; ' - '%s/tools/mkeficapsule --index 2 --monotonic-count 1 ' - '--fw-version 10 ' - '--private-key SIGNER.key --certificate SIGNER.crt ' - '--guid 5A7021F5-FEF2-48B4-AABA-832E777418C0 ' - 'u-boot.env.new Test112' - % (data_dir, u_boot_config.build_dir), - shell=True) - # raw firmware signed with proper key with lower version information - check_call('cd %s; ' - '%s/tools/mkeficapsule --index 1 --monotonic-count 1 ' - '--fw-version 2 ' - '--private-key SIGNER.key --certificate SIGNER.crt ' - '--guid 09D7CF52-0720-4710-91D1-08469B7FE9C8 ' - 'u-boot.bin.new Test113' - % (data_dir, u_boot_config.build_dir), - shell=True) - # FIT firmware signed with proper key with version information - check_call('cd %s; ' - '%s/tools/mkeficapsule --index 1 --monotonic-count 1 ' - '--fw-version 5 ' - '--private-key SIGNER.key --certificate SIGNER.crt ' - '--guid 3673B45D-6A7C-46F3-9E60-ADABB03F7937 ' - 'uboot_bin_env.itb Test114' - % (data_dir, u_boot_config.build_dir), - shell=True) - # FIT firmware signed with proper key with lower version information - check_call('cd %s; ' - '%s/tools/mkeficapsule --index 1 --monotonic-count 1 ' - '--fw-version 2 ' - '--private-key SIGNER.key --certificate SIGNER.crt ' - '--guid 3673B45D-6A7C-46F3-9E60-ADABB03F7937 ' - 'uboot_bin_env.itb Test115' - % (data_dir, u_boot_config.build_dir), - shell=True) + pythonpath = os.environ.get('PYTHONPATH', '') + os.environ['PYTHONPATH'] = pythonpath + ':' + '%s/scripts/dtc/pylibfdt' % u_boot_config.build_dir + check_call('cd %s; ' + 'cc -E -I %s/include -x assembler-with-cpp -o capsule_gen_tmp.dts %s/test/py/tests/test_efi_capsule/capsule_gen_binman.dts; ' + 'dtc -I dts -O dtb capsule_gen_tmp.dts -o capsule_binman.dtb;' + % (data_dir, u_boot_config.source_dir, u_boot_config.source_dir), shell=True) + check_call('cd %s; ' + './tools/binman/binman --toolpath %s/tools build -u -d %s/capsule_binman.dtb -O %s -m --allow-missing -I %s -I ./board/sandbox -I ./arch/sandbox/dts' + % (u_boot_config.source_dir, u_boot_config.build_dir, data_dir, data_dir, data_dir), shell=True) + os.environ['PYTHONPATH'] = pythonpath # Create a disk image with EFI system partition check_call('virt-make-fs --partition=gpt --size=+1M --type=vfat %s %s' % diff --git a/test/py/tests/test_efi_capsule/uboot_bin_env.its b/test/py/tests/test_efi_capsule/uboot_bin_env.its deleted file mode 100644 index fc659074811..00000000000 --- a/test/py/tests/test_efi_capsule/uboot_bin_env.its +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Automatic software update for U-Boot - * Make sure the flashing addresses ('load' prop) is correct for your board! - */ - -/dts-v1/; - -/ { - description = "Automatic U-Boot environment update"; - #address-cells = <2>; - - images { - u-boot-bin { - description = "U-Boot binary on SPI Flash"; - data = /incbin/("BINFILE1"); - compression = "none"; - type = "firmware"; - arch = "sandbox"; - load = <0>; - hash-1 { - algo = "sha1"; - }; - }; - u-boot-env { - description = "U-Boot environment on SPI Flash"; - data = /incbin/("BINFILE2"); - compression = "none"; - type = "firmware"; - arch = "sandbox"; - load = <0>; - hash-1 { - algo = "sha1"; - }; - }; - }; -}; -- cgit v1.2.3 From 61cad8da8885fa7b9fc685cdf55f30e615155c76 Mon Sep 17 00:00:00 2001 From: Sughosh Ganu Date: Tue, 22 Aug 2023 23:10:02 +0530 Subject: sandbox: trace: Increase trace buffer size When running the trace test on the sandbox platform, the current size of 16MiB is no longer large enough for capturing the entire trace history, and results in truncation. Use a size of 32MiB for the trace buffer on the sandbox platform while running the trace test. Signed-off-by: Sughosh Ganu Reviewed-by: Simon Glass --- test/py/tests/test_trace.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'test/py') diff --git a/test/py/tests/test_trace.py b/test/py/tests/test_trace.py index ac3e95925e9..ad2250920d7 100644 --- a/test/py/tests/test_trace.py +++ b/test/py/tests/test_trace.py @@ -61,7 +61,7 @@ def collect_trace(cons): # Read out the trace data addr = 0x02000000 - size = 0x01000000 + size = 0x02000000 out = cons.run_command(f'trace calls {addr:x} {size:x}') print(out) fname = os.path.join(TMPDIR, 'trace') -- cgit v1.2.3 From 252c9c1c266eb008fdda79ed1373eef3c93aaebf Mon Sep 17 00:00:00 2001 From: Sughosh Ganu Date: Tue, 22 Aug 2023 23:10:07 +0530 Subject: test: capsule: Remove logic to add public key ESL The public key EFI Signature List(ESL) needed for capsule authentication is now embedded into the platform's DTB as part of the build. Remove the superfluous logic from the test setup. Signed-off-by: Sughosh Ganu --- test/py/tests/test_efi_capsule/conftest.py | 14 ++++---------- test/py/tests/test_efi_capsule/signature.dts | 10 ---------- 2 files changed, 4 insertions(+), 20 deletions(-) delete mode 100644 test/py/tests/test_efi_capsule/signature.dts (limited to 'test/py') diff --git a/test/py/tests/test_efi_capsule/conftest.py b/test/py/tests/test_efi_capsule/conftest.py index 9160f294e60..dd41da9284e 100644 --- a/test/py/tests/test_efi_capsule/conftest.py +++ b/test/py/tests/test_efi_capsule/conftest.py @@ -51,21 +51,15 @@ def efi_capsule_data(request, u_boot_config): check_call('cp %s/capsule_pub_key_bad.crt %s/SIGNER2.crt' % (key_dir, data_dir), shell=True) - # Update dtb adding capsule certificate - check_call('cd %s; ' - 'cp %s/test/py/tests/test_efi_capsule/signature.dts .' - % (data_dir, u_boot_config.source_dir), shell=True) - check_call('cd %s; ' - 'dtc -@ -I dts -O dtb -o signature.dtbo signature.dts; ' - 'fdtoverlay -i %s/arch/sandbox/dts/test.dtb ' - '-o test_sig.dtb signature.dtbo' - % (data_dir, u_boot_config.build_dir), shell=True) - # Update dtb to add the version information check_call('cd %s; ' 'cp %s/test/py/tests/test_efi_capsule/version.dts .' % (data_dir, u_boot_config.source_dir), shell=True) + if capsule_auth_enabled: + check_call('cd %s; ' + 'cp %s/arch/sandbox/dts/test.dtb test_sig.dtb' + % (data_dir, u_boot_config.build_dir), shell=True) check_call('cd %s; ' 'dtc -@ -I dts -O dtb -o version.dtbo version.dts; ' 'fdtoverlay -i test_sig.dtb ' diff --git a/test/py/tests/test_efi_capsule/signature.dts b/test/py/tests/test_efi_capsule/signature.dts deleted file mode 100644 index 078cfc76c93..00000000000 --- a/test/py/tests/test_efi_capsule/signature.dts +++ /dev/null @@ -1,10 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0+ - -/dts-v1/; -/plugin/; - -&{/} { - signature { - capsule-key = /incbin/("SIGNER.esl"); - }; -}; -- cgit v1.2.3 From ba5e3e1ed0afb3daa446d2168e5c8c9fe119cbaf Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Mon, 21 Aug 2023 21:16:48 -0600 Subject: event: Support a simple spy record The current event spy is always passed the event context and the event. The context is always NULL for a static spy. The event is not often used. Introduce a 'simple' spy which takes no arguments. This allows us to drop the adaptation code that many of these spy records use. Update the event script to find these in the image. Signed-off-by: Simon Glass --- test/py/tests/test_event_dump.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'test/py') diff --git a/test/py/tests/test_event_dump.py b/test/py/tests/test_event_dump.py index da196df4c3e..041f8f9c979 100644 --- a/test/py/tests/test_event_dump.py +++ b/test/py/tests/test_event_dump.py @@ -18,5 +18,6 @@ def test_event_dump(u_boot_console): -------------------- ------------------------------ ------------------------------ EVT_FT_FIXUP bootmeth_vbe_ft_fixup .*boot/vbe_request.c:.* EVT_FT_FIXUP bootmeth_vbe_simple_ft_fixup .*boot/vbe_simple_os.c:.* -EVT_MISC_INIT_F sandbox_misc_init_f .*arch/sandbox/cpu/start.c:''' +EVT_MISC_INIT_F sandbox_misc_init_f .*arch/sandbox/cpu/start.c:.* +EVT_TEST h_adder_simple .*test/common/event.c:''' assert re.match(expect, out, re.MULTILINE) is not None -- cgit v1.2.3 From c9eff0a6b6ea2bcd54d30f8a02281681f3730223 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Mon, 21 Aug 2023 21:16:54 -0600 Subject: initcall: Support emitting events At present the initcall list consists of a list of function pointers. Over time the initcall lists will likely change to mostly emitting events, since most of the calls are board- or arch-specific. As a first step, allow an initcall to be an event type instead of a function pointer. Add the required macro and update initcall_run_list() to emit an event in that case, or ignore it if events are not enabled. The bottom 8 bits of the function pointer are used to hold the event type, with the rest being all ones. This should avoid any collision, since initcalls should not be above 0xffffff00 in memory. Convert misc_init_f over to use this mechanism. Add comments to the initcall header file while we are here. Also fix up the trace test to handle the change. Signed-off-by: Simon Glass --- test/py/tests/test_trace.py | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) (limited to 'test/py') diff --git a/test/py/tests/test_trace.py b/test/py/tests/test_trace.py index ad2250920d7..28a6e72f525 100644 --- a/test/py/tests/test_trace.py +++ b/test/py/tests/test_trace.py @@ -175,7 +175,7 @@ def check_funcgraph(cons, fname, proftool, map_fname, trace_dat): # Then look for this: # u-boot-1 [000] 282.101375: funcgraph_exit: 0.006 us | } # Then check for this: - # u-boot-1 [000] 282.101375: funcgraph_entry: 0.000 us | event_init(); + # u-boot-1 [000] 282.101375: funcgraph_entry: 0.000 us | initcall_is_event(); expected_indent = None found_start = False @@ -197,8 +197,9 @@ def check_funcgraph(cons, fname, proftool, map_fname, trace_dat): elif found_start and indent == expected_indent and brace == '}': found_end = True - # The next function after initf_bootstage() exits should be event_init() - assert upto == 'event_init()' + # The next function after initf_bootstage() exits should be + # initcall_is_event() + assert upto == 'initcall_is_event()' # Now look for initf_dm() and dm_timer_init() so we can check the bootstage # time @@ -247,7 +248,7 @@ def check_flamegraph(cons, fname, proftool, map_fname, trace_fg): # We expect dm_timer_init() to be called twice: once before relocation and # once after look1 = 'initf_dm;dm_timer_init 1' - look2 = 'board_init_r;initr_dm_devices;dm_timer_init 1' + look2 = 'board_init_r;initcall_run_list;initr_dm_devices;dm_timer_init 1' found = 0 with open(trace_fg, 'r') as fd: for line in fd: @@ -272,7 +273,7 @@ def check_flamegraph(cons, fname, proftool, map_fname, trace_fg): total += count return total - +check_flamegraph @pytest.mark.slow @pytest.mark.boardspec('sandbox') @pytest.mark.buildconfigspec('trace') -- cgit v1.2.3 From f72d0d4a2f9a2d05ebeefb583992cc620f7c4c2d Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Mon, 21 Aug 2023 21:16:56 -0600 Subject: event: Convert existing spy records to simple Very few of the existing event-spy records use the arguments they are passed. Update them to use a simple spy instead, to simplify the code. Where an adaptor function is currently used, remove it where possible. Signed-off-by: Simon Glass --- test/py/tests/test_event_dump.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'test/py') diff --git a/test/py/tests/test_event_dump.py b/test/py/tests/test_event_dump.py index 041f8f9c979..a6df9e10e54 100644 --- a/test/py/tests/test_event_dump.py +++ b/test/py/tests/test_event_dump.py @@ -18,6 +18,6 @@ def test_event_dump(u_boot_console): -------------------- ------------------------------ ------------------------------ EVT_FT_FIXUP bootmeth_vbe_ft_fixup .*boot/vbe_request.c:.* EVT_FT_FIXUP bootmeth_vbe_simple_ft_fixup .*boot/vbe_simple_os.c:.* -EVT_MISC_INIT_F sandbox_misc_init_f .*arch/sandbox/cpu/start.c:.* +EVT_MISC_INIT_F sandbox_early_getopt_check .*arch/sandbox/cpu/start.c:.* EVT_TEST h_adder_simple .*test/common/event.c:''' assert re.match(expect, out, re.MULTILINE) is not None -- cgit v1.2.3 From a3eb350649757efc5eac3bfe41d1fbf0e51b0690 Mon Sep 17 00:00:00 2001 From: Joshua Watt Date: Thu, 31 Aug 2023 10:51:36 -0600 Subject: tests: gpt: Remove test order dependency Re-create a clean disk image for each test to prevent modifications from one test affecting another Signed-off-by: Joshua Watt --- test/py/tests/test_gpt.py | 20 ++++++++------------ 1 file changed, 8 insertions(+), 12 deletions(-) (limited to 'test/py') diff --git a/test/py/tests/test_gpt.py b/test/py/tests/test_gpt.py index 73bfbf77a27..339468bc127 100644 --- a/test/py/tests/test_gpt.py +++ b/test/py/tests/test_gpt.py @@ -61,18 +61,14 @@ class GptTestDiskImage(object): cmd = ('cp', persistent, self.path) u_boot_utils.run_and_log(u_boot_console, cmd) -gtdi = None @pytest.fixture(scope='function') def state_disk_image(u_boot_console): """pytest fixture to provide a GptTestDiskImage object to tests. This is function-scoped because it uses u_boot_console, which is also - function-scoped. However, we don't need to actually do any function-scope - work, so this simply returns the same object over and over each time.""" + function-scoped. A new disk is returned each time to prevent tests from + interfering with each other.""" - global gtdi - if not gtdi: - gtdi = GptTestDiskImage(u_boot_console) - return gtdi + return GptTestDiskImage(u_boot_console) @pytest.mark.boardspec('sandbox') @pytest.mark.buildconfigspec('cmd_gpt') @@ -186,12 +182,12 @@ def test_gpt_swap_partitions(state_disk_image, u_boot_console): u_boot_console.run_command('host bind 0 ' + state_disk_image.path) output = u_boot_console.run_command('part list host 0') - assert '0x00000800 0x00000fff "first"' in output - assert '0x00001000 0x00001bff "second"' in output - u_boot_console.run_command('gpt swap host 0 first second') + assert '0x00000800 0x00000fff "part1"' in output + assert '0x00001000 0x00001bff "part2"' in output + u_boot_console.run_command('gpt swap host 0 part1 part2') output = u_boot_console.run_command('part list host 0') - assert '0x00000800 0x00000fff "second"' in output - assert '0x00001000 0x00001bff "first"' in output + assert '0x00000800 0x00000fff "part2"' in output + assert '0x00001000 0x00001bff "part1"' in output @pytest.mark.boardspec('sandbox') @pytest.mark.buildconfigspec('cmd_gpt') -- cgit v1.2.3 From b1433affd9a9de10150c31929564f68ca338911a Mon Sep 17 00:00:00 2001 From: Joshua Watt Date: Thu, 31 Aug 2023 10:51:37 -0600 Subject: cmd: gpt: Add gpt_partition_bootable variable Adds an additional variable called gpt_partition_bootable that indicates if the given partition is bootable or not. Signed-off-by: Joshua Watt --- test/py/tests/test_gpt.py | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) (limited to 'test/py') diff --git a/test/py/tests/test_gpt.py b/test/py/tests/test_gpt.py index 339468bc127..946858800d6 100644 --- a/test/py/tests/test_gpt.py +++ b/test/py/tests/test_gpt.py @@ -49,6 +49,7 @@ class GptTestDiskImage(object): u_boot_utils.run_and_log(u_boot_console, cmd) # part1 offset 1MB size 1MB cmd = ('sgdisk', '--new=1:2048:4095', '--change-name=1:part1', + '-A 1:set:2', persistent) # part2 offset 2MB size 1.5MB u_boot_utils.run_and_log(u_boot_console, cmd) @@ -117,6 +118,38 @@ def test_gpt_guid(state_disk_image, u_boot_console): output = u_boot_console.run_command('gpt guid host 0') assert '375a56f7-d6c9-4e81-b5f0-09d41ca89efe' in output +@pytest.mark.boardspec('sandbox') +@pytest.mark.buildconfigspec('cmd_gpt') +@pytest.mark.requiredtool('sgdisk') +def test_gpt_setenv(state_disk_image, u_boot_console): + """Test the gpt setenv command.""" + u_boot_console.run_command('host bind 0 ' + state_disk_image.path) + output = u_boot_console.run_command('gpt setenv host 0 part1') + assert 'success!' in output + output = u_boot_console.run_command('echo ${gpt_partition_addr}') + assert output.rstrip() == '800' + output = u_boot_console.run_command('echo ${gpt_partition_size}') + assert output.rstrip() == '800' + output = u_boot_console.run_command('echo ${gpt_partition_name}') + assert output.rstrip() == 'part1' + output = u_boot_console.run_command('echo ${gpt_partition_entry}') + assert output.rstrip() == '1' + output = u_boot_console.run_command('echo ${gpt_partition_bootable}') + assert output.rstrip() == '1' + + output = u_boot_console.run_command('gpt setenv host 0 part2') + assert 'success!' in output + output = u_boot_console.run_command('echo ${gpt_partition_addr}') + assert output.rstrip() == '1000' + output = u_boot_console.run_command('echo ${gpt_partition_size}') + assert output.rstrip() == 'c00' + output = u_boot_console.run_command('echo ${gpt_partition_name}') + assert output.rstrip() == 'part2' + output = u_boot_console.run_command('echo ${gpt_partition_entry}') + assert output.rstrip() == '2' + output = u_boot_console.run_command('echo ${gpt_partition_bootable}') + assert output.rstrip() == '0' + @pytest.mark.boardspec('sandbox') @pytest.mark.buildconfigspec('cmd_gpt') @pytest.mark.requiredtool('sgdisk') -- cgit v1.2.3 From a1e793add5dd21c2a1b08bc57ac99e43183913b6 Mon Sep 17 00:00:00 2001 From: Joshua Watt Date: Thu, 31 Aug 2023 10:51:38 -0600 Subject: cmd: gpt: Add command to set bootable flags Adds a command that can be used to modify the GPT partition table to indicate which partitions should have the bootable flag set Signed-off-by: Joshua Watt --- test/py/tests/test_gpt.py | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) (limited to 'test/py') diff --git a/test/py/tests/test_gpt.py b/test/py/tests/test_gpt.py index 946858800d6..5d23f9b2925 100644 --- a/test/py/tests/test_gpt.py +++ b/test/py/tests/test_gpt.py @@ -222,6 +222,28 @@ def test_gpt_swap_partitions(state_disk_image, u_boot_console): assert '0x00000800 0x00000fff "part2"' in output assert '0x00001000 0x00001bff "part1"' in output +@pytest.mark.buildconfigspec('cmd_gpt') +@pytest.mark.buildconfigspec('cmd_gpt_rename') +@pytest.mark.buildconfigspec('cmd_part') +@pytest.mark.requiredtool('sgdisk') +def test_gpt_set_bootable(state_disk_image, u_boot_console): + """Test the gpt set-bootable command.""" + + u_boot_console.run_command('host bind 0 ' + state_disk_image.path) + parts = ('part2', 'part1') + for bootable in parts: + output = u_boot_console.run_command(f'gpt set-bootable host 0 {bootable}') + assert 'success!' in output + + for p in parts: + output = u_boot_console.run_command(f'gpt setenv host 0 {p}') + assert 'success!' in output + output = u_boot_console.run_command('echo ${gpt_partition_bootable}') + if p == bootable: + assert output.rstrip() == '1' + else: + assert output.rstrip() == '0' + @pytest.mark.boardspec('sandbox') @pytest.mark.buildconfigspec('cmd_gpt') @pytest.mark.buildconfigspec('cmd_part') -- cgit v1.2.3 From 368beaf7bb609b1daede46e3b31f5788d52e44e5 Mon Sep 17 00:00:00 2001 From: Joshua Watt Date: Thu, 31 Aug 2023 10:51:39 -0600 Subject: cmd: gpt: Preserve type GUID if enabled If CONFIG_PARTITION_TYPE_GUID is enabled, the type GUID will be preserved when writing out the partition string. It was already respected when writing out partitions; this ensures that if you capture the current partition layout and write it back (such as when renaming), the type GUIDs are preserved. Signed-off-by: Joshua Watt --- test/py/tests/test_gpt.py | 65 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 65 insertions(+) (limited to 'test/py') diff --git a/test/py/tests/test_gpt.py b/test/py/tests/test_gpt.py index 5d23f9b2925..93007dee9a1 100644 --- a/test/py/tests/test_gpt.py +++ b/test/py/tests/test_gpt.py @@ -16,6 +16,35 @@ the test. # Mark all tests here as slow pytestmark = pytest.mark.slow +def parse_gpt_parts(disk_str): + """Parser a partition string into a list of partitions. + + Args: + disk_str: The disk description string, as returned by `gpt read` + + Returns: + A list of parsed partitions. Each partition is a dictionary with the + string value from each specified key in the partition description, or a + key with with the value True for a boolean flag + """ + parts = [] + for part_str in disk_str.split(';'): + part = {} + for option in part_str.split(","): + if not option: + continue + + if "=" in option: + key, value = option.split("=") + part[key] = value + else: + part[option] = True + + if part: + parts.append(part) + + return parts + class GptTestDiskImage(object): """Disk Image used by the GPT tests.""" @@ -49,11 +78,13 @@ class GptTestDiskImage(object): u_boot_utils.run_and_log(u_boot_console, cmd) # part1 offset 1MB size 1MB cmd = ('sgdisk', '--new=1:2048:4095', '--change-name=1:part1', + '--partition-guid=1:33194895-67f6-4561-8457-6fdeed4f50a3', '-A 1:set:2', persistent) # part2 offset 2MB size 1.5MB u_boot_utils.run_and_log(u_boot_console, cmd) cmd = ('sgdisk', '--new=2:4096:7167', '--change-name=2:part2', + '--partition-guid=2:cc9c6e4a-6551-4cb5-87be-3210f96c86fb', persistent) u_boot_utils.run_and_log(u_boot_console, cmd) cmd = ('sgdisk', '--load-backup=' + persistent) @@ -88,6 +119,40 @@ def test_gpt_read(state_disk_image, u_boot_console): assert '0x00000800 0x00000fff "part1"' in output assert '0x00001000 0x00001bff "part2"' in output +@pytest.mark.boardspec('sandbox') +@pytest.mark.buildconfigspec('cmd_gpt') +@pytest.mark.buildconfigspec('partition_type_guid') +@pytest.mark.requiredtool('sgdisk') +def test_gpt_read_var(state_disk_image, u_boot_console): + """Test the gpt read command.""" + + u_boot_console.run_command('host bind 0 ' + state_disk_image.path) + output = u_boot_console.run_command('gpt read host 0 gpt_parts') + assert 'success!' in output + + output = u_boot_console.run_command('echo ${gpt_parts}') + parts = parse_gpt_parts(output.rstrip()) + + assert parts == [ + { + "uuid_disk": "375a56f7-d6c9-4e81-b5f0-09d41ca89efe", + }, + { + "name": "part1", + "start": "0x100000", + "size": "0x100000", + "type": "0fc63daf-8483-4772-8e79-3d69d8477de4", + "uuid": "33194895-67f6-4561-8457-6fdeed4f50a3", + }, + { + "name": "part2", + "start": "0x200000", + "size": "0x180000", + "type": "0fc63daf-8483-4772-8e79-3d69d8477de4", + "uuid": "cc9c6e4a-6551-4cb5-87be-3210f96c86fb", + }, + ] + @pytest.mark.boardspec('sandbox') @pytest.mark.buildconfigspec('cmd_gpt') @pytest.mark.requiredtool('sgdisk') -- cgit v1.2.3 From 648140f77aff55d3bab072166a88ef179c474524 Mon Sep 17 00:00:00 2001 From: Joshua Watt Date: Thu, 31 Aug 2023 10:51:40 -0600 Subject: cmd: gpt: Preserve bootable flag Sets the bootable flag when constructing the partition string from the current partition configuration. This ensures that when the partitions are written back (for example, when renaming a partition), the flag is preserved. Signed-off-by: Joshua Watt --- test/py/tests/test_gpt.py | 1 + 1 file changed, 1 insertion(+) (limited to 'test/py') diff --git a/test/py/tests/test_gpt.py b/test/py/tests/test_gpt.py index 93007dee9a1..b4c03bc3a2d 100644 --- a/test/py/tests/test_gpt.py +++ b/test/py/tests/test_gpt.py @@ -143,6 +143,7 @@ def test_gpt_read_var(state_disk_image, u_boot_console): "size": "0x100000", "type": "0fc63daf-8483-4772-8e79-3d69d8477de4", "uuid": "33194895-67f6-4561-8457-6fdeed4f50a3", + "bootable": True, }, { "name": "part2", -- cgit v1.2.3 From 7cc1d87d7e1e64d7bb280ead94c55a51c4f3ee63 Mon Sep 17 00:00:00 2001 From: Joshua Watt Date: Thu, 31 Aug 2023 10:51:41 -0600 Subject: cmd: gpt: Add command to swap partition order Adds a command called "gpt transpose" which will swap the order two partition table entries in the GPT partition table (but leaves them pointing to the same locations on disk). This can be useful for swapping bootloaders in systems that use an A/B partitioning scheme where the bootrom is hard coded to look for the bootloader in a specific index in the GPT partition table. Signed-off-by: Joshua Watt --- test/py/tests/test_gpt.py | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) (limited to 'test/py') diff --git a/test/py/tests/test_gpt.py b/test/py/tests/test_gpt.py index b4c03bc3a2d..6e135b663e8 100644 --- a/test/py/tests/test_gpt.py +++ b/test/py/tests/test_gpt.py @@ -329,3 +329,22 @@ def test_gpt_write(state_disk_image, u_boot_console): assert '0x00001000 0x00001bff "second"' in output output = u_boot_console.run_command('gpt guid host 0') assert '375a56f7-d6c9-4e81-b5f0-09d41ca89efe' in output + +@pytest.mark.buildconfigspec('cmd_gpt') +@pytest.mark.buildconfigspec('cmd_gpt_rename') +@pytest.mark.buildconfigspec('cmd_part') +@pytest.mark.requiredtool('sgdisk') +def test_gpt_transpose(state_disk_image, u_boot_console): + """Test the gpt transpose command.""" + + u_boot_console.run_command('host bind 0 ' + state_disk_image.path) + output = u_boot_console.run_command('part list host 0') + assert '1\t0x00000800\t0x00000fff\t"part1"' in output + assert '2\t0x00001000\t0x00001bff\t"part2"' in output + + output = u_boot_console.run_command('gpt transpose host 0 1 2') + assert 'success!' in output + + output = u_boot_console.run_command('part list host 0') + assert '2\t0x00000800\t0x00000fff\t"part1"' in output + assert '1\t0x00001000\t0x00001bff\t"part2"' in output -- cgit v1.2.3 From 280fcda109eede9c987b1512a532973e61f06455 Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Wed, 30 Aug 2023 18:36:23 +0200 Subject: test/py: tpm2: skip tpm2_startup when env__tpm_device_test_skip=True All tpm2 tests should be possible to skip when env__tpm_device_test_skip=True but test_tpm2_startup is missing it. Reviewed-by: Ilias Apalodimas Signed-off-by: Michal Simek Link: https://lore.kernel.org/r/41f932e52bdd206b1b68d5ff313fc29b794a70e7.1693413381.git.michal.simek@amd.com --- test/py/tests/test_tpm2.py | 3 +++ 1 file changed, 3 insertions(+) (limited to 'test/py') diff --git a/test/py/tests/test_tpm2.py b/test/py/tests/test_tpm2.py index fce689cd992..c2579fa02c5 100644 --- a/test/py/tests/test_tpm2.py +++ b/test/py/tests/test_tpm2.py @@ -71,6 +71,9 @@ def test_tpm2_startup(u_boot_console): Initiate the TPM internal state machine. """ + skip_test = u_boot_console.config.env.get('env__tpm_device_test_skip', False) + if skip_test: + pytest.skip('skip TPM device test') u_boot_console.run_command('tpm2 startup TPM2_SU_CLEAR') output = u_boot_console.run_command('echo $?') assert output.endswith('0') -- cgit v1.2.3 From 53fab13a7b11630aeb731c8ef7553cf773311a9f Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Wed, 20 Sep 2023 07:29:51 -0600 Subject: efi: Use the installed SMBIOS tables U-Boot should set up the SMBIOS tables during startup, as it does on x86. Ensure that it does this correctly on non-x86 machines too, by creating an event spy for last-stage init. Tidy up the installation-condition code while we are here. Signed-off-by: Simon Glass Reviewed-by: Bin Meng --- test/py/tests/test_event_dump.py | 1 + 1 file changed, 1 insertion(+) (limited to 'test/py') diff --git a/test/py/tests/test_event_dump.py b/test/py/tests/test_event_dump.py index a6df9e10e54..e282c67335c 100644 --- a/test/py/tests/test_event_dump.py +++ b/test/py/tests/test_event_dump.py @@ -18,6 +18,7 @@ def test_event_dump(u_boot_console): -------------------- ------------------------------ ------------------------------ EVT_FT_FIXUP bootmeth_vbe_ft_fixup .*boot/vbe_request.c:.* EVT_FT_FIXUP bootmeth_vbe_simple_ft_fixup .*boot/vbe_simple_os.c:.* +EVT_LAST_STAGE_INIT install_smbios_table .*lib/efi_loader/efi_smbios.c:.* EVT_MISC_INIT_F sandbox_early_getopt_check .*arch/sandbox/cpu/start.c:.* EVT_TEST h_adder_simple .*test/common/event.c:''' assert re.match(expect, out, re.MULTILINE) is not None -- cgit v1.2.3