X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=cmd%2Fpxe.c;h=205997544623836b0976599046d9609d15351f2e;hb=ae8a53ece0ff3b1ed686c3e0af14e59973d25db8;hp=0a07f14ca8fa94a8e15097cd9b394fc7705344ae;hpb=f63963f048fd34735a2862936dbd0615d7342f8b;p=oweals%2Fu-boot.git diff --git a/cmd/pxe.c b/cmd/pxe.c index 0a07f14ca8..2059975446 100644 --- a/cmd/pxe.c +++ b/cmd/pxe.c @@ -1,19 +1,21 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * Copyright 2010-2011 Calxeda, Inc. * Copyright (c) 2014, NVIDIA CORPORATION. All rights reserved. - * - * SPDX-License-Identifier: GPL-2.0+ */ #include #include +#include #include #include +#include #include #include #include #include #include +#include #include #include "menu.h" @@ -23,6 +25,9 @@ const char *pxe_default_paths[] = { #ifdef CONFIG_SYS_SOC +#ifdef CONFIG_SYS_BOARD + "default-" CONFIG_SYS_ARCH "-" CONFIG_SYS_SOC "-" CONFIG_SYS_BOARD, +#endif "default-" CONFIG_SYS_ARCH "-" CONFIG_SYS_SOC, #endif "default-" CONFIG_SYS_ARCH, @@ -33,15 +38,15 @@ const char *pxe_default_paths[] = { 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 - * place of getenv without changing error handling otherwise. + * Like env_get, but prints an error if envvar isn't defined in the + * environment. It always returns what env_get does, so it can be used in + * place of env_get without changing error handling otherwise. */ static char *from_env(const char *envvar) { char *ret; - ret = getenv(envvar); + ret = env_get(envvar); if (!ret) printf("missing environment variable: %s\n", envvar); @@ -70,8 +75,7 @@ static int format_mac_pxe(char *outbuf, size_t outbuf_len) return -EINVAL; } - if (!eth_getenv_enetaddr_by_index("eth", eth_get_dev_index(), - ethaddr)) + if (!eth_env_get_enetaddr_by_index("eth", eth_get_dev_index(), ethaddr)) return -ENOENT; sprintf(outbuf, "01-%02x-%02x-%02x-%02x-%02x-%02x", @@ -473,6 +477,7 @@ struct pxe_label { char *name; char *menu; char *kernel; + char *config; char *append; char *initrd; char *fdt; @@ -489,6 +494,7 @@ struct pxe_label { * * title - the name of the menu as given by a 'menu title' line. * default_label - the name of the default label, if any. + * bmp - the bmp file name which is displayed in background * timeout - time in tenths of a second to wait for a user key-press before * booting the default label. * prompt - if 0, don't prompt for a choice unless the timeout period is @@ -499,6 +505,7 @@ struct pxe_label { struct pxe_menu { char *title; char *default_label; + char *bmp; int timeout; int prompt; struct list_head labels; @@ -540,6 +547,9 @@ static void label_destroy(struct pxe_label *label) if (label->kernel) free(label->kernel); + if (label->config) + free(label->config); + if (label->append) free(label->append); @@ -591,7 +601,7 @@ static int label_localboot(struct pxe_label *label) char bootargs[CONFIG_SYS_CBSIZE]; cli_simple_process_macros(label->append, bootargs); - setenv("bootargs", bootargs); + env_set("bootargs", bootargs); } debug("running: %s\n", localcmd); @@ -617,9 +627,10 @@ static int label_localboot(struct pxe_label *label) static int label_boot(cmd_tbl_t *cmdtp, struct pxe_label *label) { char *bootm_argv[] = { "bootm", NULL, NULL, NULL, NULL }; - char initrd_str[22]; + char initrd_str[28]; char mac_str[29] = ""; char ip_str[68] = ""; + char *fit_addr = NULL; int bootm_argc = 2; int len = 0; ulong kernel_addr; @@ -649,9 +660,9 @@ static int label_boot(cmd_tbl_t *cmdtp, struct pxe_label *label) } bootm_argv[2] = initrd_str; - strcpy(bootm_argv[2], getenv("ramdisk_addr_r")); + strncpy(bootm_argv[2], env_get("ramdisk_addr_r"), 18); strcat(bootm_argv[2], ":"); - strcat(bootm_argv[2], getenv("filesize")); + strncat(bootm_argv[2], env_get("filesize"), 9); } if (get_relfile_envaddr(cmdtp, label->kernel, "kernel_addr_r") < 0) { @@ -662,8 +673,8 @@ static int label_boot(cmd_tbl_t *cmdtp, struct pxe_label *label) if (label->ipappend & 0x1) { sprintf(ip_str, " ip=%s:%s:%s:%s", - getenv("ipaddr"), getenv("serverip"), - getenv("gatewayip"), getenv("netmask")); + env_get("ipaddr"), env_get("serverip"), + env_get("gatewayip"), env_get("netmask")); } #ifdef CONFIG_CMD_NET @@ -687,20 +698,33 @@ static int label_boot(cmd_tbl_t *cmdtp, struct pxe_label *label) strlen(ip_str), strlen(mac_str), sizeof(bootargs)); return 1; + } else { + if (label->append) + strncpy(bootargs, label->append, + sizeof(bootargs)); + strcat(bootargs, ip_str); + strcat(bootargs, mac_str); + + cli_simple_process_macros(bootargs, finalbootargs); + env_set("bootargs", finalbootargs); + printf("append: %s\n", finalbootargs); } + } - if (label->append) - strcpy(bootargs, label->append); - strcat(bootargs, ip_str); - strcat(bootargs, mac_str); + bootm_argv[1] = env_get("kernel_addr_r"); + /* for FIT, append the configuration identifier */ + if (label->config) { + int len = strlen(bootm_argv[1]) + strlen(label->config) + 1; - cli_simple_process_macros(bootargs, finalbootargs); - setenv("bootargs", finalbootargs); - printf("append: %s\n", finalbootargs); + fit_addr = malloc(len); + if (!fit_addr) { + printf("malloc fail (FIT address)\n"); + return 1; + } + snprintf(fit_addr, len, "%s%s", bootm_argv[1], label->config); + bootm_argv[1] = fit_addr; } - bootm_argv[1] = getenv("kernel_addr_r"); - /* * fdt usage is optional: * It handles the following scenarios. All scenarios are exclusive @@ -714,7 +738,7 @@ static int label_boot(cmd_tbl_t *cmdtp, struct pxe_label *label) * * Scenario 3: fdt blob is not available. */ - bootm_argv[3] = getenv("fdt_addr_r"); + bootm_argv[3] = env_get("fdt_addr_r"); /* if fdt label is defined then get fdt from server */ if (bootm_argv[3]) { @@ -726,7 +750,7 @@ static int label_boot(cmd_tbl_t *cmdtp, struct pxe_label *label) } else if (label->fdtdir) { char *f1, *f2, *f3, *f4, *slash; - f1 = getenv("fdtfile"); + f1 = env_get("fdtfile"); if (f1) { f2 = ""; f3 = ""; @@ -739,9 +763,9 @@ static int label_boot(cmd_tbl_t *cmdtp, struct pxe_label *label) * or the boot scripts should set $fdtfile * before invoking "pxe" or "sysboot". */ - f1 = getenv("soc"); + f1 = env_get("soc"); f2 = "-"; - f3 = getenv("board"); + f3 = env_get("board"); f4 = ".dtb"; } @@ -759,7 +783,7 @@ static int label_boot(cmd_tbl_t *cmdtp, struct pxe_label *label) fdtfilefree = malloc(len); if (!fdtfilefree) { printf("malloc fail (FDT filename)\n"); - return 1; + goto cleanup; } snprintf(fdtfilefree, len, "%s%s%s%s%s%s", @@ -773,7 +797,7 @@ static int label_boot(cmd_tbl_t *cmdtp, struct pxe_label *label) if (err < 0) { printf("Skipping %s for failure retrieving fdt\n", label->name); - return 1; + goto cleanup; } } else { bootm_argv[3] = NULL; @@ -781,7 +805,7 @@ static int label_boot(cmd_tbl_t *cmdtp, struct pxe_label *label) } if (!bootm_argv[3]) - bootm_argv[3] = getenv("fdt_addr"); + bootm_argv[3] = env_get("fdt_addr"); if (bootm_argv[3]) { if (!bootm_argv[2]) @@ -804,6 +828,10 @@ static int label_boot(cmd_tbl_t *cmdtp, struct pxe_label *label) do_bootz(cmdtp, 0, bootm_argc, bootm_argv); #endif unmap_sysmem(buf); + +cleanup: + if (fit_addr) + free(fit_addr); return 1; } @@ -830,6 +858,7 @@ enum token_type { T_FDTDIR, T_ONTIMEOUT, T_IPAPPEND, + T_BACKGROUND, T_INVALID }; @@ -863,6 +892,7 @@ static const struct token keywords[] = { {"fdtdir", T_FDTDIR}, {"ontimeout", T_ONTIMEOUT,}, {"ipappend", T_IPAPPEND,}, + {"background", T_BACKGROUND,}, {NULL, T_INVALID} }; @@ -1140,6 +1170,10 @@ static int parse_menu(cmd_tbl_t *cmdtp, char **c, struct pxe_menu *cfg, nest_level + 1); break; + case T_BACKGROUND: + err = parse_sliteral(c, &cfg->bmp); + break; + default: printf("Ignoring malformed menu command: %.*s\n", (int)(*c - s), s); @@ -1188,6 +1222,33 @@ static int parse_label_menu(char **c, struct pxe_menu *cfg, return 0; } +/* + * Handles parsing a 'kernel' label. + * expecting "filename" or "#cfg" + */ +static int parse_label_kernel(char **c, struct pxe_label *label) +{ + char *s; + int err; + + err = parse_sliteral(c, &label->kernel); + if (err < 0) + return err; + + s = strstr(label->kernel, "#"); + if (!s) + return 1; + + label->config = malloc(strlen(s) + 1); + if (!label->config) + return -ENOMEM; + + strcpy(label->config, s); + *s = 0; + + return 1; +} + /* * Parses a label and adds it to the list of labels for a menu. * @@ -1229,7 +1290,7 @@ static int parse_label(char **c, struct pxe_menu *cfg) case T_KERNEL: case T_LINUX: - err = parse_sliteral(c, &label->kernel); + err = parse_label_kernel(c, label); break; case T_APPEND: @@ -1454,8 +1515,8 @@ static struct menu *pxe_menu_to_menu(struct pxe_menu *cfg) /* * Create a menu and add items for all the labels. */ - m = menu_create(cfg->title, cfg->timeout, cfg->prompt, label_print, - NULL, NULL); + m = menu_create(cfg->title, DIV_ROUND_UP(cfg->timeout, 10), + cfg->prompt, label_print, NULL, NULL); if (!m) return NULL; @@ -1527,6 +1588,20 @@ static void handle_pxe_menu(cmd_tbl_t *cmdtp, struct pxe_menu *cfg) struct menu *m; int err; +#ifdef CONFIG_CMD_BMP + /* display BMP if available */ + if (cfg->bmp) { + if (get_relfile(cmdtp, cfg->bmp, load_addr)) { + run_command("cls", 0); + bmp_display(load_addr, + BMP_ALIGN_CENTER, BMP_ALIGN_CENTER); + } else { + printf("Skipping background bmp %s for failure\n", + cfg->bmp); + } + } +#endif + m = pxe_menu_to_menu(cfg); if (!m) return; @@ -1671,10 +1746,10 @@ static int do_sysboot(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) } if (argc < 6) - filename = getenv("bootfile"); + filename = env_get("bootfile"); else { filename = argv[5]; - setenv("bootfile", filename); + env_set("bootfile", filename); } if (strstr(argv[3], "ext2"))