From patchwork Fri Apr 3 14:04:47 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Simon Glass X-Patchwork-Id: 2109 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=1775225195; bh=s1edS834cRKpw4uzuZk2uGH7WTfeAOD2UkgkcVQ4b68=; 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=GlDg9h/hRqh2CzqMvpyiQsXcvJUzSGWlBUSoOK0DRIXO5xZ9LkqzMhW66NS+UAFpF TrD7dDl/tBZUUY8ovRwBQlv2qRlwZ3JX1O34gnNFtojvpW+pma+XwdlHRaaUMBelhk 0lDhKhm+WxCrQ4c12osbw+l2hXEyyjlRrwdjp8vTIzUv5T+Yp4fFTG1kAAEumoChSW tirEehlblBlslSCVl5KLICWFT+EIZKYDbVHsALiKdfdhz4eBfhTqX63yBdOb6nkR+9 26aK5OT5f8uxpPbx3DbA4ZTG+omEPYb6WDurwAWfoZR8b1ROJV8KoFWAiGGbF1zdqt p+59f9fv3zqSg== Received: from localhost (localhost [127.0.0.1]) by mail.u-boot.org (Postfix) with ESMTP id EEFDD6A34F for ; Fri, 3 Apr 2026 08:06:35 -0600 (MDT) 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 Ykc-IOoA9rjp for ; Fri, 3 Apr 2026 08:06:35 -0600 (MDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=u-boot.org; s=default; t=1775225195; bh=s1edS834cRKpw4uzuZk2uGH7WTfeAOD2UkgkcVQ4b68=; 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=GlDg9h/hRqh2CzqMvpyiQsXcvJUzSGWlBUSoOK0DRIXO5xZ9LkqzMhW66NS+UAFpF TrD7dDl/tBZUUY8ovRwBQlv2qRlwZ3JX1O34gnNFtojvpW+pma+XwdlHRaaUMBelhk 0lDhKhm+WxCrQ4c12osbw+l2hXEyyjlRrwdjp8vTIzUv5T+Yp4fFTG1kAAEumoChSW tirEehlblBlslSCVl5KLICWFT+EIZKYDbVHsALiKdfdhz4eBfhTqX63yBdOb6nkR+9 26aK5OT5f8uxpPbx3DbA4ZTG+omEPYb6WDurwAWfoZR8b1ROJV8KoFWAiGGbF1zdqt p+59f9fv3zqSg== Received: from mail.u-boot.org (localhost [127.0.0.1]) by mail.u-boot.org (Postfix) with ESMTP id D85B66A340 for ; Fri, 3 Apr 2026 08:06:35 -0600 (MDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=u-boot.org; s=default; t=1775225194; bh=npTcauRzhsl8ez9PFFwUm00pCXIoxxgPr4xRrKIcyiY=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=e6sBMZuItoxGVM2wMurZUnwqqVQ8bBHln1fr70NajFVkoMb5pMJxp3m1uSao+JR75 cEPNBVfFSacssqEg/DZJqYEzt90EBLyYSO0IPjCtHAkBdRQhxfpeqAJ3dwn6aCiG1F GMlMbvxv4wXEFJLxfl7kU8QuKmnM4JRhDOo8TED/WbNdY38cimngps/7Q0Ky5dP6v4 Fby9+JdA2MZlNTIkGeiVc6pFwGJbxjfkkCL2n1PLYIygocBChE7MeMVeOYHAApxEF0 DizeFPAv4ELN1VsQjtLYGm4P9fGOQ5jOyYOneackJ/BtVXMTlk2RVX/qTaHRzoZQX6 ox0gHk/HfKpRQ== Received: from localhost (localhost [127.0.0.1]) by mail.u-boot.org (Postfix) with ESMTP id 38F1F6A340; Fri, 3 Apr 2026 08:06:34 -0600 (MDT) 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 2Pkj06Dyqz5U; Fri, 3 Apr 2026 08:06:34 -0600 (MDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=u-boot.org; s=default; t=1775225188; bh=7/SLoFb7Kn1Ll2Z2ACiTRtNIw0BZVXJBglgIPeicXmc=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=CAlZJRS1UBoE3nesBA3JO+Vgct1p5dn9ArWeMYy+eQFtZOp41aaK0ihI00dR6FuGh ebRo/afODCzP8Id0iqIrYWviA1V5HYiq2cfsZ/ezRPkdyw6kybCPUsfWK5nTFdpwB4 jRm+Xsx+IF6W9Zs5Emc5DucN4/eOchdpdjBP7lRcZMWaT353LF9uIgLPlpSyQagmFl cZAwLmGOOufLKWMiB4Bo9Ar9BEM+893FaZzOwHcYIXxllDxGUB0cGsYpJqJ6lMJY3M y3ecm7NYTJcbN0KTZPXEp/DW7Wkb3tWwReWnJQrSUwRDZfe5IJpo4fWuomxRy3cSD7 JPOFfZsmqSFbQ== Received: from u-boot.org (unknown [73.34.74.121]) by mail.u-boot.org (Postfix) with ESMTPSA id 1677867EE6; Fri, 3 Apr 2026 08:06:28 -0600 (MDT) From: Simon Glass To: U-Boot Concept Date: Fri, 3 Apr 2026 08:04:47 -0600 Message-ID: <20260403140523.1998228-26-sjg@u-boot.org> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260403140523.1998228-1-sjg@u-boot.org> References: <20260403140523.1998228-1-sjg@u-boot.org> MIME-Version: 1.0 Message-ID-Hash: 7RZTTW7LAH4ZSSLPZDBNSRH6WJAGSYG3 X-Message-ID-Hash: 7RZTTW7LAH4ZSSLPZDBNSRH6WJAGSYG3 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 X-Mailman-Version: 3.3.10 Precedence: list Subject: [Concept] [PATCH 25/34] vfs: Support VFS paths in the source command 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 Extend the source command to accept VFS paths: source /boot/boot.scr source /host/setup.cmd When the argument contains a '/', it is treated as a VFS path. The file is loaded into memory and checked for a mkimage header. If present, cmd_source_script() handles it as a FIT or legacy image script. Otherwise, the file is executed as a plain text command list via run_command_list(). This is the key integration point for using VFS in boot scripts. Signed-off-by: Simon Glass --- cmd/source.c | 72 ++++++++++++++++++++++++++++++++++++++++++++++++++++ test/dm/fs.c | 33 ++++++++++++++++++++++++ 2 files changed, 105 insertions(+) diff --git a/cmd/source.c b/cmd/source.c index c9b5f8e400a..c5a3e41d8ef 100644 --- a/cmd/source.c +++ b/cmd/source.c @@ -16,13 +16,78 @@ #include #include +#include +#include +#include #include #include #include #include +#include #include #include +#if IS_ENABLED(CONFIG_VFS) +/** + * source_vfs_file() - Load and execute a script from a VFS path + * + * Loads the file into memory. If it has a valid image header, runs it + * via cmd_source_script(). Otherwise treats it as a plain text command + * list. + * + * @path: VFS path to the script file + * Return: 0 on success, non-zero on error + */ +static int source_vfs_file(const char *path) +{ + struct file_uc_priv *uc_priv; + struct udevice *fil; + long actual; + char *buf; + ulong addr; + int ret; + + ret = vfs_open_file(path, DIR_O_RDONLY, &fil); + if (ret) { + printf("## Cannot find script '%s'\n", path); + return CMD_RET_FAILURE; + } + + uc_priv = dev_get_uclass_priv(fil); + buf = malloc(uc_priv->size + 1); + if (!buf) + return CMD_RET_FAILURE; + + actual = file_read_at(fil, buf, 0, uc_priv->size); + if (actual < 0) { + free(buf); + printf("## Cannot read script '%s'\n", path); + return CMD_RET_FAILURE; + } + + buf[actual] = '\0'; + + /* Check for a mkimage header (legacy or FIT) */ + if (actual >= sizeof(struct legacy_img_hdr) && + image_get_magic((struct legacy_img_hdr *)buf) == IH_MAGIC) { + addr = map_to_sysmem(buf); + ret = cmd_source_script(addr, NULL, NULL); + } else { + /* Plain text command list */ + ret = run_command_list(buf, actual, 0); + } + + free(buf); + + return ret; +} + +static bool is_vfs_path(const char *arg) +{ + return arg && (arg[0] == '/' || strchr(arg, '/')); +} +#endif + static int do_source(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) { @@ -30,6 +95,13 @@ static int do_source(struct cmd_tbl *cmdtp, int flag, int argc, int rcode; const char *fit_uname = NULL, *confname = NULL; +#if IS_ENABLED(CONFIG_VFS) + if (argc >= 2 && is_vfs_path(argv[1])) { + printf("## Executing script from '%s'\n", argv[1]); + return source_vfs_file(argv[1]); + } +#endif + /* Find script image */ if (argc < 2) { addr = CONFIG_SYS_LOAD_ADDR; diff --git a/test/dm/fs.c b/test/dm/fs.c index 4158d2ff3dc..2e046a4bd0c 100644 --- a/test/dm/fs.c +++ b/test/dm/fs.c @@ -6,6 +6,7 @@ */ #include +#include #include #include #include @@ -793,6 +794,38 @@ static int dm_test_vfs_symlink(struct unit_test_state *uts) } DM_TEST(dm_test_vfs_symlink, UTF_SCAN_FDT); +/* Test source command with VFS path */ +static int dm_test_vfs_source(struct unit_test_state *uts) +{ + ut_assertok(vfs_init()); + + ut_assertok(run_command("mount hostfs /host", 0)); + ut_assert_console_end(); + + /* Create a simple script that sets an env var */ + memcpy(map_sysmem(0x1000, 18), "setenv vfs_test ok", 18); + ut_assertok(run_command("save 1000 /host/.vfs_script 12", 0)); + ut_assert_nextline("18 bytes written"); + ut_assert_console_end(); + + /* Run it via source */ + ut_assertok(run_command("source /host/.vfs_script", 0)); + ut_assert_nextlinen("## Executing script"); + ut_assert_console_end(); + + /* Verify the env var was set */ + ut_asserteq_str("ok", env_get("vfs_test")); + + os_unlink(".vfs_script"); + env_set("vfs_test", NULL); + + ut_assertok(run_command("umount /host", 0)); + ut_assert_console_end(); + + return 0; +} +DM_TEST(dm_test_vfs_source, UTF_SCAN_FDT); + /* Test the ln command via VFS */ static int dm_test_vfs_ln(struct unit_test_state *uts) {