From patchwork Fri Jan 9 23:11:17 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Simon Glass X-Patchwork-Id: 1404 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=1768000371; bh=Z9gIqsSNFxbutY5PcC3gRvzn+V4Ob4Zzxm/XW0WBwEY=; 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=YVv/rJunbSak37D1RI+Sb4IhYWg769V7QB6EaeCSzKvYLWtcm66DuWXodBkla0pMC M8CmiA0K0MiiJF3XYd1cMbJt361hxkVL2YVX6yVt5aI958rZcyvmNikQlzxVNFUc0d 9kQ4XHwiCaak+MmuCcfJljqCdczktAX+PjNIR4tmGj/AM239w4ljQjJnF+iTrCQVxf niJtzY6ZV3vQcWnJXUR8VVQYFicT/PB/yZgOyqbehSXVFTIas7MB7snw0uCS5LEMaU gl85mYs8IwZ1Z7w7uINQoUchrBw+5dHg7S+w9oyAO9AHnNprw5YZzorpmvZYjaC9ru nsXrf6+FgAYIA== Received: from localhost (localhost [127.0.0.1]) by mail.u-boot.org (Postfix) with ESMTP id AF2456923D for ; Fri, 9 Jan 2026 16:12:51 -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 d-WDRy5L0hnZ for ; Fri, 9 Jan 2026 16:12:51 -0700 (MST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=u-boot.org; s=default; t=1768000371; bh=Z9gIqsSNFxbutY5PcC3gRvzn+V4Ob4Zzxm/XW0WBwEY=; 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=YVv/rJunbSak37D1RI+Sb4IhYWg769V7QB6EaeCSzKvYLWtcm66DuWXodBkla0pMC M8CmiA0K0MiiJF3XYd1cMbJt361hxkVL2YVX6yVt5aI958rZcyvmNikQlzxVNFUc0d 9kQ4XHwiCaak+MmuCcfJljqCdczktAX+PjNIR4tmGj/AM239w4ljQjJnF+iTrCQVxf niJtzY6ZV3vQcWnJXUR8VVQYFicT/PB/yZgOyqbehSXVFTIas7MB7snw0uCS5LEMaU gl85mYs8IwZ1Z7w7uINQoUchrBw+5dHg7S+w9oyAO9AHnNprw5YZzorpmvZYjaC9ru nsXrf6+FgAYIA== Received: from mail.u-boot.org (localhost [127.0.0.1]) by mail.u-boot.org (Postfix) with ESMTP id 9E19569235 for ; Fri, 9 Jan 2026 16:12:51 -0700 (MST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=u-boot.org; s=default; t=1768000368; bh=GC/NxxvA1bSlE/KfbHHn1eoIqS+AfLECIXXrzX7XP48=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=u37qijx6TCU49045h7LPI1pH7t2Fv3JKfBszN1NcSSKORQa6ynuDI5ljLpMla+iRQ dMmBzbxE2C3BP4iLKHSy9unpYaPdDr55Z9YGZDbcT3EXKu1MpnIR6qUAU79xLDFU2T +vBX/1YUweXh4QTUfQeBDwrEG1sYAwYSOtvVI61ulRW0u8oblFaKtQOQbeV7tkH8xj ZpMNzrGLAkXZymQLdZOyOnV/tF3qV/cy90ijIPk0TTjTgN7NR4qA+nmt/18lWZTC8B MCdaBXWQI45dN9ubLdP5gXiaayjcLx8B3hg3sI7Clf74mRrxrfIFI5sSFZ3YEsAnnp So2h2BTGwk3tA== Received: from localhost (localhost [127.0.0.1]) by mail.u-boot.org (Postfix) with ESMTP id BDD3569218; Fri, 9 Jan 2026 16:12:48 -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 ZIhHm769xkuB; Fri, 9 Jan 2026 16:12:48 -0700 (MST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=u-boot.org; s=default; t=1768000364; bh=5N3sC/p6BDPZqnq0u9HIdwO2X1oo+23N46X0OUvhxE8=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=FRNLWwOa75IJdUq5yCManMsmvPkDX8IY65Ye4OTDdS+4pD8qZpw2xnrdI2D4apocB vsHRCA8yL5Ho5pMbrlrL2yYDRG95kMq8z4LLnahEoYvTksJD0qWfqE0x2w2S9xqyl+ 9A7mpfIuP35llTcZCvsUGpzibn6DT26NVxDPrBjCMCUnLjCKbKX4esIZwKaboI/Xzn zDOKpq7Rs6D3zUeEwenJld8jJEkAQjTL/ms0tRg5aLADBuVKU/wbcgkZP5VQDd8tXM 0ixNC3JxyQKfqURa1uDyhxfPcAPgITjr/98pT0ChU9uffxxvTGQPaKGUm1KFzMTDH7 3Z7OgV8RoqLZg== Received: from u-boot.org (unknown [73.34.74.121]) by mail.u-boot.org (Postfix) with ESMTPSA id 3ACAF69206; Fri, 9 Jan 2026 16:12:44 -0700 (MST) From: Simon Glass To: U-Boot Concept Date: Fri, 9 Jan 2026 16:11:17 -0700 Message-ID: <20260109231151.4056804-9-sjg@u-boot.org> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260109231151.4056804-1-sjg@u-boot.org> References: <20260109231151.4056804-1-sjg@u-boot.org> MIME-Version: 1.0 Message-ID-Hash: 3D7565VQ2ZYHZVFABPPLDFJR7VD3XJRM X-Message-ID-Hash: 3D7565VQ2ZYHZVFABPPLDFJR7VD3XJRM 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: Heinrich Schuchardt , Simon Glass , "Claude Opus 4 . 5" X-Mailman-Version: 3.3.10 Precedence: list Subject: [Concept] [PATCH 08/32] test: pxe: Add test for FIT images with embedded FDT 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 handling of FIT images containing an embedded FDT when the extlinux.conf uses the 'fit' keyword without an explicit 'fdt' line. The test creates a FIT image with an embedded DTB using mkimage, then loads a label that references it via 'fit /boot/image.fit'. It verifies that ctx.conf_fdt_str is NULL (the current behaviour for this case). Note: Ideally conf_fdt_str should be set to the FIT address so bootm can extract the FDT, but that is a pre-existing limitation. This test detects regressions where conf_fdt_str is incorrectly set to fdt_addr_r instead of NULL. Co-developed-by: Claude Opus 4.5 Signed-off-by: Simon Glass --- test/boot/pxe.c | 91 ++++++++++++++++++++++++++++++++ test/py/tests/test_pxe_parser.py | 69 ++++++++++++++++++++++++ 2 files changed, 160 insertions(+) diff --git a/test/boot/pxe.c b/test/boot/pxe.c index 46b26496fbd..4c87aafce55 100644 --- a/test/boot/pxe.c +++ b/test/boot/pxe.c @@ -1166,3 +1166,94 @@ static int pxe_test_alloc_norun(struct unit_test_state *uts) PXE_TEST_ARGS(pxe_test_alloc_norun, UTF_CONSOLE | UTF_MANUAL, { "fs_image", UT_ARG_STR }, { "cfg_path", UT_ARG_STR }); + +/** + * Test FIT image with embedded FDT (no explicit fdt line) + * + * This tests that when using 'fit /path.fit' without an explicit 'fdt' + * line (label->fdt is NULL), the FDT address is set to the FIT address + * so bootm can extract the FDT from the FIT image. + * + * The buggy behavior: When label->fdt is NULL, the FIT check fails: + * if (label->fdt && label->kernel_label && + * !strcmp(label->kernel_label, label->fdt)) + * and conf_fdt_str is not set to the FIT address. + * + * The correct behavior: When the kernel is a FIT image with embedded FDT + * and no explicit fdt line is provided, conf_fdt_str should be set to + * the kernel (FIT) address so bootm can extract the FDT. + */ +static int pxe_test_fit_embedded_fdt_norun(struct unit_test_state *uts) +{ + const char *fs_image = ut_str(PXE_ARG_FS_IMAGE); + const char *cfg_path = ut_str(PXE_ARG_CFG_PATH); + struct pxe_test_info info; + struct pxe_context ctx; + struct pxe_label *label; + struct pxe_menu *cfg; + ulong addr = PXE_LOAD_ADDR; + + ut_assertnonnull(fs_image); + ut_assertnonnull(cfg_path); + + info.uts = uts; + + /* Bind the filesystem image */ + ut_assertok(run_commandf("host bind 0 %s", fs_image)); + + /* Set up the PXE context */ + ut_assertok(pxe_setup_ctx(&ctx, pxe_test_getfile, &info, true, cfg_path, + false, false, NULL)); + + /* Set up environment for loading */ + ut_assertok(env_set_hex("kernel_addr_r", PXE_KERNEL_ADDR)); + ut_assertok(env_set_hex("fdt_addr_r", PXE_FDT_ADDR)); + + /* Read and parse the config file */ + ut_asserteq(1, get_pxe_file(&ctx, cfg_path, addr)); + + cfg = parse_pxefile(&ctx, addr); + ut_assertnonnull(cfg); + + /* Consume parsing output */ + ut_assert_nextline("Retrieving file: %s", cfg_path); + ut_assert_console_end(); + + /* Get the fitonly label which uses 'fit' without 'fdt' */ + label = list_first_entry(&cfg->labels, struct pxe_label, list); + ut_asserteq_str("fitonly", label->name); + + /* Verify this is a FIT label with no explicit fdt */ + ut_assertnonnull(label->kernel); /* /boot/image.fit */ + ut_assertnull(label->config); /* NULL when no #config suffix */ + ut_assertnull(label->fdt); /* No explicit fdt line - this is key */ + + /* Load the label */ + ut_assertok(pxe_load_label(&ctx, label)); + + /* Consume load output */ + ut_assert_nextline("Retrieving file: /boot/image.fit"); + ut_assert_console_end(); + + /* + * For FIT images with embedded FDT and no explicit fdt line, + * conf_fdt_str is currently NULL. Ideally it should be set to the + * kernel address so bootm can extract the FDT from the FIT, but + * that is a pre-existing limitation. + * + * This test detects regressions where conf_fdt_str is incorrectly + * set to fdt_addr_r instead of NULL (which would cause bootm to + * look at the wrong address for the FDT). + */ + ut_assertnull(ctx.conf_fdt_str); + ut_asserteq(0, ctx.conf_fdt); + + /* Clean up */ + destroy_pxe_menu(cfg); + pxe_destroy_ctx(&ctx); + + return 0; +} +PXE_TEST_ARGS(pxe_test_fit_embedded_fdt_norun, UTF_CONSOLE | UTF_MANUAL, + { "fs_image", UT_ARG_STR }, + { "cfg_path", UT_ARG_STR }); diff --git a/test/py/tests/test_pxe_parser.py b/test/py/tests/test_pxe_parser.py index b728fb86946..af97568e960 100644 --- a/test/py/tests/test_pxe_parser.py +++ b/test/py/tests/test_pxe_parser.py @@ -11,11 +11,14 @@ Tests are implemented in C (test/boot/pxe.c) and called from here. Python handles filesystem image setup and configuration. """ +import gzip import os import pytest import subprocess +import tempfile from fs_helper import FsHelper +import utils # Simple base DTS with symbols enabled (for overlay support) @@ -400,6 +403,60 @@ def pxe_error_image(u_boot_config): fsh.cleanup() +@pytest.fixture +def pxe_fit_image(u_boot_config, u_boot_log): + """Create a filesystem image with a FIT image containing embedded FDT + + This tests that when using the 'fit' keyword without an explicit 'fdt' + line, the FDT is extracted from the FIT image. This is the scenario where + label->fdt is NULL but the kernel is a FIT containing an embedded FDT. + """ + fsh = FsHelper(u_boot_config, 'vfat', 4, prefix='pxe_fit') + fsh.setup() + + # Create a FIT image with embedded FDT using mkimage + mkimage = u_boot_config.build_dir + '/tools/mkimage' + boot_dir = os.path.join(fsh.srcdir, 'boot') + os.makedirs(boot_dir, exist_ok=True) + + with tempfile.TemporaryDirectory(suffix='pxe_fit') as tmp: + # Create a fake gzipped kernel + kern = os.path.join(tmp, 'kern') + with open(kern, 'wb') as fd: + fd.write(gzip.compress(b'vmlinux-test')) + + # Create a DTB for the FIT + dtb = os.path.join(tmp, 'board.dtb') + compile_dts(BASE_DTS, dtb) + + # Create FIT image with embedded DTB + fit = os.path.join(boot_dir, 'image.fit') + subprocess.run( + f'{mkimage} -f auto -T kernel -A sandbox -O linux ' + f'-d {kern} -b {dtb} {fit}', + shell=True, check=True, capture_output=True) + + # Create extlinux.conf using 'fit' keyword without 'fdt' line + # This is the key test case: label->fdt is NULL, but FIT has embedded FDT + labels = [ + { + 'name': 'fitonly', + 'menu': 'FIT Boot (no explicit fdt)', + 'fit': '/boot/image.fit', + 'append': 'console=ttyS0', + 'default': True, + }, + ] + + cfg_path = create_extlinux_conf(fsh.srcdir, labels) + fsh.mk_fs() + + yield fsh.fs_img, cfg_path + + if not u_boot_config.persist: + fsh.cleanup() + + @pytest.mark.boardspec('sandbox') @pytest.mark.requiredtool('dtc') class TestPxeParser: @@ -467,3 +524,15 @@ class TestPxeParser: with ubman.log.section('Test PXE overlay no addr'): ubman.run_ut('pxe', 'pxe_test_overlay_no_addr', fs_image=fs_img, cfg_path=cfg_path) + + def test_pxe_fit_embedded_fdt(self, ubman, pxe_fit_image): + """Test FIT image with embedded FDT (no explicit fdt line) + + This tests that when using 'fit /path.fit' without an explicit 'fdt' + line, the FDT address is set to the FIT address so bootm can extract + the FDT from the FIT image. + """ + fs_img, cfg_path = pxe_fit_image + with ubman.log.section('Test PXE FIT embedded FDT'): + ubman.run_ut('pxe', 'pxe_test_fit_embedded_fdt', + fs_image=fs_img, cfg_path=cfg_path)