Newer
Older
* Copyright (c) 2014, NVIDIA CORPORATION. All rights reserved.
* SPDX-License-Identifier: GPL-2.0+
#include <common.h>
#include <command.h>
#include <malloc.h>
#include <mapmem.h>
#include <linux/string.h>
#include <linux/ctype.h>
#include <errno.h>
#include <linux/list.h>
#include <fs.h>
#include "cli.h"
const char *pxe_default_paths[] = {
"default-" CONFIG_SYS_ARCH "-" CONFIG_SYS_SOC,
"default-" CONFIG_SYS_ARCH,
"default",
NULL
};
/*
* Like getenv, but prints an error if envvar isn't defined in the
* environment. It always returns what getenv does, so it can be used in
* place of getenv without changing error handling otherwise.
*/
static char *from_env(const char *envvar)
{
char *ret;
ret = getenv(envvar);
if (!ret)
printf("missing environment variable: %s\n", envvar);
return ret;
}
#ifdef CONFIG_CMD_NET
/*
* Convert an ethaddr from the environment to the format used by pxelinux
* filenames based on mac addresses. Convert's ':' to '-', and adds "01-" to
* the beginning of the ethernet address to indicate a hardware type of
* Ethernet. Also converts uppercase hex characters into lowercase, to match
* pxelinux's behavior.
*
* Returns 1 for success, -ENOENT if 'ethaddr' is undefined in the
* environment, or some other value < 0 on error.
*/
static int format_mac_pxe(char *outbuf, size_t outbuf_len)
{
printf("outbuf is too small (%zd < 21)\n", outbuf_len);
if (!eth_getenv_enetaddr_by_index("eth", eth_get_dev_index(),
ethaddr))
return -ENOENT;
sprintf(outbuf, "01-%02x-%02x-%02x-%02x-%02x-%02x",
ethaddr[0], ethaddr[1], ethaddr[2],
ethaddr[3], ethaddr[4], ethaddr[5]);
/*
* Returns the directory the file specified in the bootfile env variable is
* in. If bootfile isn't defined in the environment, return NULL, which should
* be interpreted as "don't prepend anything to paths".
*/
static int get_bootfile_path(const char *file_path, char *bootfile_path,
size_t bootfile_path_size)
/* Only syslinux allows absolute paths */
if (file_path[0] == '/' && !is_pxe)
path_len = (last_slash - bootfile) + 1;
if (bootfile_path_size < path_len) {
printf("bootfile_path too small. (%zd < %zd)\n",
bootfile_path_size, path_len);
return -1;
}
strncpy(bootfile_path, bootfile, path_len);
bootfile_path[path_len] = '\0';
return 1;
}
static int (*do_getfile)(cmd_tbl_t *cmdtp, const char *file_path, char *file_addr);
#ifdef CONFIG_CMD_NET
static int do_get_tftp(cmd_tbl_t *cmdtp, const char *file_path, char *file_addr)
{
char *tftp_argv[] = {"tftp", NULL, NULL, NULL};
tftp_argv[1] = file_addr;
if (do_tftpb(cmdtp, 0, 3, tftp_argv))
return -ENOENT;
return 1;
}
static char *fs_argv[5];
static int do_get_ext2(cmd_tbl_t *cmdtp, const char *file_path, char *file_addr)
{
#ifdef CONFIG_CMD_EXT2
fs_argv[0] = "ext2load";
fs_argv[3] = file_addr;
if (!do_ext2load(cmdtp, 0, 5, fs_argv))
return 1;
#endif
return -ENOENT;
}
static int do_get_fat(cmd_tbl_t *cmdtp, const char *file_path, char *file_addr)
{
#ifdef CONFIG_CMD_FAT
fs_argv[0] = "fatload";
fs_argv[3] = file_addr;
if (!do_fat_fsload(cmdtp, 0, 5, fs_argv))
return 1;
#endif
return -ENOENT;
}
static int do_get_any(cmd_tbl_t *cmdtp, const char *file_path, char *file_addr)
{
#ifdef CONFIG_CMD_FS_GENERIC
fs_argv[0] = "load";
fs_argv[3] = file_addr;
fs_argv[4] = (void *)file_path;
if (!do_load(cmdtp, 0, 5, fs_argv, FS_TYPE_ANY))
return 1;
#endif
return -ENOENT;
}
/*
* As in pxelinux, paths to files referenced from files we retrieve are
* relative to the location of bootfile. get_relfile takes such a path and
* joins it with the bootfile path to get the full path to the target file. If
* the bootfile path is NULL, we use file_path as is.
*
* Returns 1 for success, or < 0 on error.
*/
static int get_relfile(cmd_tbl_t *cmdtp, const char *file_path,
unsigned long file_addr)
{
size_t path_len;
char relfile[MAX_TFTP_PATH_LEN+1];
Loading
Loading full blame...