X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=common%2Fcmd_pxe.c;h=abf0941b579c20ae8ca1b31ba7196921e39ffab2;hb=59565736839108846d8dfa6782babfaefff6b58b;hp=c5f4a221b8c152770f62601896468d96a12e867f;hpb=3be2bdf5dc69b3142c1162a59bc67191c9077567;p=oweals%2Fu-boot.git diff --git a/common/cmd_pxe.c b/common/cmd_pxe.c index c5f4a221b8..abf0941b57 100644 --- a/common/cmd_pxe.c +++ b/common/cmd_pxe.c @@ -1,5 +1,6 @@ /* * Copyright 2010-2011 Calxeda, Inc. + * Copyright (c) 2014, NVIDIA CORPORATION. All rights reserved. * * SPDX-License-Identifier: GPL-2.0+ */ @@ -7,12 +8,16 @@ #include #include #include +#include #include #include #include #include +#include +#include #include "menu.h" +#include "cli.h" #define MAX_TFTP_PATH_LEN 127 @@ -25,6 +30,8 @@ const char *pxe_default_paths[] = { NULL }; +static bool is_pxe; + /* * 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 @@ -42,6 +49,7 @@ static char *from_env(const char *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 @@ -57,7 +65,7 @@ static int format_mac_pxe(char *outbuf, size_t outbuf_len) uchar ethaddr[6]; if (outbuf_len < 21) { - printf("outbuf is too small (%d < 21)\n", outbuf_len); + printf("outbuf is too small (%zd < 21)\n", outbuf_len); return -EINVAL; } @@ -72,6 +80,7 @@ static int format_mac_pxe(char *outbuf, size_t outbuf_len) return 1; } +#endif /* * Returns the directory the file specified in the bootfile env variable is @@ -84,7 +93,8 @@ static int get_bootfile_path(const char *file_path, char *bootfile_path, char *bootfile, *last_slash; size_t path_len = 0; - if (file_path[0] == '/') + /* Only syslinux allows absolute paths */ + if (file_path[0] == '/' && !is_pxe) goto ret; bootfile = from_env("bootfile"); @@ -100,7 +110,7 @@ static int get_bootfile_path(const char *file_path, char *bootfile_path, path_len = (last_slash - bootfile) + 1; if (bootfile_path_size < path_len) { - printf("bootfile_path too small. (%d < %d)\n", + printf("bootfile_path too small. (%zd < %zd)\n", bootfile_path_size, path_len); return -1; @@ -114,44 +124,59 @@ static int get_bootfile_path(const char *file_path, char *bootfile_path, return 1; } -static int (*do_getfile)(const char *file_path, char *file_addr); +static int (*do_getfile)(cmd_tbl_t *cmdtp, const char *file_path, char *file_addr); -static int do_get_tftp(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; tftp_argv[2] = (void *)file_path; - if (do_tftpb(NULL, 0, 3, tftp_argv)) + if (do_tftpb(cmdtp, 0, 3, tftp_argv)) return -ENOENT; return 1; } +#endif static char *fs_argv[5]; -static int do_get_ext2(const char *file_path, char *file_addr) +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; fs_argv[4] = (void *)file_path; - if (!do_ext2load(NULL, 0, 5, fs_argv)) + if (!do_ext2load(cmdtp, 0, 5, fs_argv)) return 1; #endif return -ENOENT; } -static int do_get_fat(const char *file_path, char *file_addr) +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; fs_argv[4] = (void *)file_path; - if (!do_fat_fsload(NULL, 0, 5, fs_argv)) + 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; @@ -165,11 +190,12 @@ static int do_get_fat(const char *file_path, char *file_addr) * * Returns 1 for success, or < 0 on error. */ -static int get_relfile(const char *file_path, void *file_addr) +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]; - char addr_buf[10]; + char addr_buf[18]; int err; err = get_bootfile_path(file_path, relfile, sizeof(relfile)); @@ -192,9 +218,9 @@ static int get_relfile(const char *file_path, void *file_addr) printf("Retrieving file: %s\n", relfile); - sprintf(addr_buf, "%p", file_addr); + sprintf(addr_buf, "%lx", file_addr); - return do_getfile(relfile, addr_buf); + return do_getfile(cmdtp, relfile, addr_buf); } /* @@ -204,13 +230,15 @@ static int get_relfile(const char *file_path, void *file_addr) * * Returns 1 on success, or < 0 for error. */ -static int get_pxe_file(const char *file_path, void *file_addr) +static int get_pxe_file(cmd_tbl_t *cmdtp, const char *file_path, + unsigned long file_addr) { unsigned long config_file_size; char *tftp_filesize; int err; + char *buf; - err = get_relfile(file_path, file_addr); + err = get_relfile(cmdtp, file_path, file_addr); if (err < 0) return err; @@ -227,11 +255,15 @@ static int get_pxe_file(const char *file_path, void *file_addr) if (strict_strtoul(tftp_filesize, 16, &config_file_size) < 0) return -EINVAL; - *(char *)(file_addr + config_file_size) = '\0'; + buf = map_sysmem(file_addr + config_file_size, 1); + *buf = '\0'; + unmap_sysmem(buf); return 1; } +#ifdef CONFIG_CMD_NET + #define PXELINUX_DIR "pxelinux.cfg/" /* @@ -241,7 +273,8 @@ static int get_pxe_file(const char *file_path, void *file_addr) * * Returns 1 on success or < 0 on error. */ -static int get_pxelinux_path(const char *file, void *pxefile_addr_r) +static int get_pxelinux_path(cmd_tbl_t *cmdtp, const char *file, + unsigned long pxefile_addr_r) { size_t base_len = strlen(PXELINUX_DIR); char path[MAX_TFTP_PATH_LEN+1]; @@ -254,7 +287,7 @@ static int get_pxelinux_path(const char *file, void *pxefile_addr_r) sprintf(path, PXELINUX_DIR "%s", file); - return get_pxe_file(path, pxefile_addr_r); + return get_pxe_file(cmdtp, path, pxefile_addr_r); } /* @@ -262,7 +295,7 @@ static int get_pxelinux_path(const char *file, void *pxefile_addr_r) * * Returns 1 on success or < 0 on error. */ -static int pxe_uuid_path(void *pxefile_addr_r) +static int pxe_uuid_path(cmd_tbl_t *cmdtp, unsigned long pxefile_addr_r) { char *uuid_str; @@ -271,7 +304,7 @@ static int pxe_uuid_path(void *pxefile_addr_r) if (!uuid_str) return -ENOENT; - return get_pxelinux_path(uuid_str, pxefile_addr_r); + return get_pxelinux_path(cmdtp, uuid_str, pxefile_addr_r); } /* @@ -280,7 +313,7 @@ static int pxe_uuid_path(void *pxefile_addr_r) * * Returns 1 on success or < 0 on error. */ -static int pxe_mac_path(void *pxefile_addr_r) +static int pxe_mac_path(cmd_tbl_t *cmdtp, unsigned long pxefile_addr_r) { char mac_str[21]; int err; @@ -290,7 +323,7 @@ static int pxe_mac_path(void *pxefile_addr_r) if (err < 0) return err; - return get_pxelinux_path(mac_str, pxefile_addr_r); + return get_pxelinux_path(cmdtp, mac_str, pxefile_addr_r); } /* @@ -300,15 +333,15 @@ static int pxe_mac_path(void *pxefile_addr_r) * * Returns 1 on success or < 0 on error. */ -static int pxe_ipaddr_paths(void *pxefile_addr_r) +static int pxe_ipaddr_paths(cmd_tbl_t *cmdtp, unsigned long pxefile_addr_r) { char ip_addr[9]; int mask_pos, err; - sprintf(ip_addr, "%08X", ntohl(NetOurIP)); + sprintf(ip_addr, "%08X", ntohl(net_ip.s_addr)); for (mask_pos = 7; mask_pos >= 0; mask_pos--) { - err = get_pxelinux_path(ip_addr, pxefile_addr_r); + err = get_pxelinux_path(cmdtp, ip_addr, pxefile_addr_r); if (err > 0) return err; @@ -359,17 +392,17 @@ do_pxe_get(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) * Keep trying paths until we successfully get a file we're looking * for. */ - if (pxe_uuid_path((void *)pxefile_addr_r) > 0 || - pxe_mac_path((void *)pxefile_addr_r) > 0 || - pxe_ipaddr_paths((void *)pxefile_addr_r) > 0) { + if (pxe_uuid_path(cmdtp, pxefile_addr_r) > 0 || + pxe_mac_path(cmdtp, pxefile_addr_r) > 0 || + pxe_ipaddr_paths(cmdtp, pxefile_addr_r) > 0) { printf("Config file found\n"); return 0; } while (pxe_default_paths[i]) { - if (get_pxelinux_path(pxe_default_paths[i], - (void *)pxefile_addr_r) > 0) { + if (get_pxelinux_path(cmdtp, pxe_default_paths[i], + pxefile_addr_r) > 0) { printf("Config file found\n"); return 0; } @@ -380,6 +413,7 @@ do_pxe_get(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) return 1; } +#endif /* * Wrapper to make it easier to store the file at file_path in the location @@ -388,7 +422,7 @@ do_pxe_get(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) * * Returns 1 on success or < 0 on error. */ -static int get_relfile_envaddr(const char *file_path, const char *envaddr_name) +static int get_relfile_envaddr(cmd_tbl_t *cmdtp, const char *file_path, const char *envaddr_name) { unsigned long file_addr; char *envaddr; @@ -401,7 +435,7 @@ static int get_relfile_envaddr(const char *file_path, const char *envaddr_name) if (strict_strtoul(envaddr, 16, &file_addr) < 0) return -EINVAL; - return get_relfile(file_path, (void *)file_addr); + return get_relfile(cmdtp, file_path, file_addr); } /* @@ -442,6 +476,7 @@ struct pxe_label { char *append; char *initrd; char *fdt; + char *fdtdir; int ipappend; int attempted; int localboot; @@ -514,6 +549,9 @@ static void label_destroy(struct pxe_label *label) if (label->fdt) free(label->fdt); + if (label->fdtdir) + free(label->fdtdir); + free(label); } @@ -549,8 +587,12 @@ static int label_localboot(struct pxe_label *label) if (!localcmd) return -ENOENT; - if (label->append) - setenv("bootargs", label->append); + if (label->append) { + char bootargs[CONFIG_SYS_CBSIZE]; + + cli_simple_process_macros(label->append, bootargs); + setenv("bootargs", bootargs); + } debug("running: %s\n", localcmd); @@ -578,9 +620,10 @@ static int label_boot(cmd_tbl_t *cmdtp, struct pxe_label *label) char initrd_str[22]; char mac_str[29] = ""; char ip_str[68] = ""; - char *bootargs; int bootm_argc = 3; int len = 0; + ulong kernel_addr; + void *buf; label_print(label); @@ -599,7 +642,7 @@ static int label_boot(cmd_tbl_t *cmdtp, struct pxe_label *label) } if (label->initrd) { - if (get_relfile_envaddr(label->initrd, "ramdisk_addr_r") < 0) { + if (get_relfile_envaddr(cmdtp, label->initrd, "ramdisk_addr_r") < 0) { printf("Skipping %s for failure retrieving initrd\n", label->name); return 1; @@ -613,7 +656,7 @@ static int label_boot(cmd_tbl_t *cmdtp, struct pxe_label *label) bootm_argv[2] = "-"; } - if (get_relfile_envaddr(label->kernel, "kernel_addr_r") < 0) { + if (get_relfile_envaddr(cmdtp, label->kernel, "kernel_addr_r") < 0) { printf("Skipping %s for failure retrieving kernel\n", label->name); return 1; @@ -623,35 +666,39 @@ static int label_boot(cmd_tbl_t *cmdtp, struct pxe_label *label) sprintf(ip_str, " ip=%s:%s:%s:%s", getenv("ipaddr"), getenv("serverip"), getenv("gatewayip"), getenv("netmask")); - len += strlen(ip_str); } +#ifdef CONFIG_CMD_NET if (label->ipappend & 0x2) { int err; strcpy(mac_str, " BOOTIF="); err = format_mac_pxe(mac_str + 8, sizeof(mac_str) - 8); if (err < 0) mac_str[0] = '\0'; - len += strlen(mac_str); } +#endif - if (label->append) - len += strlen(label->append); + if ((label->ipappend & 0x3) || label->append) { + char bootargs[CONFIG_SYS_CBSIZE] = ""; + char finalbootargs[CONFIG_SYS_CBSIZE]; - if (len) { - bootargs = malloc(len + 1); - if (!bootargs) + if (strlen(label->append ?: "") + + strlen(ip_str) + strlen(mac_str) + 1 > sizeof(bootargs)) { + printf("bootarg overflow %zd+%zd+%zd+1 > %zd\n", + strlen(label->append ?: ""), + strlen(ip_str), strlen(mac_str), + sizeof(bootargs)); return 1; - bootargs[0] = '\0'; + } + if (label->append) strcpy(bootargs, label->append); strcat(bootargs, ip_str); strcat(bootargs, mac_str); - setenv("bootargs", bootargs); - printf("append: %s\n", bootargs); - - free(bootargs); + cli_simple_process_macros(bootargs, finalbootargs); + setenv("bootargs", finalbootargs); + printf("append: %s\n", finalbootargs); } bootm_argv[1] = getenv("kernel_addr_r"); @@ -672,24 +719,86 @@ static int label_boot(cmd_tbl_t *cmdtp, struct pxe_label *label) bootm_argv[3] = getenv("fdt_addr_r"); /* if fdt label is defined then get fdt from server */ - if (bootm_argv[3] && label->fdt) { - if (get_relfile_envaddr(label->fdt, "fdt_addr_r") < 0) { - printf("Skipping %s for failure retrieving fdt\n", - label->name); - return 1; + if (bootm_argv[3]) { + char *fdtfile = NULL; + char *fdtfilefree = NULL; + + if (label->fdt) { + fdtfile = label->fdt; + } else if (label->fdtdir) { + char *f1, *f2, *f3, *f4, *slash; + + f1 = getenv("fdtfile"); + if (f1) { + f2 = ""; + f3 = ""; + f4 = ""; + } else { + /* + * For complex cases where this code doesn't + * generate the correct filename, the board + * code should set $fdtfile during early boot, + * or the boot scripts should set $fdtfile + * before invoking "pxe" or "sysboot". + */ + f1 = getenv("soc"); + f2 = "-"; + f3 = getenv("board"); + f4 = ".dtb"; + } + + len = strlen(label->fdtdir); + if (!len) + slash = "./"; + else if (label->fdtdir[len - 1] != '/') + slash = "/"; + else + slash = ""; + + len = strlen(label->fdtdir) + strlen(slash) + + strlen(f1) + strlen(f2) + strlen(f3) + + strlen(f4) + 1; + fdtfilefree = malloc(len); + if (!fdtfilefree) { + printf("malloc fail (FDT filename)\n"); + return 1; + } + + snprintf(fdtfilefree, len, "%s%s%s%s%s%s", + label->fdtdir, slash, f1, f2, f3, f4); + fdtfile = fdtfilefree; + } + + if (fdtfile) { + int err = get_relfile_envaddr(cmdtp, fdtfile, "fdt_addr_r"); + free(fdtfilefree); + if (err < 0) { + printf("Skipping %s for failure retrieving fdt\n", + label->name); + return 1; + } + } else { + bootm_argv[3] = NULL; } - } else + } + + if (!bootm_argv[3]) bootm_argv[3] = getenv("fdt_addr"); if (bootm_argv[3]) bootm_argc = 4; - do_bootm(cmdtp, 0, bootm_argc, bootm_argv); - + kernel_addr = genimg_get_kernel_addr(bootm_argv[1]); + buf = map_sysmem(kernel_addr, 0); + /* Try bootm for legacy and FIT format image */ + if (genimg_get_format(buf) != IMAGE_FORMAT_INVALID) + do_bootm(cmdtp, 0, bootm_argc, bootm_argv); #ifdef CONFIG_CMD_BOOTZ - /* Try booting a zImage if do_bootm returns */ - do_bootz(cmdtp, 0, bootm_argc, bootm_argv); + /* Try booting a zImage */ + else + do_bootz(cmdtp, 0, bootm_argc, bootm_argv); #endif + unmap_sysmem(buf); return 1; } @@ -713,6 +822,7 @@ enum token_type { T_PROMPT, T_INCLUDE, T_FDT, + T_FDTDIR, T_ONTIMEOUT, T_IPAPPEND, T_INVALID @@ -742,7 +852,10 @@ static const struct token keywords[] = { {"append", T_APPEND}, {"initrd", T_INITRD}, {"include", T_INCLUDE}, + {"devicetree", T_FDT}, {"fdt", T_FDT}, + {"devicetreedir", T_FDTDIR}, + {"fdtdir", T_FDTDIR}, {"ontimeout", T_ONTIMEOUT,}, {"ipappend", T_IPAPPEND,}, {NULL, T_INVALID} @@ -950,7 +1063,8 @@ static int parse_integer(char **c, int *dst) return 1; } -static int parse_pxefile_top(char *p, struct pxe_menu *cfg, int nest_level); +static int parse_pxefile_top(cmd_tbl_t *cmdtp, char *p, unsigned long base, + struct pxe_menu *cfg, int nest_level); /* * Parse an include statement, and retrieve and parse the file it mentions. @@ -960,12 +1074,14 @@ static int parse_pxefile_top(char *p, struct pxe_menu *cfg, int nest_level); * include, nest_level has already been incremented and doesn't need to be * incremented here. */ -static int handle_include(char **c, char *base, +static int handle_include(cmd_tbl_t *cmdtp, char **c, unsigned long base, struct pxe_menu *cfg, int nest_level) { char *include_path; char *s = *c; int err; + char *buf; + int ret; err = parse_sliteral(c, &include_path); @@ -975,27 +1091,32 @@ static int handle_include(char **c, char *base, return err; } - err = get_pxe_file(include_path, base); + err = get_pxe_file(cmdtp, include_path, base); if (err < 0) { printf("Couldn't retrieve %s\n", include_path); return err; } - return parse_pxefile_top(base, cfg, nest_level); + buf = map_sysmem(base, 0); + ret = parse_pxefile_top(cmdtp, buf, base, cfg, nest_level); + unmap_sysmem(buf); + + return ret; } /* * Parse lines that begin with 'menu'. * - * b and nest are provided to handle the 'menu include' case. + * base and nest are provided to handle the 'menu include' case. * - * b should be the address where the file currently being parsed is stored. + * base should point to a location where it's safe to store the included file. * * nest_level should be 1 when parsing the top level pxe file, 2 when parsing * a file it includes, 3 when parsing a file included by that file, and so on. */ -static int parse_menu(char **c, struct pxe_menu *cfg, char *b, int nest_level) +static int parse_menu(cmd_tbl_t *cmdtp, char **c, struct pxe_menu *cfg, + unsigned long base, int nest_level) { struct token t; char *s = *c; @@ -1010,7 +1131,7 @@ static int parse_menu(char **c, struct pxe_menu *cfg, char *b, int nest_level) break; case T_INCLUDE: - err = handle_include(c, b + strlen(b) + 1, cfg, + err = handle_include(cmdtp, c, base, cfg, nest_level + 1); break; @@ -1131,6 +1252,11 @@ static int parse_label(char **c, struct pxe_menu *cfg) err = parse_sliteral(c, &label->fdt); break; + case T_FDTDIR: + if (!label->fdtdir) + err = parse_sliteral(c, &label->fdtdir); + break; + case T_LOCALBOOT: label->localboot = 1; err = parse_integer(c, &label->localboot_val); @@ -1172,7 +1298,8 @@ static int parse_label(char **c, struct pxe_menu *cfg) * * Returns 1 on success, < 0 on error. */ -static int parse_pxefile_top(char *p, struct pxe_menu *cfg, int nest_level) +static int parse_pxefile_top(cmd_tbl_t *cmdtp, char *p, unsigned long base, + struct pxe_menu *cfg, int nest_level) { struct token t; char *s, *b, *label_name; @@ -1194,7 +1321,9 @@ static int parse_pxefile_top(char *p, struct pxe_menu *cfg, int nest_level) switch (t.type) { case T_MENU: cfg->prompt = 1; - err = parse_menu(&p, cfg, b, nest_level); + err = parse_menu(cmdtp, &p, cfg, + base + ALIGN(strlen(b) + 1, 4), + nest_level); break; case T_TIMEOUT: @@ -1219,8 +1348,9 @@ static int parse_pxefile_top(char *p, struct pxe_menu *cfg, int nest_level) break; case T_INCLUDE: - err = handle_include(&p, b + ALIGN(strlen(b), 4), cfg, - nest_level + 1); + err = handle_include(cmdtp, &p, + base + ALIGN(strlen(b), 4), cfg, + nest_level + 1); break; case T_PROMPT: @@ -1276,9 +1406,11 @@ static void destroy_pxe_menu(struct pxe_menu *cfg) * files it includes). The resulting pxe_menu struct can be free()'d by using * the destroy_pxe_menu() function. */ -static struct pxe_menu *parse_pxefile(char *menucfg) +static struct pxe_menu *parse_pxefile(cmd_tbl_t *cmdtp, unsigned long menucfg) { struct pxe_menu *cfg; + char *buf; + int r; cfg = malloc(sizeof(struct pxe_menu)); @@ -1289,7 +1421,11 @@ static struct pxe_menu *parse_pxefile(char *menucfg) INIT_LIST_HEAD(&cfg->labels); - if (parse_pxefile_top(menucfg, cfg, 1) < 0) { + buf = map_sysmem(menucfg, 0); + r = parse_pxefile_top(cmdtp, buf, menucfg, cfg, 1); + unmap_sysmem(buf); + + if (r < 0) { destroy_pxe_menu(cfg); return NULL; } @@ -1416,6 +1552,7 @@ static void handle_pxe_menu(cmd_tbl_t *cmdtp, struct pxe_menu *cfg) boot_unattempted_labels(cmdtp, cfg); } +#ifdef CONFIG_CMD_NET /* * Boots a system using a pxe file * @@ -1446,7 +1583,7 @@ do_pxe_boot(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) return 1; } - cfg = parse_pxefile((char *)(pxefile_addr_r)); + cfg = parse_pxefile(cmdtp, pxefile_addr_r); if (cfg == NULL) { printf("Error parsing config file\n"); @@ -1457,6 +1594,8 @@ do_pxe_boot(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) destroy_pxe_menu(cfg); + copy_filename(net_boot_file_name, "", sizeof(net_boot_file_name)); + return 0; } @@ -1465,13 +1604,15 @@ static cmd_tbl_t cmd_pxe_sub[] = { U_BOOT_CMD_MKENT(boot, 2, 1, do_pxe_boot, "", "") }; -int do_pxe(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) +static int do_pxe(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { cmd_tbl_t *cp; if (argc < 2) return CMD_RET_USAGE; + is_pxe = true; + /* drop initial "pxe" arg */ argc--; argv++; @@ -1490,13 +1631,14 @@ U_BOOT_CMD( "get - try to retrieve a pxe file using tftp\npxe " "boot [pxefile_addr_r] - boot from the pxe file at pxefile_addr_r\n" ); +#endif /* * Boots a system using a local disk syslinux/extlinux file * * Returns 0 on success, 1 on error. */ -int do_sysboot(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) +static int do_sysboot(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { unsigned long pxefile_addr_r; struct pxe_menu *cfg; @@ -1504,7 +1646,9 @@ int do_sysboot(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) char *filename; int prompt = 0; - if (strstr(argv[1], "-p")) { + is_pxe = false; + + if (argc > 1 && strstr(argv[1], "-p")) { prompt = 1; argc--; argv++; @@ -1532,6 +1676,8 @@ int do_sysboot(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) do_getfile = do_get_ext2; else if (strstr(argv[3], "fat")) do_getfile = do_get_fat; + else if (strstr(argv[3], "any")) + do_getfile = do_get_any; else { printf("Invalid filesystem: %s\n", argv[3]); return 1; @@ -1544,12 +1690,12 @@ int do_sysboot(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) return 1; } - if (get_pxe_file(filename, (void *)pxefile_addr_r) < 0) { + if (get_pxe_file(cmdtp, filename, pxefile_addr_r) < 0) { printf("Error reading config file\n"); return 1; } - cfg = parse_pxefile((char *)(pxefile_addr_r)); + cfg = parse_pxefile(cmdtp, pxefile_addr_r); if (cfg == NULL) { printf("Error parsing config file\n"); @@ -1569,7 +1715,7 @@ int do_sysboot(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) U_BOOT_CMD( sysboot, 7, 1, do_sysboot, "command to get and boot from syslinux files", - "[-p] [addr] [filename]\n" - " - load and parse syslinux menu file 'filename' from ext2 or fat\n" - " filesystem on 'dev' on 'interface' to address 'addr'" + "[-p] [addr] [filename]\n" + " - load and parse syslinux menu file 'filename' from ext2, fat\n" + " or any filesystem on 'dev' on 'interface' to address 'addr'" );