summaryrefslogtreecommitdiff
path: root/boot
diff options
context:
space:
mode:
authorSimon Glass <sjg@chromium.org>2021-10-14 21:48:08 +0300
committerTom Rini <trini@konsulko.com>2021-11-12 03:02:36 +0300
commit4d79e884adf6842beb94566bf5249c07a84a5b51 (patch)
tree7eb943b038db3795e57cec8536553dbc959197e1 /boot
parent4a255ea3b65e7793eea97a90ad00dc2b59889683 (diff)
downloadu-boot-4d79e884adf6842beb94566bf5249c07a84a5b51.tar.xz
pxe: Return the file size from the getfile() function
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 <sjg@chromium.org> Reviewed-by: Artem Lapkin <email2tema@gmail.com> Tested-by: Artem Lapkin <email2tema@gmail.com> Reviewed-by: Ramon Fried <rfried.dev@gmail.com>
Diffstat (limited to 'boot')
-rw-r--r--boot/pxe_utils.c70
1 files changed, 43 insertions, 27 deletions
diff --git a/boot/pxe_utils.c b/boot/pxe_utils.c
index 48fb7076fd..a7a84f26c1 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;
@@ -443,21 +455,25 @@ 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;
}
initrd_addr_str = env_get("ramdisk_addr_r");
- strncpy(initrd_filesize, env_get("filesize"), 9);
+ strcpy(initrd_filesize, simple_xtoa(size));
strncpy(initrd_str, initrd_addr_str, 18);
strcat(initrd_str, ":");
strncat(initrd_str, initrd_filesize, 9);
}
- 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;
@@ -599,7 +615,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) {
@@ -1403,7 +1419,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,