From patchwork Thu Nov 20 02:55:40 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Simon Glass X-Patchwork-Id: 733 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=1763607405; bh=1O3+p872ws/0govTvOqzlqqUlVUcATL82rXwMdAMlKc=; 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=XFNi/kC/mFsU4sZk4HgBcFOgDjFdfjj4x56yh/w+xl2KcuSBEXM2pcnPjvxjumpqj giD8GLx8Ct5kZPNTrJgKcuSIaJBBwWHd2AhNPzTcrKEvqFaeZPXyxYEcTxQxU994GQ GljESL5ZuhkjzYI6cnIK7759EBnFbWngcHvAWoqUddSPCzxnEtKPh+UqFmgZT7gK+3 nzh9ZDULxz0pCBIrSQp3JzjqyO3E/WBfLTatXD6hqRFis1XwNX0P9uNuygpMFad67j 8ZXpg0eNKe0jTxU4bKOM3JEu8btF+tWPupiOmPMnK1sFY0UOGJxJSuZ4ngxYySI29v wJtsE69ldLc+g== Received: from localhost (localhost [127.0.0.1]) by mail.u-boot.org (Postfix) with ESMTP id 75C96686C9 for ; Wed, 19 Nov 2025 19:56:45 -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 w2vZU9P2XHAo for ; Wed, 19 Nov 2025 19:56:45 -0700 (MST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=u-boot.org; s=default; t=1763607403; bh=1O3+p872ws/0govTvOqzlqqUlVUcATL82rXwMdAMlKc=; 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=Mf0KsmvNvl8mwlFKurg4mkqXdNBbl2YmxH81VHOn+BXriwGtFKTfW2pS4EcHYO1yi tP2M10XYLKSlJ1NAuqP7rCGP2TP8ifm2tI2mmMpYM+n7Cy65iD00Q0xbeAiR6oQDFL bP/ziUHKvxKZ70dNEtX6k727jENo5WSaq6YoVYDEJb1MttEVN3LDnWnEbgdQDwB7d8 U8kChDAxxkJwAdXGN09JPjoIEP/9xskou0NfHvyL7Q37wuV5NfC2N+mOC/W3DZGSak NhWfagSd7bOPH1WUpA4ehsxkAevhWk6CoMm17bx+Nmb1Ec5c2p+n8eP7VfhmfAPQIu qWL/6h05i4Srw== Received: from mail.u-boot.org (localhost [127.0.0.1]) by mail.u-boot.org (Postfix) with ESMTP id C8823686DF for ; Wed, 19 Nov 2025 19:56:43 -0700 (MST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=u-boot.org; s=default; t=1763607401; bh=/JszXojwMAVMkZI49rPulBGtXH4anMxI0x6B1Uxum/c=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=u3Fa/qQBWPCJQWnHXvq3gRVn4KZtWoStF99V8zbSDw/JlRxv9jaI8pyj133FgbdC8 Emj2gZmxyzLnC8bucyM4gSezEudafg/DQOrLFsG9oPeNctsIrxWgVSff5wj786/bqz BoOY0rNCsT5fE5jUTLyiPCWVgNk3MSFnqbXTgOIibXN9yx4aPLLDmft51xI1FUt/SU 1EFFV4YzKVzufi1zMu8O67iZZt+RohEo6t83mUGc+FPTIEjDCUbmrres9bAVsvieGL G/ZMN/pV8uuS/LOM2W0mg+LI6if1o3pia99RzoimyJ4eZnPCq84lIsh5lWkYhwvdQS AFvb6vSTxYFEQ== Received: from localhost (localhost [127.0.0.1]) by mail.u-boot.org (Postfix) with ESMTP id 670FA68631; Wed, 19 Nov 2025 19:56:41 -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 CDzro0QFbPsg; Wed, 19 Nov 2025 19:56:41 -0700 (MST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=u-boot.org; s=default; t=1763607400; bh=nI9ToTo9pI/qELJUfk9w6tRf8x1GFghGMsQh+e8vPyc=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=MP0YueAxN2ZPogU5oyOJucUEmL1Q2A8jXoXM2e3WZUKdZ8dWdwRclMO8pS0WrbOk9 MCjq8NOaCHqtxtoXrKyetIxasA2HQUiPgT8Ot73LRR40qonDWurFuegvewMBYench0 hxXFfIzWlXLvkLS/nWbdvB8Ab6dobzQuHtHyMd1u47ZB+3MjSYyISwzLvHHljN6Dlb tQfgY8wyoc3BWN0ZWyF6ODOQTSri4Mu/jRiSa6PDXLsIaiWxfcrB6D+ZSleYiHGA/w BqFQnySP30vaCzb6CaS+JHa90ZEHPh4/EZr+ajH0jGYmru8mZkhiXL+QRd/DL18VGP BDFwdkY7kP4XQ== Received: from u-boot.org (unknown [73.34.74.121]) by mail.u-boot.org (Postfix) with ESMTPSA id 7A6215E7DA; Wed, 19 Nov 2025 19:56:40 -0700 (MST) From: Simon Glass To: U-Boot Concept Date: Wed, 19 Nov 2025 19:55:40 -0700 Message-ID: <20251120025614.2215587-6-sjg@u-boot.org> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20251120025614.2215587-1-sjg@u-boot.org> References: <20251120025614.2215587-1-sjg@u-boot.org> MIME-Version: 1.0 Message-ID-Hash: ZTKMNGG7U234WPLQ22WD4A3LKW5WBBYS X-Message-ID-Hash: ZTKMNGG7U234WPLQ22WD4A3LKW5WBBYS 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 X-Mailman-Version: 3.3.10 Precedence: list Subject: [Concept] [PATCH 05/30] test: Add a test for FIT image printing 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 The code for printing FITs is quite messy, with lots of separate printf() calls, an indentation string, etc. It also has no tests. In preparation for refactoring this code, add a test. Use Python code to create the test image and C code to test it. The test covers FIT description, image details (type, architecture, OS, addresses), and configuration details. Co-developed-by: Claude Signed-off-by: Simon Glass --- test/boot/Makefile | 1 + test/boot/fit_print.c | 93 +++++++++++++++++++++++++ test/py/tests/test_fit_print.py | 120 ++++++++++++++++++++++++++++++++ 3 files changed, 214 insertions(+) create mode 100644 test/boot/fit_print.c create mode 100644 test/py/tests/test_fit_print.py diff --git a/test/boot/Makefile b/test/boot/Makefile index 71c482f8d24..70e15bf63fa 100644 --- a/test/boot/Makefile +++ b/test/boot/Makefile @@ -5,6 +5,7 @@ ifdef CONFIG_UT_BOOTSTD obj-$(CONFIG_BOOTSTD) += bootdev.o bootstd_common.o bootflow.o bootmeth.o obj-$(CONFIG_FIT) += image.o +obj-$(CONFIG_$(PHASE_)FIT_PRINT) += fit_print.o obj-$(CONFIG_BLK_LUKS) += luks.o obj-$(CONFIG_EXPO) += expo.o expo_common.o diff --git a/test/boot/fit_print.c b/test/boot/fit_print.c new file mode 100644 index 00000000000..ef1e86800ee --- /dev/null +++ b/test/boot/fit_print.c @@ -0,0 +1,93 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Test for FIT image printing + * + * Copyright 2025 Canonical Ltd + * Written by Simon Glass + */ + +#include +#include +#include +#include +#include +#include "bootstd_common.h" + +/* Test fit_print_contents() output */ +static int test_fit_print_norun(struct unit_test_state *uts) +{ + char fname[256]; + void *fit; + void *buf; + ulong addr; + int size; + + /* Load the FIT created by the Python test */ + ut_assertok(os_persistent_file(fname, sizeof(fname), "test-fit.fit")); + ut_assertok(os_read_file(fname, &buf, &size)); + + /* Copy to address 0x10000 and print from there */ + addr = 0x10000; + fit = map_sysmem(addr, size); + memcpy(fit, buf, size); + + /* Print it and check output line by line */ + console_record_reset_enable(); + fit_print_contents(fit); + + /* Check every line of output */ + ut_assert_nextline(" FIT description: Test FIT image for printing"); + ut_assert_nextline(" Created: 2009-02-13 23:31:30 UTC"); + ut_assert_nextline(" Image 0 (kernel)"); + ut_assert_nextline(" Description: Test kernel"); + ut_assert_nextline(" Created: 2009-02-13 23:31:30 UTC"); + ut_assert_nextline(" Type: Kernel Image"); + ut_assert_nextline(" Compression: gzip compressed"); + ut_assert_nextline(" Data Start: 0x000100c4"); + ut_assert_nextline(" Data Size: 327 Bytes = 327 Bytes"); + ut_assert_nextline(" Architecture: Sandbox"); + ut_assert_nextline(" OS: Linux"); + ut_assert_nextline(" Load Address: 0x01000000"); + ut_assert_nextline(" Entry Point: 0x01000000"); + ut_assert_nextline(" Hash algo: sha256"); + ut_assert_nextline(" Hash value: fad998b94ef12fdac0c347915d8b9b6069a4011399e1a2097638a2cb33244cee"); + ut_assert_nextline(" Image 1 (ramdisk)"); + ut_assert_nextline(" Description: Test ramdisk"); + ut_assert_nextline(" Created: 2009-02-13 23:31:30 UTC"); + ut_assert_nextline(" Type: RAMDisk Image"); + ut_assert_nextline(" Compression: uncompressed"); + ut_assert_nextline(" Data Start: 0x00010304"); + ut_assert_nextline(" Data Size: 301 Bytes = 301 Bytes"); + ut_assert_nextline(" Architecture: Sandbox"); + ut_assert_nextline(" OS: Linux"); + ut_assert_nextline(" Load Address: 0x02000000"); + ut_assert_nextline(" Entry Point: unavailable"); + ut_assert_nextline(" Hash algo: sha256"); + ut_assert_nextline(" Hash value: 53e2a65d92ad890dcd89d83a1f95ad6b8206e0e4889548b035062fc494e7f655"); + ut_assert_nextline(" Image 2 (fdt)"); + ut_assert_nextline(" Description: Test FDT"); + ut_assert_nextline(" Created: 2009-02-13 23:31:30 UTC"); + ut_assert_nextline(" Type: Flat Device Tree"); + ut_assert_nextline(" Compression: uncompressed"); + ut_assert_nextline(" Data Start: 0x00010514"); + ut_assert_nextline(" Data Size: 157 Bytes = 157 Bytes"); + ut_assert_nextline(" Architecture: Sandbox"); + ut_assert_nextline(" Hash algo: sha256"); + ut_assert_nextline(" Hash value: 51918524b06745cae06331047c7e566909431bf71338e5f703dffba1823274f4"); + ut_assert_nextline(" Default Configuration: 'conf-1'"); + ut_assert_nextline(" Configuration 0 (conf-1)"); + ut_assert_nextline(" Description: Test configuration"); + ut_assert_nextline(" Kernel: kernel"); + ut_assert_nextline(" Init Ramdisk: ramdisk"); + ut_assert_nextline(" FDT: fdt"); + ut_assert_nextline(" Configuration 1 (conf-2)"); + ut_assert_nextline(" Description: Alternate configuration"); + ut_assert_nextline(" Kernel: kernel"); + ut_assert_nextline(" FDT: fdt"); + ut_assert_console_end(); + + os_free(buf); + + return 0; +} +BOOTSTD_TEST(test_fit_print_norun, UTF_CONSOLE | UTF_MANUAL); diff --git a/test/py/tests/test_fit_print.py b/test/py/tests/test_fit_print.py new file mode 100644 index 00000000000..4960ce503b4 --- /dev/null +++ b/test/py/tests/test_fit_print.py @@ -0,0 +1,120 @@ +# SPDX-License-Identifier: GPL-2.0+ +# Copyright 2025 Canonical Ltd +# Written by Simon Glass + +"""Test for FIT image printing""" + +import os + +import pytest + +import fit_util +import utils + +# ITS for testing FIT printing with hashes, ramdisk, and multiple configs +PRINT_ITS = ''' +/dts-v1/; + +/ { + description = "Test FIT image for printing"; + #address-cells = <1>; + + images { + kernel { + description = "Test kernel"; + data = /incbin/("%(kernel)s"); + type = "kernel"; + arch = "sandbox"; + os = "linux"; + compression = "gzip"; + load = <0x1000000>; + entry = <0x1000000>; + hash-1 { + algo = "sha256"; + }; + }; + ramdisk { + description = "Test ramdisk"; + data = /incbin/("%(ramdisk)s"); + type = "ramdisk"; + arch = "sandbox"; + os = "linux"; + compression = "none"; + load = <0x2000000>; + hash-1 { + algo = "sha256"; + }; + }; + fdt { + description = "Test FDT"; + data = /incbin/("%(fdt)s"); + type = "flat_dt"; + arch = "sandbox"; + compression = "none"; + hash-1 { + algo = "sha256"; + }; + }; + }; + configurations { + default = "conf-1"; + conf-1 { + description = "Test configuration"; + kernel = "kernel"; + fdt = "fdt"; + ramdisk = "ramdisk"; + }; + conf-2 { + description = "Alternate configuration"; + kernel = "kernel"; + fdt = "fdt"; + }; + }; +}; +''' + +@pytest.mark.boardspec('sandbox') +@pytest.mark.buildconfigspec('fit_print') +@pytest.mark.requiredtool('dtc') +def test_fit_print(ubman): + """Test fit_print_contents() via C unit test""" + mkimage = os.path.join(ubman.config.build_dir, 'tools/mkimage') + + # Create test files (make kernel ~6.3K) + kernel = fit_util.make_kernel(ubman, 'test-kernel.bin', + 'kernel with some extra test data') + + # Compress the kernel (with -n to avoid timestamps for reproducibility) + kernel_gz = kernel + '.gz' + utils.run_and_log(ubman, ['gzip', '-f', '-n', '-k', kernel]) + + fdt = fit_util.make_dtb(ubman, ''' +/dts-v1/; +/ { + #address-cells = <1>; + #size-cells = <0>; + model = "Test"; +}; +''', 'test-fdt') + ramdisk = fit_util.make_kernel(ubman, 'test-ramdisk.bin', 'ramdisk') + + # Compress the ramdisk (with -n to avoid timestamps for reproducibility) + ramdisk_gz = ramdisk + '.gz' + utils.run_and_log(ubman, ['gzip', '-f', '-n', '-k', ramdisk]) + + # Create FIT image with fixed timestamp for reproducible output + params = { + 'kernel': kernel_gz, + 'fdt': fdt, + 'ramdisk': ramdisk_gz, + } + env = os.environ.copy() + env['SOURCE_DATE_EPOCH'] = '1234567890' # 2009-02-13 23:31:30 UTC + fit = os.path.join(ubman.config.persistent_data_dir, 'test-fit.fit') + its = fit_util.make_its(ubman, PRINT_ITS, params) + utils.run_and_log(ubman, [mkimage, '-f', its, fit], env=env) + + # Run the C test which will load and verify this FIT + ubman.run_command('ut -f bootstd test_fit_print_norun') + result = ubman.run_command('echo $?') + assert '0' == result