X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=cmd%2Fpxe.c;h=1dd0a74ea392b2682e01ca1609aa2b39a17b8022;hb=a897269c932999a5c028654489ad68baa6806fdb;hp=c5a770a26995fabc5a1b3b0b7450997d29e110db;hpb=1fdafb2e3dfecdc4129a8062ad25b1adb32b0efb;p=oweals%2Fu-boot.git diff --git a/cmd/pxe.c b/cmd/pxe.c index c5a770a269..1dd0a74ea3 100644 --- a/cmd/pxe.c +++ b/cmd/pxe.c @@ -1,19 +1,20 @@ +// 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 "menu.h" @@ -23,6 +24,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, @@ -472,6 +476,7 @@ struct pxe_label { char *name; char *menu; char *kernel; + char *config; char *append; char *initrd; char *fdt; @@ -488,6 +493,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 @@ -498,6 +504,7 @@ struct pxe_label { struct pxe_menu { char *title; char *default_label; + char *bmp; int timeout; int prompt; struct list_head labels; @@ -539,6 +546,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); @@ -616,9 +626,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; @@ -648,9 +659,9 @@ static int label_boot(cmd_tbl_t *cmdtp, struct pxe_label *label) } bootm_argv[2] = initrd_str; - strcpy(bootm_argv[2], env_get("ramdisk_addr_r")); + strncpy(bootm_argv[2], env_get("ramdisk_addr_r"), 18); strcat(bootm_argv[2], ":"); - strcat(bootm_argv[2], env_get("filesize")); + strncat(bootm_argv[2], env_get("filesize"), 9); } if (get_relfile_envaddr(cmdtp, label->kernel, "kernel_addr_r") < 0) { @@ -686,19 +697,32 @@ 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); - - cli_simple_process_macros(bootargs, finalbootargs); - env_set("bootargs", finalbootargs); - printf("append: %s\n", finalbootargs); } 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; + + 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; + } /* * fdt usage is optional: @@ -758,7 +782,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", @@ -772,7 +796,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; @@ -803,6 +827,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; } @@ -829,6 +857,7 @@ enum token_type { T_FDTDIR, T_ONTIMEOUT, T_IPAPPEND, + T_BACKGROUND, T_INVALID }; @@ -862,6 +891,7 @@ static const struct token keywords[] = { {"fdtdir", T_FDTDIR}, {"ontimeout", T_ONTIMEOUT,}, {"ipappend", T_IPAPPEND,}, + {"background", T_BACKGROUND,}, {NULL, T_INVALID} }; @@ -1139,6 +1169,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); @@ -1187,6 +1221,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. * @@ -1228,7 +1289,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: @@ -1453,8 +1514,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; @@ -1526,6 +1587,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;