X-Git-Url: https://git.kernelconcepts.de/?a=blobdiff_plain;f=common%2Fcmd_pxe.c;h=080b3760de0074d2468a838a12ce850ac510b059;hb=001bd08c07559603eade16459d72c17d5e4d5034;hp=0ab1e0aaa63fa13e8b60a78ea3b7fb1a9698b293;hpb=5a1095a830299aef8dd32495e505e92ab1749e89;p=karo-tx-uboot.git diff --git a/common/cmd_pxe.c b/common/cmd_pxe.c index 0ab1e0aaa6..080b3760de 100644 --- a/common/cmd_pxe.c +++ b/common/cmd_pxe.c @@ -8,11 +8,13 @@ #include #include #include +#include #include #include #include #include #include +#include #include "menu.h" #include "cli.h" @@ -188,11 +190,12 @@ static int do_get_any(cmd_tbl_t *cmdtp, const char *file_path, char *file_addr) * * Returns 1 for success, or < 0 on error. */ -static int get_relfile(cmd_tbl_t *cmdtp, 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)); @@ -215,7 +218,7 @@ static int get_relfile(cmd_tbl_t *cmdtp, 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(cmdtp, relfile, addr_buf); } @@ -227,11 +230,13 @@ static int get_relfile(cmd_tbl_t *cmdtp, const char *file_path, void *file_addr) * * Returns 1 on success, or < 0 for error. */ -static int get_pxe_file(cmd_tbl_t *cmdtp, 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(cmdtp, file_path, file_addr); @@ -250,7 +255,9 @@ static int get_pxe_file(cmd_tbl_t *cmdtp, 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; } @@ -266,7 +273,8 @@ static int get_pxe_file(cmd_tbl_t *cmdtp, const char *file_path, void *file_addr * * Returns 1 on success or < 0 on error. */ -static int get_pxelinux_path(cmd_tbl_t *cmdtp, 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]; @@ -287,7 +295,7 @@ static int get_pxelinux_path(cmd_tbl_t *cmdtp, const char *file, void *pxefile_a * * Returns 1 on success or < 0 on error. */ -static int pxe_uuid_path(cmd_tbl_t *cmdtp, void *pxefile_addr_r) +static int pxe_uuid_path(cmd_tbl_t *cmdtp, unsigned long pxefile_addr_r) { char *uuid_str; @@ -305,7 +313,7 @@ static int pxe_uuid_path(cmd_tbl_t *cmdtp, void *pxefile_addr_r) * * Returns 1 on success or < 0 on error. */ -static int pxe_mac_path(cmd_tbl_t *cmdtp, void *pxefile_addr_r) +static int pxe_mac_path(cmd_tbl_t *cmdtp, unsigned long pxefile_addr_r) { char mac_str[21]; int err; @@ -325,12 +333,12 @@ static int pxe_mac_path(cmd_tbl_t *cmdtp, void *pxefile_addr_r) * * Returns 1 on success or < 0 on error. */ -static int pxe_ipaddr_paths(cmd_tbl_t *cmdtp, 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(cmdtp, ip_addr, pxefile_addr_r); @@ -384,9 +392,9 @@ 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(cmdtp, (void *)pxefile_addr_r) > 0 || - pxe_mac_path(cmdtp, (void *)pxefile_addr_r) > 0 || - pxe_ipaddr_paths(cmdtp, (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; @@ -394,7 +402,7 @@ do_pxe_get(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) while (pxe_default_paths[i]) { if (get_pxelinux_path(cmdtp, pxe_default_paths[i], - (void *)pxefile_addr_r) > 0) { + pxefile_addr_r) > 0) { printf("Config file found\n"); return 0; } @@ -427,7 +435,7 @@ static int get_relfile_envaddr(cmd_tbl_t *cmdtp, const char *file_path, const ch if (strict_strtoul(envaddr, 16, &file_addr) < 0) return -EINVAL; - return get_relfile(cmdtp, file_path, (void *)file_addr); + return get_relfile(cmdtp, file_path, file_addr); } /* @@ -674,6 +682,15 @@ static int label_boot(cmd_tbl_t *cmdtp, struct pxe_label *label) char bootargs[CONFIG_SYS_CBSIZE] = ""; char finalbootargs[CONFIG_SYS_CBSIZE]; + 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; + } + if (label->append) strcpy(bootargs, label->append); strcat(bootargs, ip_str); @@ -776,11 +793,16 @@ static int label_boot(cmd_tbl_t *cmdtp, struct pxe_label *label) /* 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 */ +#ifdef CONFIG_CMD_BOOTI + /* Try booting an AArch64 Linux kernel image */ + else + do_booti(cmdtp, 0, bootm_argc, bootm_argv); +#elif defined(CONFIG_CMD_BOOTZ) + /* Try booting a Image */ else do_bootz(cmdtp, 0, bootm_argc, bootm_argv); #endif + unmap_sysmem(buf); return 1; } @@ -1045,7 +1067,8 @@ static int parse_integer(char **c, int *dst) return 1; } -static int parse_pxefile_top(cmd_tbl_t *cmdtp, 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. @@ -1055,12 +1078,14 @@ static int parse_pxefile_top(cmd_tbl_t *cmdtp, char *p, struct pxe_menu *cfg, in * include, nest_level has already been incremented and doesn't need to be * incremented here. */ -static int handle_include(cmd_tbl_t *cmdtp, 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); @@ -1077,20 +1102,25 @@ static int handle_include(cmd_tbl_t *cmdtp, char **c, char *base, return err; } - return parse_pxefile_top(cmdtp, 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(cmd_tbl_t *cmdtp, 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; @@ -1105,7 +1135,7 @@ static int parse_menu(cmd_tbl_t *cmdtp, char **c, struct pxe_menu *cfg, char *b, break; case T_INCLUDE: - err = handle_include(cmdtp, c, b + strlen(b) + 1, cfg, + err = handle_include(cmdtp, c, base, cfg, nest_level + 1); break; @@ -1272,7 +1302,8 @@ static int parse_label(char **c, struct pxe_menu *cfg) * * Returns 1 on success, < 0 on error. */ -static int parse_pxefile_top(cmd_tbl_t *cmdtp, 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; @@ -1294,7 +1325,9 @@ static int parse_pxefile_top(cmd_tbl_t *cmdtp, char *p, struct pxe_menu *cfg, in switch (t.type) { case T_MENU: cfg->prompt = 1; - err = parse_menu(cmdtp, &p, cfg, b, nest_level); + err = parse_menu(cmdtp, &p, cfg, + base + ALIGN(strlen(b) + 1, 4), + nest_level); break; case T_TIMEOUT: @@ -1319,8 +1352,9 @@ static int parse_pxefile_top(cmd_tbl_t *cmdtp, char *p, struct pxe_menu *cfg, in break; case T_INCLUDE: - err = handle_include(cmdtp, &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: @@ -1376,9 +1410,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(cmd_tbl_t *cmdtp, 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)); @@ -1389,7 +1425,11 @@ static struct pxe_menu *parse_pxefile(cmd_tbl_t *cmdtp, char *menucfg) INIT_LIST_HEAD(&cfg->labels); - if (parse_pxefile_top(cmdtp, 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; } @@ -1547,7 +1587,7 @@ do_pxe_boot(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) return 1; } - cfg = parse_pxefile(cmdtp, (char *)(pxefile_addr_r)); + cfg = parse_pxefile(cmdtp, pxefile_addr_r); if (cfg == NULL) { printf("Error parsing config file\n"); @@ -1558,7 +1598,7 @@ do_pxe_boot(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) destroy_pxe_menu(cfg); - copy_filename(BootFile, "", sizeof(BootFile)); + copy_filename(net_boot_file_name, "", sizeof(net_boot_file_name)); return 0; } @@ -1612,7 +1652,7 @@ static int do_sysboot(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) is_pxe = false; - if (strstr(argv[1], "-p")) { + if (argc > 1 && strstr(argv[1], "-p")) { prompt = 1; argc--; argv++; @@ -1654,12 +1694,12 @@ static int do_sysboot(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) return 1; } - if (get_pxe_file(cmdtp, 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(cmdtp, (char *)(pxefile_addr_r)); + cfg = parse_pxefile(cmdtp, pxefile_addr_r); if (cfg == NULL) { printf("Error parsing config file\n");