mirror of
https://github.com/AsahiLinux/u-boot
synced 2024-12-01 08:59:33 +00:00
12df842ee3
The 'bootfile' environment variable is read in the bowels of pxe_util to provide a directory to which all loaded files are relative. This is not obvious from the API to PXE and it is strange to make the caller set an environment variable rather than pass this as a parameter. The code is also convoluted, which this feature implemented by get_bootfile_path(). Update the API to improve this. Unfortunately this means that pxe_setup_ctx() can fail, so add error checking. 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>
135 lines
2.9 KiB
C
135 lines
2.9 KiB
C
// SPDX-License-Identifier: GPL-2.0+
|
|
|
|
#include <common.h>
|
|
#include <command.h>
|
|
#include <env.h>
|
|
#include <fs.h>
|
|
#include <pxe_utils.h>
|
|
|
|
static char *fs_argv[5];
|
|
|
|
static int do_get_ext2(struct pxe_context *ctx, const char *file_path,
|
|
char *file_addr)
|
|
{
|
|
#ifdef CONFIG_CMD_EXT2
|
|
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;
|
|
#endif
|
|
return -ENOENT;
|
|
}
|
|
|
|
static int do_get_fat(struct pxe_context *ctx, const char *file_path,
|
|
char *file_addr)
|
|
{
|
|
#ifdef CONFIG_CMD_FAT
|
|
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;
|
|
#endif
|
|
return -ENOENT;
|
|
}
|
|
|
|
static int do_get_any(struct pxe_context *ctx, 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(ctx->cmdtp, 0, 5, fs_argv, FS_TYPE_ANY))
|
|
return 1;
|
|
#endif
|
|
return -ENOENT;
|
|
}
|
|
|
|
/*
|
|
* Boots a system using a local disk syslinux/extlinux file
|
|
*
|
|
* Returns 0 on success, 1 on error.
|
|
*/
|
|
static int do_sysboot(struct cmd_tbl *cmdtp, int flag, int argc,
|
|
char *const argv[])
|
|
{
|
|
unsigned long pxefile_addr_r;
|
|
pxe_getfile_func getfile;
|
|
struct pxe_context ctx;
|
|
char *pxefile_addr_str;
|
|
char *filename;
|
|
int prompt = 0;
|
|
int ret;
|
|
|
|
if (argc > 1 && strstr(argv[1], "-p")) {
|
|
prompt = 1;
|
|
argc--;
|
|
argv++;
|
|
}
|
|
|
|
if (argc < 4)
|
|
return cmd_usage(cmdtp);
|
|
|
|
if (argc < 5) {
|
|
pxefile_addr_str = from_env("pxefile_addr_r");
|
|
if (!pxefile_addr_str)
|
|
return 1;
|
|
} else {
|
|
pxefile_addr_str = argv[4];
|
|
}
|
|
|
|
if (argc < 6) {
|
|
filename = env_get("bootfile");
|
|
} else {
|
|
filename = argv[5];
|
|
env_set("bootfile", filename);
|
|
}
|
|
|
|
if (strstr(argv[3], "ext2")) {
|
|
getfile = do_get_ext2;
|
|
} else if (strstr(argv[3], "fat")) {
|
|
getfile = do_get_fat;
|
|
} else if (strstr(argv[3], "any")) {
|
|
getfile = do_get_any;
|
|
} else {
|
|
printf("Invalid filesystem: %s\n", argv[3]);
|
|
return 1;
|
|
}
|
|
fs_argv[1] = argv[1];
|
|
fs_argv[2] = argv[2];
|
|
|
|
if (strict_strtoul(pxefile_addr_str, 16, &pxefile_addr_r) < 0) {
|
|
printf("Invalid pxefile address: %s\n", pxefile_addr_str);
|
|
return 1;
|
|
}
|
|
|
|
if (pxe_setup_ctx(&ctx, cmdtp, getfile, NULL, true, filename)) {
|
|
printf("Out of memory\n");
|
|
return CMD_RET_FAILURE;
|
|
}
|
|
|
|
if (get_pxe_file(&ctx, filename, pxefile_addr_r) < 0) {
|
|
printf("Error reading config file\n");
|
|
pxe_destroy_ctx(&ctx);
|
|
return 1;
|
|
}
|
|
|
|
ret = pxe_process(&ctx, pxefile_addr_r, prompt);
|
|
pxe_destroy_ctx(&ctx);
|
|
if (ret)
|
|
return CMD_RET_FAILURE;
|
|
|
|
return 0;
|
|
}
|
|
|
|
U_BOOT_CMD(sysboot, 7, 1, do_sysboot,
|
|
"command to get and boot from syslinux files",
|
|
"[-p] <interface> <dev[:part]> <ext2|fat|any> [addr] [filename]\n"
|
|
" - load and parse syslinux menu file 'filename' from ext2, fat\n"
|
|
" or any filesystem on 'dev' on 'interface' to address 'addr'"
|
|
);
|