From patchwork Thu Oct 14 18:48:08 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Simon Glass X-Patchwork-Id: 1541107 X-Patchwork-Delegate: trini@ti.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: bilbo.ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=chromium.org header.i=@chromium.org header.a=rsa-sha256 header.s=google header.b=YXXQa4Zp; dkim-atps=neutral Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=lists.denx.de (client-ip=85.214.62.61; helo=phobos.denx.de; envelope-from=u-boot-bounces@lists.denx.de; receiver=) Received: from phobos.denx.de (phobos.denx.de [85.214.62.61]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits)) (No client certificate requested) by bilbo.ozlabs.org (Postfix) with ESMTPS id 4HVdmT1bmGz9sR4 for ; Fri, 15 Oct 2021 05:51:53 +1100 (AEDT) Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id BF2DE83800; Thu, 14 Oct 2021 20:50:47 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=chromium.org Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=u-boot-bounces@lists.denx.de Authentication-Results: phobos.denx.de; dkim=pass (1024-bit key; unprotected) header.d=chromium.org header.i=@chromium.org header.b="YXXQa4Zp"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id 64CCA836BB; Thu, 14 Oct 2021 20:49:20 +0200 (CEST) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on phobos.denx.de X-Spam-Level: X-Spam-Status: No, score=-2.1 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,SPF_HELO_NONE, SPF_PASS autolearn=ham autolearn_force=no version=3.4.2 Received: from mail-il1-x131.google.com (mail-il1-x131.google.com [IPv6:2607:f8b0:4864:20::131]) (using TLSv1.3 with cipher TLS_AES_128_GCM_SHA256 (128/128 bits)) (No client certificate requested) by phobos.denx.de (Postfix) with ESMTPS id B0C29836E4 for ; Thu, 14 Oct 2021 20:48:38 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=chromium.org Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=sjg@chromium.org Received: by mail-il1-x131.google.com with SMTP id i11so4525182ila.12 for ; Thu, 14 Oct 2021 11:48:38 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=cMQVs2Nj9wBa17hiSfVW+D2bEsAP3UWwJT6QBW2Bk3Y=; b=YXXQa4Zpm9tx6LWHRAdzqrS/5vOAxZ+9LJWlIRItdb1nKhH03Y3On3+PmvZ2roEdmA 5EoLuQgAqW9+0XUTjUb07ViHHCsXxdh9L4RkiE/fGaMAseNRSMUosTxTTqYSV4KXyORg AVrL01IPB9McAIQdOsYr6PYuYCEeXxrZBDGPY= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=cMQVs2Nj9wBa17hiSfVW+D2bEsAP3UWwJT6QBW2Bk3Y=; b=fRhi8BQUvffCh7n0151aGIJlDv4FKiHQpN1feXCzdmpVNbzzRAWWWz3xWgY7ndJBEu e/BiOdJbM0buRufkQZ8f8QJn4lOOEmXm5dliJS+va4PcCqq3Vy84M4RrbasDjrGnjeeI H+4w52Su/kXX6JlszjIuw3bc8ycjlsugpyaDKOWcFW+rgZjRxe2R5Y0Z/gpls0/Q4xrR KYunI8plCj9JSBy0T2uy3ZVcZNm5RULrkUOnhgMpGa1JJv1nu5RXET17outB0f/cdhJz A8KdpfGrzfX5D/UXD+cUdgSSl41Y2zVKYhHATsAKEgJ0gm5ls3VGo0TGujW+nZdJfS46 JmqQ== X-Gm-Message-State: AOAM532lHB7cPxhzjYxtvCYAnPphhZVpauE72b7ATUhRGd4B/b0V67K2 rXrFS8ObAII9QhPC3OpMhLc0z/lrujgTpA== X-Google-Smtp-Source: ABdhPJyayG9zkagPS2AwbB9vSgWdnJFJvKdqTWeiQDzpi5lTx6VONKpbMh/82a4UWgtBq6f0C9MZEw== X-Received: by 2002:a05:6e02:190b:: with SMTP id w11mr536714ilu.292.1634237317100; Thu, 14 Oct 2021 11:48:37 -0700 (PDT) Received: from kiwi.bld.corp.google.com (c-67-190-101-114.hsd1.co.comcast.net. [67.190.101.114]) by smtp.gmail.com with ESMTPSA id w15sm1697625ill.23.2021.10.14.11.48.36 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 14 Oct 2021 11:48:36 -0700 (PDT) From: Simon Glass To: U-Boot Mailing List Cc: Patrice Chotard , Artem Lapkin , Tom Rini , Joe Hershberger , Heinrich Schuchardt , Peter Hoyes , Simon Glass Subject: [PATCH v3 15/18] pxe: Return the file size from the getfile() function Date: Thu, 14 Oct 2021 12:48:08 -0600 Message-Id: <20211014124803.v3.15.I5ea9daa8a0f8ddcedd99a7dcf136c195b5c9eb50@changeid> X-Mailer: git-send-email 2.33.0.1079.g6e70778dc9-goog In-Reply-To: <20211014184811.482560-1-sjg@chromium.org> References: <20211014184811.482560-1-sjg@chromium.org> MIME-Version: 1.0 X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.34 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" X-Virus-Scanned: clamav-milter 0.103.2 at phobos.denx.de X-Virus-Status: Clean It is pretty strange that the pxe code uses the 'filesize' environment variable find the size of a file it has just read. Partly this is because it uses the command-line interpreter to parse its request to load the file. As a first step towards unwinding this, return it directly from the getfile() function. This makes the code a bit longer, for now, but will be cleaned up in future patches. Signed-off-by: Simon Glass Reviewed-by: Artem Lapkin Tested-by: Artem Lapkin Reviewed-by: Ramon Fried --- (no changes since v1) boot/pxe_utils.c | 70 ++++++++++++++++++++++++++++----------------- cmd/pxe.c | 7 ++++- cmd/sysboot.c | 21 ++++++++++++-- include/pxe_utils.h | 13 ++++++++- 4 files changed, 79 insertions(+), 32 deletions(-) diff --git a/boot/pxe_utils.c b/boot/pxe_utils.c index f36f1f8a60c..e377e16be56 100644 --- a/boot/pxe_utils.c +++ b/boot/pxe_utils.c @@ -30,6 +30,20 @@ #define MAX_TFTP_PATH_LEN 512 +int pxe_get_file_size(ulong *sizep) +{ + const char *val; + + val = from_env("filesize"); + if (!val) + return -ENOENT; + + if (strict_strtoul(val, 16, sizep) < 0) + return -EINVAL; + + return 0; +} + /** * format_mac_pxe() - obtain a MAC address in the PXE format * @@ -75,14 +89,17 @@ int format_mac_pxe(char *outbuf, size_t outbuf_len) * @ctx: PXE context * @file_path: File path to read (relative to the PXE file) * @file_addr: Address to load file to + * @filesizep: If not NULL, returns the file size in bytes * Returns 1 for success, or < 0 on error */ static int get_relfile(struct pxe_context *ctx, const char *file_path, - unsigned long file_addr) + unsigned long file_addr, ulong *filesizep) { size_t path_len; char relfile[MAX_TFTP_PATH_LEN + 1]; char addr_buf[18]; + ulong size; + int ret; if (file_path[0] == '/' && ctx->allow_abs_path) *relfile = '\0'; @@ -103,7 +120,13 @@ static int get_relfile(struct pxe_context *ctx, const char *file_path, sprintf(addr_buf, "%lx", file_addr); - return ctx->getfile(ctx, relfile, addr_buf); + ret = ctx->getfile(ctx, relfile, addr_buf, &size); + if (ret < 0) + return log_msg_ret("get", ret); + if (filesizep) + *filesizep = size; + + return 1; } /** @@ -117,29 +140,17 @@ static int get_relfile(struct pxe_context *ctx, const char *file_path, * Returns 1 for success, or < 0 on error */ int get_pxe_file(struct pxe_context *ctx, const char *file_path, - unsigned long file_addr) + ulong file_addr) { - unsigned long config_file_size; - char *tftp_filesize; + ulong size; int err; char *buf; - err = get_relfile(ctx, file_path, file_addr); + err = get_relfile(ctx, file_path, file_addr, &size); if (err < 0) return err; - /* - * the file comes without a NUL byte at the end, so find out its size - * and add the NUL byte. - */ - tftp_filesize = from_env("filesize"); - if (!tftp_filesize) - return -ENOENT; - - if (strict_strtoul(tftp_filesize, 16, &config_file_size) < 0) - return -EINVAL; - - buf = map_sysmem(file_addr + config_file_size, 1); + buf = map_sysmem(file_addr + size, 1); *buf = '\0'; unmap_sysmem(buf); @@ -184,12 +195,13 @@ int get_pxelinux_path(struct pxe_context *ctx, const char *file, * @file_path: File path to read (relative to the PXE file) * @envaddr_name: Name of environment variable which contains the address to * load to + * @filesizep: Returns the file size in bytes * Returns 1 on success, -ENOENT if @envaddr_name does not exist as an * environment variable, -EINVAL if its format is not valid hex, or other * value < 0 on other error */ static int get_relfile_envaddr(struct pxe_context *ctx, const char *file_path, - const char *envaddr_name) + const char *envaddr_name, ulong *filesizep) { unsigned long file_addr; char *envaddr; @@ -201,7 +213,7 @@ static int get_relfile_envaddr(struct pxe_context *ctx, const char *file_path, if (strict_strtoul(envaddr, 16, &file_addr) < 0) return -EINVAL; - return get_relfile(ctx, file_path, file_addr); + return get_relfile(ctx, file_path, file_addr, filesizep); } /** @@ -357,8 +369,8 @@ static void label_boot_fdtoverlay(struct pxe_context *ctx, goto skip_overlay; /* Load overlay file */ - err = get_relfile_envaddr(ctx, overlayfile, - "fdtoverlay_addr_r"); + err = get_relfile_envaddr(ctx, overlayfile, "fdtoverlay_addr_r", + NULL); if (err < 0) { printf("Failed loading overlay %s\n", overlayfile); goto skip_overlay; @@ -438,7 +450,10 @@ static int label_boot(struct pxe_context *ctx, struct pxe_label *label) } if (label->initrd) { - if (get_relfile_envaddr(ctx, label->initrd, "ramdisk_addr_r") < 0) { + ulong size; + + if (get_relfile_envaddr(ctx, label->initrd, "ramdisk_addr_r", + &size) < 0) { printf("Skipping %s for failure retrieving initrd\n", label->name); return 1; @@ -447,11 +462,12 @@ static int label_boot(struct pxe_context *ctx, struct pxe_label *label) bootm_argv[2] = initrd_str; strncpy(bootm_argv[2], env_get("ramdisk_addr_r"), 18); strcat(bootm_argv[2], ":"); - strncat(bootm_argv[2], env_get("filesize"), 9); + strcat(bootm_argv[2], simple_xtoa(size)); bootm_argc = 3; } - if (get_relfile_envaddr(ctx, label->kernel, "kernel_addr_r") < 0) { + if (get_relfile_envaddr(ctx, label->kernel, "kernel_addr_r", + NULL) < 0) { printf("Skipping %s for failure retrieving kernel\n", label->name); return 1; @@ -592,7 +608,7 @@ static int label_boot(struct pxe_context *ctx, struct pxe_label *label) if (fdtfile) { int err = get_relfile_envaddr(ctx, fdtfile, - "fdt_addr_r"); + "fdt_addr_r", NULL); free(fdtfilefree); if (err < 0) { @@ -1384,7 +1400,7 @@ void handle_pxe_menu(struct pxe_context *ctx, struct pxe_menu *cfg) if (IS_ENABLED(CONFIG_CMD_BMP)) { /* display BMP if available */ if (cfg->bmp) { - if (get_relfile(ctx, cfg->bmp, image_load_addr)) { + if (get_relfile(ctx, cfg->bmp, image_load_addr, NULL)) { if (CONFIG_IS_ENABLED(CMD_CLS)) run_command("cls", 0); bmp_display(image_load_addr, diff --git a/cmd/pxe.c b/cmd/pxe.c index e319db51ef5..81703386c42 100644 --- a/cmd/pxe.c +++ b/cmd/pxe.c @@ -25,15 +25,20 @@ const char *pxe_default_paths[] = { }; static int do_get_tftp(struct pxe_context *ctx, const char *file_path, - char *file_addr) + char *file_addr, ulong *sizep) { char *tftp_argv[] = {"tftp", NULL, NULL, NULL}; + int ret; tftp_argv[1] = file_addr; tftp_argv[2] = (void *)file_path; if (do_tftpb(ctx->cmdtp, 0, 3, tftp_argv)) return -ENOENT; + ret = pxe_get_file_size(sizep); + if (ret) + return log_msg_ret("tftp", ret); + ctx->pxe_file_size = *sizep; return 1; } diff --git a/cmd/sysboot.c b/cmd/sysboot.c index c45fed774d6..6344ecd357b 100644 --- a/cmd/sysboot.c +++ b/cmd/sysboot.c @@ -9,43 +9,58 @@ static char *fs_argv[5]; static int do_get_ext2(struct pxe_context *ctx, const char *file_path, - char *file_addr) + char *file_addr, ulong *sizep) { #ifdef CONFIG_CMD_EXT2 + int ret; + fs_argv[0] = "ext2load"; fs_argv[3] = file_addr; fs_argv[4] = (void *)file_path; if (!do_ext2load(ctx->cmdtp, 0, 5, fs_argv)) return 1; + ret = pxe_get_file_size(sizep); + if (ret) + return log_msg_ret("tftp", ret); #endif return -ENOENT; } static int do_get_fat(struct pxe_context *ctx, const char *file_path, - char *file_addr) + char *file_addr, ulong *sizep) { #ifdef CONFIG_CMD_FAT + int ret; + fs_argv[0] = "fatload"; fs_argv[3] = file_addr; fs_argv[4] = (void *)file_path; if (!do_fat_fsload(ctx->cmdtp, 0, 5, fs_argv)) return 1; + ret = pxe_get_file_size(sizep); + if (ret) + return log_msg_ret("tftp", ret); #endif return -ENOENT; } static int do_get_any(struct pxe_context *ctx, const char *file_path, - char *file_addr) + char *file_addr, ulong *sizep) { #ifdef CONFIG_CMD_FS_GENERIC + int ret; + fs_argv[0] = "load"; fs_argv[3] = file_addr; fs_argv[4] = (void *)file_path; if (!do_load(ctx->cmdtp, 0, 5, fs_argv, FS_TYPE_ANY)) return 1; + ret = pxe_get_file_size(sizep); + if (ret) + return log_msg_ret("tftp", ret); #endif return -ENOENT; } diff --git a/include/pxe_utils.h b/include/pxe_utils.h index 8b50f2e6861..194a5ed8cc7 100644 --- a/include/pxe_utils.h +++ b/include/pxe_utils.h @@ -77,7 +77,7 @@ struct pxe_menu { struct pxe_context; typedef int (*pxe_getfile_func)(struct pxe_context *ctx, const char *file_path, - char *file_addr); + char *file_addr, ulong *filesizep); /** * struct pxe_context - context information for PXE parsing @@ -88,6 +88,7 @@ typedef int (*pxe_getfile_func)(struct pxe_context *ctx, const char *file_path, * @allow_abs_path: true to allow absolute paths * @bootdir: Directory that files are loaded from ("" if no directory). This is * allocated + * @pxe_file_size: Size of the PXE file */ struct pxe_context { struct cmd_tbl *cmdtp; @@ -98,6 +99,7 @@ struct pxe_context { * @file_path: Path to the file * @file_addr: String containing the hex address to put the file in * memory + * @filesizep: Returns the file size in bytes * Return 0 if OK, -ve on error */ pxe_getfile_func getfile; @@ -105,6 +107,7 @@ struct pxe_context { void *userdata; bool allow_abs_path; char *bootdir; + ulong pxe_file_size; }; /** @@ -225,4 +228,12 @@ void pxe_destroy_ctx(struct pxe_context *ctx); */ int pxe_process(struct pxe_context *ctx, ulong pxefile_addr_r, bool prompt); +/** + * pxe_get_file_size() - Read the value of the 'filesize' environment variable + * + * @sizep: Place to put the value + * @return 0 if OK, -ENOENT if no such variable, -EINVAL if format is invalid + */ +int pxe_get_file_size(ulong *sizep); + #endif /* __PXE_UTILS_H */