From patchwork Fri Feb 13 20:24:10 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Simon Glass X-Patchwork-Id: 1852 Return-Path: X-Original-To: u-boot-concept@u-boot.org Delivered-To: u-boot-concept@u-boot.org DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=u-boot.org; s=default; t=1771014300; bh=aVrtMblhkPnvaJ2MMyWIlresXOsy8vBZ3rRa/umWgoM=; h=From:To:Date:In-Reply-To:References:CC:Subject:List-Id: List-Archive:List-Help:List-Owner:List-Post:List-Subscribe: List-Unsubscribe:From; b=elKus2f3168DppKdKUfAgoANZBZfmrNvDZCtu2aRvll0L0zA1FETo4N+fO4VvHw86 nhu676FUw4p9VGX2aHTM1tL0fHCTPYLj/AeWplYe/r7G6UUBu0t/sDcerk3a3RelWl aMZU0vrh0MrRsl0h8jdLeliM20/Mn6+llRTg19gWCt2fANphj/9E4xouDqf41+dwz2 Ff2tRp0GBOlqj4P7FsOwOdP8qtsU3OZIynCuFD2bDNhakgM0bACKwtLyEj7JpfiaQQ xptpXKmcpsYrN9JV89PdjO4ARUj6/2s3o+NHHC8tqPk90DZK1U5A7bBx/8iOChEFp9 PAeaN7/gbl9Hg== Received: from localhost (localhost [127.0.0.1]) by mail.u-boot.org (Postfix) with ESMTP id 14F9769A66 for ; Fri, 13 Feb 2026 13:25:00 -0700 (MST) X-Virus-Scanned: Debian amavis at Received: from mail.u-boot.org ([127.0.0.1]) by localhost (mail.u-boot.org [127.0.0.1]) (amavis, port 10024) with ESMTP id 1MLetGhATRvh for ; Fri, 13 Feb 2026 13:25:00 -0700 (MST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=u-boot.org; s=default; t=1771014300; bh=aVrtMblhkPnvaJ2MMyWIlresXOsy8vBZ3rRa/umWgoM=; h=From:To:Date:In-Reply-To:References:CC:Subject:List-Id: List-Archive:List-Help:List-Owner:List-Post:List-Subscribe: List-Unsubscribe:From; b=elKus2f3168DppKdKUfAgoANZBZfmrNvDZCtu2aRvll0L0zA1FETo4N+fO4VvHw86 nhu676FUw4p9VGX2aHTM1tL0fHCTPYLj/AeWplYe/r7G6UUBu0t/sDcerk3a3RelWl aMZU0vrh0MrRsl0h8jdLeliM20/Mn6+llRTg19gWCt2fANphj/9E4xouDqf41+dwz2 Ff2tRp0GBOlqj4P7FsOwOdP8qtsU3OZIynCuFD2bDNhakgM0bACKwtLyEj7JpfiaQQ xptpXKmcpsYrN9JV89PdjO4ARUj6/2s3o+NHHC8tqPk90DZK1U5A7bBx/8iOChEFp9 PAeaN7/gbl9Hg== Received: from mail.u-boot.org (localhost [127.0.0.1]) by mail.u-boot.org (Postfix) with ESMTP id 001DE69B2D for ; Fri, 13 Feb 2026 13:24:59 -0700 (MST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=u-boot.org; s=default; t=1771014297; bh=kjJE+RrnjWHJpzfku4UsfGsrjeOwkNUme1bPehRexRo=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=vaYZecXNDe3re1U7I4F1Y09SK581W2hz/ypucdLspJPH2H7SbWYUwPdLhYhv7Uizh 3pDwrHjtQOCwCmi/dSN+zNmQGo/ol7NebRHkVUAD8qJ0FeNosqDax9p2F+o17CHAM4 N1B1WcuYsIZmqsonngA8WYZaW5ewaGNnNZaRB4B50qlGxO8fk7xRpiQAEQtqdmzxIR 1Wc+iHyhCgEuH+XiEa+mR1IBMZHQ5koS7mE6u/3ZgGwblkB5sXX6k+IhwP0WZUGNFi 65Sn7rPmbW4SDA00C0j3rvHX42zto+Y2Iub6DjBKuqstsnGKtNGQ4tbKCMekCPK49x NT1UVrNHbj6sg== Received: from localhost (localhost [127.0.0.1]) by mail.u-boot.org (Postfix) with ESMTP id DB79B69B2D; Fri, 13 Feb 2026 13:24:57 -0700 (MST) X-Virus-Scanned: Debian amavis at Received: from mail.u-boot.org ([127.0.0.1]) by localhost (mail.u-boot.org [127.0.0.1]) (amavis, port 10026) with ESMTP id UzJzddghFbyR; Fri, 13 Feb 2026 13:24:57 -0700 (MST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=u-boot.org; s=default; t=1771014292; bh=sf8+GliADNEFARWgxc27ONZ8SIPAmYwcIgG2w5QF5E0=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=pd0OyOYm9WNA3VTU3p+sQzggcw0ji4P39+zTRL6oVAzZCGh6BppZI7NYZSfUoLaTh H5knsiiHiv12EkwdBYrBisXpLyrkNDKa4ujxESDc4zWwy5mnVzTRBdlAeU9Wft21Kg UNSQ4SUtIVa5ngVaejywk4uHz+0iHwIbd3YpR5AE8MGQ8aGiYS/LuO98OnUuxn1w7Y BJuKz2ARbcENYnBEi7yguVz38U6bnKcHMyweLJ60htDSV1l8Mhuo6fWWmS/oP2ysAW hRE5QACgHdAhX+6aOANvPA4TCW5sDTNMLP/V3XgNSbQ0KYY7nU4zc395lgTXXW4iM+ iHT95P5UlEr5Q== Received: from u-boot.org (unknown [73.34.74.121]) by mail.u-boot.org (Postfix) with ESMTPSA id 903E569A66; Fri, 13 Feb 2026 13:24:52 -0700 (MST) From: Simon Glass To: U-Boot Concept Date: Fri, 13 Feb 2026 13:24:10 -0700 Message-ID: <20260213202417.223068-6-sjg@u-boot.org> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260213202417.223068-1-sjg@u-boot.org> References: <20260213202417.223068-1-sjg@u-boot.org> MIME-Version: 1.0 Message-ID-Hash: PBSEUYLXZ66WXYZX73ZKDU7CHBTBQTFS X-Message-ID-Hash: PBSEUYLXZ66WXYZX73ZKDU7CHBTBQTFS X-MailFrom: sjg@u-boot.org X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; loop; banned-address; emergency; member-moderation; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; digests; suspicious-header CC: Simon Glass , "Claude Sonnet 4 . 5" X-Mailman-Version: 3.3.10 Precedence: list Subject: [Concept] [PATCH 5/8] test: Add bootflow test for BLS bootmethod List-Id: Discussion and patches related to U-Boot Concept Archived-At: List-Archive: List-Help: List-Owner: List-Post: List-Subscribe: List-Unsubscribe: From: Simon Glass Add a test that verifies the BLS bootmethod can discover and boot from a Boot Loader Specification entry file. The test creates a disk image (mmc15) with a BLS entry at loader/entry.conf and verifies that bootflow scan finds it and reports it correctly. Test coverage: - Disk image creation with BLS entry format - Bootflow discovery via 'bootflow scan' - Bootflow listing and info display - Integration with standard bootdev framework The disk image setup creates a minimal BLS Type #1 entry with kernel, initrd, devicetree, and boot options. Co-developed-by: Claude Sonnet 4.5 Signed-off-by: Simon Glass --- arch/sandbox/dts/test.dts | 7 ++++ test/boot/bootflow.c | 54 ++++++++++++++++++++++++++++++ test/py/img/bls.py | 70 +++++++++++++++++++++++++++++++++++++++ test/py/tests/test_ut.py | 2 ++ 4 files changed, 133 insertions(+) create mode 100644 test/py/img/bls.py diff --git a/arch/sandbox/dts/test.dts b/arch/sandbox/dts/test.dts index 33c25014e94..90167567757 100644 --- a/arch/sandbox/dts/test.dts +++ b/arch/sandbox/dts/test.dts @@ -1296,6 +1296,13 @@ filename = "mmc14.img"; }; + /* This is used for BLS tests */ + mmc15 { + status = "disabled"; + compatible = "sandbox,mmc"; + filename = "mmc15.img"; + }; + pch { compatible = "sandbox,pch"; }; diff --git a/test/boot/bootflow.c b/test/boot/bootflow.c index 9a9cc68fa11..e1e50319740 100644 --- a/test/boot/bootflow.c +++ b/test/boot/bootflow.c @@ -36,6 +36,7 @@ DECLARE_GLOBAL_DATA_PTR; extern U_BOOT_DRIVER(bootmeth_android); extern U_BOOT_DRIVER(bootmeth_cros); extern U_BOOT_DRIVER(bootmeth_2script); +extern U_BOOT_DRIVER(bootmeth_2bls); /* Use this as the vendor for EFI to tell the app to exit boot services */ static u16 __efi_runtime_data test_vendor[] = u"U-Boot testing"; @@ -684,6 +685,13 @@ static int prep_mmc_bootdev(struct unit_test_state *uts, const char *mmc_dev, "android", 0, ofnode_null(), &dev)); } + /* Enable the BLS bootmeth if needed */ + if (IS_ENABLED(CONFIG_BOOTMETH_BLS) && bind_cros_android) { + ut_assertok(uclass_first_device_err(UCLASS_BOOTSTD, &bootstd)); + ut_assertok(device_bind(bootstd, DM_DRIVER_REF(bootmeth_2bls), + "bls", 0, ofnode_null(), &dev)); + } + /* Change the order to include the device */ std = dev_get_priv(bootstd); old_order = std->bootdev_order; @@ -1809,3 +1817,49 @@ static int bootflow_cmd_info_encrypted(struct unit_test_state *uts) return 0; } BOOTSTD_TEST(bootflow_cmd_info_encrypted, UTF_DM | UTF_SCAN_FDT | UTF_CONSOLE); + +/* Check 'bootflow scan' finds a BLS bootflow */ +static int bootflow_cmd_bls(struct unit_test_state *uts) +{ + struct bootstd_priv *std; + const char **old_order; + + ut_assertok(prep_mmc_bootdev(uts, "mmc15", true, &old_order)); + ut_assertok(run_command("bootflow scan", 0)); + ut_assert_console_end(); + + /* Restore the order used by the device tree */ + ut_assertok(bootstd_get_priv(&std)); + free(std->bootdev_order); + std->bootdev_order = old_order; + + ut_assertok(run_command("bootflow list", 0)); + ut_assert_nextline("Showing all bootflows"); + ut_assert_nextline("Seq Method State Uclass Part E Name Filename"); + ut_assert_nextlinen("---"); + ut_assert_nextlinen(" 0 extlinux"); + ut_assert_nextline(" 1 bls ready mmc 1 mmc15.bootdev.part_1 /loader/entry.conf"); + ut_assert_nextlinen("---"); + ut_assert_nextline("(2 bootflows, 2 valid)"); + ut_assert_console_end(); + + /* Select the BLS bootflow and check info */ + ut_assertok(run_command("bootflow select 1", 0)); + ut_assert_console_end(); + ut_assertok(run_command("bootflow info", 0)); + ut_assert_nextline("Name: mmc15.bootdev.part_1"); + ut_assert_nextline("Device: mmc15.bootdev"); + ut_assert_nextline("Block dev: mmc15.blk"); + ut_assert_nextline("Method: bls"); + ut_assert_nextline("State: ready"); + ut_assert_nextline("Partition: 1"); + if (IS_ENABLED(CONFIG_BLK_LUKS)) + ut_assert_nextline("Encrypted: no"); + ut_assert_nextline("Subdir: (none)"); + ut_assert_nextline("Filename: /loader/entry.conf"); + ut_assert_skip_to_line("Error: 0"); + ut_assert_console_end(); + + return 0; +} +BOOTSTD_TEST(bootflow_cmd_bls, UTF_DM | UTF_SCAN_FDT | UTF_CONSOLE); diff --git a/test/py/img/bls.py b/test/py/img/bls.py new file mode 100644 index 00000000000..0f55aad8ba5 --- /dev/null +++ b/test/py/img/bls.py @@ -0,0 +1,70 @@ +# SPDX-License-Identifier: GPL-2.0+ +# Copyright 2026 Canonical Ltd + +"""Create BLS test disk images""" + +import gzip +import os + +import utils +from fs_helper import DiskHelper, FsHelper +from img.common import mkdir_cond + + +def setup_bls_image(config, log, devnum, basename): + """Create a 20MB BLS disk image with a single FAT partition + + Args: + config (ArbitraryAttributeContainer): Configuration + log (multiplexed_log.Logfile): Log to write to + devnum (int): Device number to use, e.g. 5 + basename (str): Base name to use in the filename, e.g. 'mmc' + """ + vmlinux = 'vmlinuz-6.8.0' + initrd = 'initrd.img-6.8.0' + dtb = 'sandbox.dtb' + + # BLS Type #1 entry format + script = f'''title Test Boot +version 6.8.0 +linux /{vmlinux} +options root=/dev/mmcblk0p2 ro quiet +initrd /{initrd} +devicetree /{dtb}''' + + fsh = FsHelper(config, 'vfat', 18, prefix=basename) + fsh.setup() + + # Create loader directory for BLS entry + loader = os.path.join(fsh.srcdir, 'loader') + mkdir_cond(loader) + + # Create BLS entry file + conf = os.path.join(loader, 'entry.conf') + with open(conf, 'w', encoding='ascii') as fd: + print(script, file=fd) + + # Create compressed kernel image + inf = os.path.join(config.persistent_data_dir, 'inf') + with open(inf, 'wb') as fd: + fd.write(gzip.compress(b'vmlinux')) + mkimage = config.build_dir + '/tools/mkimage' + utils.run_and_log_no_ubman( + log, f'{mkimage} -f auto -d {inf} {os.path.join(fsh.srcdir, vmlinux)}') + + # Create initrd file + with open(os.path.join(fsh.srcdir, initrd), 'w', encoding='ascii') as fd: + print('initrd', file=fd) + + # Create device tree blob + dtb_file = os.path.join(fsh.srcdir, dtb) + utils.run_and_log_no_ubman( + log, f'dtc -o {dtb_file}', stdin=b'/dts-v1/; / {};') + + fsh.mk_fs() + + # Create disk image with single bootable partition + img = DiskHelper(config, devnum, basename) + img.add_fs(fsh, DiskHelper.VFAT, bootable=True) + img.create() + fsh.cleanup() diff --git a/test/py/tests/test_ut.py b/test/py/tests/test_ut.py index da36898d803..e64ccd407a0 100644 --- a/test/py/tests/test_ut.py +++ b/test/py/tests/test_ut.py @@ -23,6 +23,7 @@ from img.common import mkdir_cond, copy_partition, setup_extlinux_image from img.fedora import setup_fedora_image from img.ubuntu import setup_ubuntu_image from img.armbian import setup_bootmenu_image +from img.bls import setup_bls_image from img.chromeos import setup_cros_image from img.android import setup_android_image from img.efi import setup_efi_image @@ -79,6 +80,7 @@ def test_ut_dm_init_bootstd(u_boot_config, u_boot_log): u_boot_log (multiplexed_log.Logfile): Log to write to """ setup_fedora_image(u_boot_config, u_boot_log, 1, 'mmc') + setup_bls_image(u_boot_config, u_boot_log, 15, 'mmc') setup_bootmenu_image(u_boot_config, u_boot_log) setup_cedit_file(u_boot_config, u_boot_log) setup_cros_image(u_boot_config, u_boot_log)