Merge branch '2021-11-12-assorted-updates'

- A number of pxe related cleanups and related re-organization.
- A few related pxe/sysboot/extlinux improvements
- Remove some dead code.
- Update Azure to use a newer Windows build environment
- Add a .get_maintainer.conf file
- A few minor TI SoC platform updates
This commit is contained in:
Tom Rini 2021-11-12 10:14:24 -05:00
commit 515bf78ff9
49 changed files with 882 additions and 726 deletions

View File

@ -1,5 +1,5 @@
variables:
windows_vm: vs2017-win2016
windows_vm: windows-2019
ubuntu_vm: ubuntu-18.04
macos_vm: macOS-10.15
ci_runner_image: trini/u-boot-gitlab-ci-runner:focal-20210921-05Oct2021

1
.get_maintainer.conf Normal file
View File

@ -0,0 +1 @@
--find-maintainer-files --maintainer-path=.

View File

@ -466,6 +466,8 @@ endmenu # General setup
source "api/Kconfig"
source "boot/Kconfig"
source "common/Kconfig"
source "cmd/Kconfig"

View File

@ -808,6 +808,7 @@ HAVE_VENDOR_COMMON_LIB = $(if $(wildcard $(srctree)/board/$(VENDOR)/common/Makef
libs-$(CONFIG_API) += api/
libs-$(HAVE_VENDOR_COMMON_LIB) += board/$(VENDOR)/common/
libs-y += boot/
libs-y += cmd/
libs-y += common/
libs-$(CONFIG_OF_EMBED) += dts/
@ -2104,7 +2105,7 @@ CLEAN_DIRS += $(MODVERDIR) \
$(filter-out include, $(shell ls -1 $d 2>/dev/null))))
CLEAN_FILES += include/bmp_logo.h include/bmp_logo_data.h tools/version.h \
boot* u-boot* MLO* SPL System.map fit-dtb.blob* \
u-boot* MLO* SPL System.map fit-dtb.blob* \
u-boot-ivt.img.log u-boot-dtb.imx.log SPL.log u-boot.imx.log \
lpc32xx-* bl31.c bl31.elf bl31_*.bin image.map tispl.bin* \
idbloader.img flash.bin flash.log defconfig keep-syms-lto.c

1
README
View File

@ -144,6 +144,7 @@ Directory Hierarchy:
/xtensa Files generic to Xtensa architecture
/api Machine/arch-independent API for external apps
/board Board-dependent files
/boot Support for images and booting
/cmd U-Boot commands functions
/common Misc architecture-independent functions
/configs Board default configuration files

View File

@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0+ or X11
/*
* Copyright (C) 2018 Grinn Sp. z o.o. -- http://www.grinn-global.com/
* Copyright (C) 2018-2021 Grinn Sp. z o.o. -- http://www.grinn-global.com/
* Author: Marcin Niestroj <m.niestroj@grinn-global.com>
*/
@ -9,5 +9,6 @@
/ {
chosen {
stdout-path = &uart0;
tick-timer = &timer2;
};
};

View File

@ -259,7 +259,8 @@ void show_boot_progress(int progress)
struct udevice *dev;
int ret;
if (progress < 0 || progress == BOOTSTAGE_ID_ENTER_CLI_LOOP) {
if ((progress < 0 && progress != -BOOTSTAGE_ID_NET_ETH_START) ||
progress == BOOTSTAGE_ID_ENTER_CLI_LOOP) {
ret = led_get_by_label("status-led-green", &dev);
if (ret == 0)
led_set_state(dev, LEDST_OFF);

37
boot/Makefile Normal file
View File

@ -0,0 +1,37 @@
# SPDX-License-Identifier: GPL-2.0+
#
# (C) Copyright 2004-2006
# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
ifndef CONFIG_SPL_BUILD
# This option is not just y/n - it can have a numeric value
ifdef CONFIG_BOOT_RETRY_TIME
obj-y += bootretry.o
endif
obj-$(CONFIG_CMD_BOOTM) += bootm.o bootm_os.o
obj-$(CONFIG_CMD_BOOTZ) += bootm.o bootm_os.o
obj-$(CONFIG_CMD_BOOTI) += bootm.o bootm_os.o
obj-$(CONFIG_CMD_PXE) += pxe_utils.o
obj-$(CONFIG_CMD_SYSBOOT) += pxe_utils.o
endif
obj-y += image.o image-board.o
obj-$(CONFIG_ANDROID_AB) += android_ab.o
obj-$(CONFIG_ANDROID_BOOT_IMAGE) += image-android.o image-android-dt.o
obj-$(CONFIG_$(SPL_TPL_)OF_LIBFDT) += image-fdt.o
obj-$(CONFIG_$(SPL_TPL_)FIT_SIGNATURE) += fdt_region.o
obj-$(CONFIG_$(SPL_TPL_)FIT) += image-fit.o
obj-$(CONFIG_$(SPL_)MULTI_DTB_FIT) += boot_fit.o common_fit.o
obj-$(CONFIG_$(SPL_TPL_)IMAGE_SIGN_INFO) += image-sig.o
obj-$(CONFIG_$(SPL_TPL_)FIT_SIGNATURE) += image-fit-sig.o
obj-$(CONFIG_$(SPL_TPL_)FIT_CIPHER) += image-cipher.o
obj-$(CONFIG_CMD_ADTIMG) += image-android-dt.o
ifdef CONFIG_SPL_BUILD
obj-$(CONFIG_SPL_LOAD_FIT) += common_fit.o
endif

View File

@ -138,28 +138,6 @@ static int do_bootm_netbsd(int flag, int argc, char *const argv[],
}
#endif /* CONFIG_BOOTM_NETBSD*/
#ifdef CONFIG_LYNXKDI
static int do_bootm_lynxkdi(int flag, int argc, char *const argv[],
bootm_headers_t *images)
{
image_header_t *hdr = &images->legacy_hdr_os_copy;
if (flag != BOOTM_STATE_OS_GO)
return 0;
#if defined(CONFIG_FIT)
if (!images->legacy_hdr_valid) {
fit_unsupported_reset("Lynx");
return 1;
}
#endif
lynxkdi_boot((image_header_t *)hdr);
return 1;
}
#endif /* CONFIG_LYNXKDI */
#ifdef CONFIG_BOOTM_RTEMS
static int do_bootm_rtems(int flag, int argc, char *const argv[],
bootm_headers_t *images)
@ -570,9 +548,6 @@ static boot_os_fn *boot_os[] = {
#ifdef CONFIG_BOOTM_NETBSD
[IH_OS_NETBSD] = do_bootm_netbsd,
#endif
#ifdef CONFIG_LYNXKDI
[IH_OS_LYNXOS] = do_bootm_lynxkdi,
#endif
#ifdef CONFIG_BOOTM_RTEMS
[IH_OS_RTEMS] = do_bootm_rtems,
#endif

View File

@ -106,7 +106,7 @@ static const table_entry_t uimage_os[] = {
{ IH_OS_INVALID, "invalid", "Invalid OS", },
{ IH_OS_ARM_TRUSTED_FIRMWARE, "arm-trusted-firmware", "ARM Trusted Firmware" },
{ IH_OS_LINUX, "linux", "Linux", },
#if defined(CONFIG_LYNXKDI) || defined(USE_HOSTCC)
#if defined(USE_HOSTCC)
{ IH_OS_LYNXOS, "lynxos", "LynxOS", },
#endif
{ IH_OS_NETBSD, "netbsd", "NetBSD", },

View File

@ -30,17 +30,34 @@
#define MAX_TFTP_PATH_LEN 512
bool is_pxe;
int pxe_get_file_size(ulong *sizep)
{
const char *val;
/*
* Convert an ethaddr from the environment to the format used by pxelinux
* filenames based on mac addresses. Convert's ':' to '-', and adds "01-" to
* the beginning of the ethernet address to indicate a hardware type of
* Ethernet. Also converts uppercase hex characters into lowercase, to match
* pxelinux's behavior.
val = from_env("filesize");
if (!val)
return -ENOENT;
if (strict_strtoul(val, 16, sizep) < 0)
return -EINVAL;
return 0;
}
/**
* format_mac_pxe() - obtain a MAC address in the PXE format
*
* Returns 1 for success, -ENOENT if 'ethaddr' is undefined in the
* environment, or some other value < 0 on error.
* This produces a MAC-address string in the format for the current ethernet
* device:
*
* 01-aa-bb-cc-dd-ee-ff
*
* where aa-ff is the MAC address in hex
*
* @outbuf: Buffer to write string to
* @outbuf_len: length of buffer
* @return 1 if OK, -ENOSPC if buffer is too small, -ENOENT is there is no
* current ethernet device
*/
int format_mac_pxe(char *outbuf, size_t outbuf_len)
{
@ -48,8 +65,7 @@ int format_mac_pxe(char *outbuf, size_t outbuf_len)
if (outbuf_len < 21) {
printf("outbuf is too small (%zd < 21)\n", outbuf_len);
return -EINVAL;
return -ENOSPC;
}
if (!eth_env_get_enetaddr_by_index("eth", eth_get_dev_index(), ethaddr))
@ -62,74 +78,35 @@ int format_mac_pxe(char *outbuf, size_t outbuf_len)
return 1;
}
/*
* Returns the directory the file specified in the bootfile env variable is
* in. If bootfile isn't defined in the environment, return NULL, which should
* be interpreted as "don't prepend anything to paths".
*/
static int get_bootfile_path(const char *file_path, char *bootfile_path,
size_t bootfile_path_size)
{
char *bootfile, *last_slash;
size_t path_len = 0;
/* Only syslinux allows absolute paths */
if (file_path[0] == '/' && !is_pxe)
goto ret;
bootfile = from_env("bootfile");
if (!bootfile)
goto ret;
last_slash = strrchr(bootfile, '/');
if (!last_slash)
goto ret;
path_len = (last_slash - bootfile) + 1;
if (bootfile_path_size < path_len) {
printf("bootfile_path too small. (%zd < %zd)\n",
bootfile_path_size, path_len);
return -1;
}
strncpy(bootfile_path, bootfile, path_len);
ret:
bootfile_path[path_len] = '\0';
return 1;
}
int (*do_getfile)(struct cmd_tbl *cmdtp, const char *file_path,
char *file_addr);
/*
/**
* get_relfile() - read a file relative to the PXE file
*
* As in pxelinux, paths to files referenced from files we retrieve are
* relative to the location of bootfile. get_relfile takes such a path and
* joins it with the bootfile path to get the full path to the target file. If
* the bootfile path is NULL, we use file_path as is.
*
* Returns 1 for success, or < 0 on error.
* @ctx: PXE context
* @file_path: File path to read (relative to the PXE file)
* @file_addr: Address to load file to
* @filesizep: If not NULL, returns the file size in bytes
* Returns 1 for success, or < 0 on error
*/
static int get_relfile(struct cmd_tbl *cmdtp, const char *file_path,
unsigned long file_addr)
static int get_relfile(struct pxe_context *ctx, const char *file_path,
unsigned long file_addr, ulong *filesizep)
{
size_t path_len;
char relfile[MAX_TFTP_PATH_LEN + 1];
char addr_buf[18];
int err;
ulong size;
int ret;
err = get_bootfile_path(file_path, relfile, sizeof(relfile));
if (file_path[0] == '/' && ctx->allow_abs_path)
*relfile = '\0';
else
strncpy(relfile, ctx->bootdir, MAX_TFTP_PATH_LEN);
if (err < 0)
return err;
path_len = strlen(file_path);
path_len += strlen(relfile);
path_len = strlen(file_path) + strlen(relfile);
if (path_len > MAX_TFTP_PATH_LEN) {
printf("Base path too long (%s%s)\n", relfile, file_path);
@ -143,42 +120,37 @@ static int get_relfile(struct cmd_tbl *cmdtp, const char *file_path,
sprintf(addr_buf, "%lx", file_addr);
return do_getfile(cmdtp, relfile, addr_buf);
ret = ctx->getfile(ctx, relfile, addr_buf, &size);
if (ret < 0)
return log_msg_ret("get", ret);
if (filesizep)
*filesizep = size;
return 1;
}
/*
* Retrieve the file at 'file_path' to the locate given by 'file_addr'. If
* 'bootfile' was specified in the environment, the path to bootfile will be
* prepended to 'file_path' and the resulting path will be used.
/**
* get_pxe_file() - read a file
*
* Returns 1 on success, or < 0 for error.
* The file is read and nul-terminated
*
* @ctx: PXE context
* @file_path: File path to read (relative to the PXE file)
* @file_addr: Address to load file to
* Returns 1 for success, or < 0 on error
*/
int get_pxe_file(struct cmd_tbl *cmdtp, const char *file_path,
unsigned long file_addr)
int get_pxe_file(struct pxe_context *ctx, const char *file_path,
ulong file_addr)
{
unsigned long config_file_size;
char *tftp_filesize;
ulong size;
int err;
char *buf;
err = get_relfile(cmdtp, file_path, file_addr);
err = get_relfile(ctx, file_path, file_addr, &size);
if (err < 0)
return err;
/*
* the file comes without a NUL byte at the end, so find out its size
* and add the NUL byte.
*/
tftp_filesize = from_env("filesize");
if (!tftp_filesize)
return -ENOENT;
if (strict_strtoul(tftp_filesize, 16, &config_file_size) < 0)
return -EINVAL;
buf = map_sysmem(file_addr + config_file_size, 1);
buf = map_sysmem(file_addr + size, 1);
*buf = '\0';
unmap_sysmem(buf);
@ -187,14 +159,15 @@ int get_pxe_file(struct cmd_tbl *cmdtp, const char *file_path,
#define PXELINUX_DIR "pxelinux.cfg/"
/*
* Retrieves a file in the 'pxelinux.cfg' folder. Since this uses get_pxe_file
* to do the hard work, the location of the 'pxelinux.cfg' folder is generated
* from the bootfile path, as described above.
/**
* get_pxelinux_path() - Get a file in the pxelinux.cfg/ directory
*
* Returns 1 on success or < 0 on error.
* @ctx: PXE context
* @file: Filename to process (relative to pxelinux.cfg/)
* Returns 1 for success, -ENAMETOOLONG if the resulting path is too long.
* or other value < 0 on other error
*/
int get_pxelinux_path(struct cmd_tbl *cmdtp, const char *file,
int get_pxelinux_path(struct pxe_context *ctx, const char *file,
unsigned long pxefile_addr_r)
{
size_t base_len = strlen(PXELINUX_DIR);
@ -208,45 +181,54 @@ int get_pxelinux_path(struct cmd_tbl *cmdtp, const char *file,
sprintf(path, PXELINUX_DIR "%s", file);
return get_pxe_file(cmdtp, path, pxefile_addr_r);
return get_pxe_file(ctx, path, pxefile_addr_r);
}
/*
/**
* get_relfile_envaddr() - read a file to an address in an env var
*
* Wrapper to make it easier to store the file at file_path in the location
* specified by envaddr_name. file_path will be joined to the bootfile path,
* if any is specified.
*
* Returns 1 on success or < 0 on error.
* @ctx: PXE context
* @file_path: File path to read (relative to the PXE file)
* @envaddr_name: Name of environment variable which contains the address to
* load to
* @filesizep: Returns the file size in bytes
* Returns 1 on success, -ENOENT if @envaddr_name does not exist as an
* environment variable, -EINVAL if its format is not valid hex, or other
* value < 0 on other error
*/
static int get_relfile_envaddr(struct cmd_tbl *cmdtp, const char *file_path,
const char *envaddr_name)
static int get_relfile_envaddr(struct pxe_context *ctx, const char *file_path,
const char *envaddr_name, ulong *filesizep)
{
unsigned long file_addr;
char *envaddr;
envaddr = from_env(envaddr_name);
if (!envaddr)
return -ENOENT;
if (strict_strtoul(envaddr, 16, &file_addr) < 0)
return -EINVAL;
return get_relfile(cmdtp, file_path, file_addr);
return get_relfile(ctx, file_path, file_addr, filesizep);
}
/*
/**
* label_create() - crate a new PXE label
*
* Allocates memory for and initializes a pxe_label. This uses malloc, so the
* result must be free()'d to reclaim the memory.
*
* Returns NULL if malloc fails.
* Returns a pointer to the label, or NULL if out of memory
*/
static struct pxe_label *label_create(void)
{
struct pxe_label *label;
label = malloc(sizeof(struct pxe_label));
if (!label)
return NULL;
@ -255,48 +237,39 @@ static struct pxe_label *label_create(void)
return label;
}
/*
* Free the memory used by a pxe_label, including that used by its name,
* kernel, append and initrd members, if they're non NULL.
/**
* label_destroy() - free the memory used by a pxe_label
*
* This frees @label itself as well as memory used by its name,
* kernel, config, append, initrd, fdt, fdtdir and fdtoverlay members, if
* they're non-NULL.
*
* So - be sure to only use dynamically allocated memory for the members of
* the pxe_label struct, unless you want to clean it up first. These are
* currently only created by the pxe file parsing code.
*
* @label: Label to free
*/
static void label_destroy(struct pxe_label *label)
{
if (label->name)
free(label->name);
if (label->kernel)
free(label->kernel);
if (label->config)
free(label->config);
if (label->append)
free(label->append);
if (label->initrd)
free(label->initrd);
if (label->fdt)
free(label->fdt);
if (label->fdtdir)
free(label->fdtdir);
if (label->fdtoverlays)
free(label->fdtoverlays);
free(label->name);
free(label->kernel);
free(label->config);
free(label->append);
free(label->initrd);
free(label->fdt);
free(label->fdtdir);
free(label->fdtoverlays);
free(label);
}
/*
* Print a label and its string members if they're defined.
/**
* label_print() - Print a label and its string members if they're defined
*
* This is passed as a callback to the menu code for displaying each
* menu entry.
*
* @data: Label to print (is cast to struct pxe_label *)
*/
static void label_print(void *data)
{
@ -306,21 +279,22 @@ static void label_print(void *data)
printf("%s:\t%s\n", label->num, c);
}
/*
* Boot a label that specified 'localboot'. This requires that the 'localcmd'
* environment variable is defined. Its contents will be executed as U-Boot
* command. If the label specified an 'append' line, its contents will be
* used to overwrite the contents of the 'bootargs' environment variable prior
* to running 'localcmd'.
/**
* label_localboot() - Boot a label that specified 'localboot'
*
* Returns 1 on success or < 0 on error.
* This requires that the 'localcmd' environment variable is defined. Its
* contents will be executed as U-Boot commands. If the label specified an
* 'append' line, its contents will be used to overwrite the contents of the
* 'bootargs' environment variable prior to running 'localcmd'.
*
* @label: Label to process
* Returns 1 on success or < 0 on error
*/
static int label_localboot(struct pxe_label *label)
{
char *localcmd;
localcmd = from_env("localcmd");
if (!localcmd)
return -ENOENT;
@ -337,11 +311,15 @@ static int label_localboot(struct pxe_label *label)
return run_command_list(localcmd, strlen(localcmd), 0);
}
/*
* Loads fdt overlays specified in 'fdtoverlays'.
/**
* label_boot_fdtoverlay() - Loads fdt overlays specified in 'fdtoverlays'
*
* @ctx: PXE context
* @label: Label to process
*/
#ifdef CONFIG_OF_LIBFDT_OVERLAY
static void label_boot_fdtoverlay(struct cmd_tbl *cmdtp, struct pxe_label *label)
static void label_boot_fdtoverlay(struct pxe_context *ctx,
struct pxe_label *label)
{
char *fdtoverlay = label->fdtoverlays;
struct fdt_header *working_fdt;
@ -391,8 +369,8 @@ static void label_boot_fdtoverlay(struct cmd_tbl *cmdtp, struct pxe_label *label
goto skip_overlay;
/* Load overlay file */
err = get_relfile_envaddr(cmdtp, overlayfile,
"fdtoverlay_addr_r");
err = get_relfile_envaddr(ctx, overlayfile, "fdtoverlay_addr_r",
NULL);
if (err < 0) {
printf("Failed loading overlay %s\n", overlayfile);
goto skip_overlay;
@ -423,8 +401,8 @@ skip_overlay:
}
#endif
/*
* Boot according to the contents of a pxe_label.
/**
* label_boot() - Boot according to the contents of a pxe_label
*
* If we can't boot for any reason, we return. A successful boot never
* returns.
@ -437,8 +415,13 @@ skip_overlay:
*
* If the label specifies an 'append' line, its contents will overwrite that
* of the 'bootargs' environment variable.
*
* @ctx: PXE context
* @label: Label to process
* Returns does not return on success, otherwise returns 0 if a localboot
* label was processed, or 1 on error
*/
static int label_boot(struct cmd_tbl *cmdtp, struct pxe_label *label)
static int label_boot(struct pxe_context *ctx, struct pxe_label *label)
{
char *bootm_argv[] = { "bootm", NULL, NULL, NULL, NULL };
char *zboot_argv[] = { "zboot", NULL, "0", NULL, NULL };
@ -472,21 +455,25 @@ static int label_boot(struct cmd_tbl *cmdtp, struct pxe_label *label)
}
if (label->initrd) {
if (get_relfile_envaddr(cmdtp, label->initrd, "ramdisk_addr_r") < 0) {
ulong size;
if (get_relfile_envaddr(ctx, label->initrd, "ramdisk_addr_r",
&size) < 0) {
printf("Skipping %s for failure retrieving initrd\n",
label->name);
return 1;
}
initrd_addr_str = env_get("ramdisk_addr_r");
strncpy(initrd_filesize, env_get("filesize"), 9);
strcpy(initrd_filesize, simple_xtoa(size));
strncpy(initrd_str, initrd_addr_str, 18);
strcat(initrd_str, ":");
strncat(initrd_str, initrd_filesize, 9);
}
if (get_relfile_envaddr(cmdtp, label->kernel, "kernel_addr_r") < 0) {
if (get_relfile_envaddr(ctx, label->kernel, "kernel_addr_r",
NULL) < 0) {
printf("Skipping %s for failure retrieving kernel\n",
label->name);
return 1;
@ -627,8 +614,8 @@ static int label_boot(struct cmd_tbl *cmdtp, struct pxe_label *label)
}
if (fdtfile) {
int err = get_relfile_envaddr(cmdtp, fdtfile,
"fdt_addr_r");
int err = get_relfile_envaddr(ctx, fdtfile,
"fdt_addr_r", NULL);
free(fdtfilefree);
if (err < 0) {
@ -643,7 +630,7 @@ static int label_boot(struct cmd_tbl *cmdtp, struct pxe_label *label)
#ifdef CONFIG_OF_LIBFDT_OVERLAY
if (label->fdtoverlays)
label_boot_fdtoverlay(cmdtp, label);
label_boot_fdtoverlay(ctx, label);
#endif
} else {
bootm_argv[3] = NULL;
@ -675,28 +662,26 @@ static int label_boot(struct cmd_tbl *cmdtp, struct pxe_label *label)
buf = map_sysmem(kernel_addr_r, 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);
do_bootm(ctx->cmdtp, 0, bootm_argc, bootm_argv);
/* Try booting an AArch64 Linux kernel image */
else if (IS_ENABLED(CONFIG_CMD_BOOTI))
do_booti(cmdtp, 0, bootm_argc, bootm_argv);
do_booti(ctx->cmdtp, 0, bootm_argc, bootm_argv);
/* Try booting a Image */
else if (IS_ENABLED(CONFIG_CMD_BOOTZ))
do_bootz(cmdtp, 0, bootm_argc, bootm_argv);
do_bootz(ctx->cmdtp, 0, bootm_argc, bootm_argv);
/* Try booting an x86_64 Linux kernel image */
else if (IS_ENABLED(CONFIG_CMD_ZBOOT))
do_zboot_parent(cmdtp, 0, zboot_argc, zboot_argv, NULL);
do_zboot_parent(ctx->cmdtp, 0, zboot_argc, zboot_argv, NULL);
unmap_sysmem(buf);
cleanup:
if (fit_addr)
free(fit_addr);
free(fit_addr);
return 1;
}
/*
* Tokens for the pxe file parser.
*/
/** enum token_type - Tokens for the pxe file parser */
enum token_type {
T_EOL,
T_STRING,
@ -722,17 +707,13 @@ enum token_type {
T_INVALID
};
/*
* A token - given by a value and a type.
*/
/** struct token - token - given by a value and a type */
struct token {
char *val;
enum token_type type;
};
/*
* Keywords recognized.
*/
/* Keywords recognized */
static const struct token keywords[] = {
{"menu", T_MENU},
{"title", T_TITLE},
@ -757,7 +738,9 @@ static const struct token keywords[] = {
{NULL, T_INVALID}
};
/*
/**
* enum lex_state - lexer state
*
* Since pxe(linux) files don't have a token to identify the start of a
* literal, we have to keep track of when we're in a state where a literal is
* expected vs when we're in a state a keyword is expected.
@ -768,11 +751,10 @@ enum lex_state {
L_SLITERAL
};
/*
* get_string retrieves a string from *p and stores it as a token in
* *t.
/**
* get_string() - retrieves a string from *p and stores it as a token in *t.
*
* get_string used for scanning both string literals and keywords.
* This is used for scanning both string literals and keywords.
*
* Characters from *p are copied into t-val until a character equal to
* delim is found, or a NUL byte is reached. If delim has the special value of
@ -785,9 +767,15 @@ enum lex_state {
* The location of *p is updated to point to the first character after the end
* of the token - the ending delimiter.
*
* On success, the new value of t->val is returned. Memory for t->val is
* allocated using malloc and must be free()'d to reclaim it. If insufficient
* memory is available, NULL is returned.
* Memory for t->val is allocated using malloc and must be free()'d to reclaim
* it.
*
* @p: Points to a pointer to the current position in the input being processed.
* Updated to point at the first character after the current token
* @t: Pointers to a token to fill in
* @delim: Delimiter character to look for, either newline or space
* @lower: true to convert the string to lower case when storing
* Returns the new value of t->val, on success, NULL if out of memory
*/
static char *get_string(char **p, struct token *t, char delim, int lower)
{
@ -802,7 +790,6 @@ static char *get_string(char **p, struct token *t, char delim, int lower)
*/
b = *p;
e = *p;
while (*e) {
if ((delim == ' ' && isspace(*e)) || delim == *e)
break;
@ -828,18 +815,18 @@ static char *get_string(char **p, struct token *t, char delim, int lower)
t->val[len] = '\0';
/*
* Update *p so the caller knows where to continue scanning.
*/
/* Update *p so the caller knows where to continue scanning */
*p = e;
t->type = T_STRING;
return t->val;
}
/*
* Populate a keyword token with a type and value.
/**
* get_keyword() - Populate a keyword token with a type and value
*
* Updates the ->type field based on the keyword string in @val
* @t: Token to populate
*/
static void get_keyword(struct token *t)
{
@ -853,11 +840,14 @@ static void get_keyword(struct token *t)
}
}
/*
* Get the next token. We have to keep track of which state we're in to know
* if we're looking to get a string literal or a keyword.
/**
* get_token() - Get the next token
*
* *p is updated to point at the first character after the current token.
* We have to keep track of which state we're in to know if we're looking to get
* a string literal or a keyword.
*
* @p: Points to a pointer to the current position in the input being processed.
* Updated to point at the first character after the current token
*/
static void get_token(char **p, struct token *t, enum lex_state state)
{
@ -901,8 +891,13 @@ static void get_token(char **p, struct token *t, enum lex_state state)
*p = c;
}
/*
* Increment *c until we get to the end of the current line, or EOF.
/**
* eol_or_eof() - Find end of line
*
* Increment *c until we get to the end of the current line, or EOF
*
* @c: Points to a pointer to the current position in the input being processed.
* Updated to point at the first character after the current token
*/
static void eol_or_eof(char **c)
{
@ -947,7 +942,6 @@ static int parse_integer(char **c, int *dst)
char *s = *c;
get_token(c, &t, L_SLITERAL);
if (t.type != T_STRING) {
printf("Expected string: %.*s\n", (int)(*c - s), s);
return -EINVAL;
@ -960,7 +954,7 @@ static int parse_integer(char **c, int *dst)
return 1;
}
static int parse_pxefile_top(struct cmd_tbl *cmdtp, char *p, unsigned long base,
static int parse_pxefile_top(struct pxe_context *ctx, char *p, ulong base,
struct pxe_menu *cfg, int nest_level);
/*
@ -971,7 +965,7 @@ static int parse_pxefile_top(struct cmd_tbl *cmdtp, char *p, unsigned long base,
* include, nest_level has already been incremented and doesn't need to be
* incremented here.
*/
static int handle_include(struct cmd_tbl *cmdtp, char **c, unsigned long base,
static int handle_include(struct pxe_context *ctx, char **c, unsigned long base,
struct pxe_menu *cfg, int nest_level)
{
char *include_path;
@ -981,21 +975,19 @@ static int handle_include(struct cmd_tbl *cmdtp, char **c, unsigned long base,
int ret;
err = parse_sliteral(c, &include_path);
if (err < 0) {
printf("Expected include path: %.*s\n", (int)(*c - s), s);
return err;
}
err = get_pxe_file(cmdtp, include_path, base);
err = get_pxe_file(ctx, include_path, base);
if (err < 0) {
printf("Couldn't retrieve %s\n", include_path);
return err;
}
buf = map_sysmem(base, 0);
ret = parse_pxefile_top(cmdtp, buf, base, cfg, nest_level);
ret = parse_pxefile_top(ctx, buf, base, cfg, nest_level);
unmap_sysmem(buf);
return ret;
@ -1011,7 +1003,7 @@ static int handle_include(struct cmd_tbl *cmdtp, char **c, unsigned long base,
* 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(struct cmd_tbl *cmdtp, char **c, struct pxe_menu *cfg,
static int parse_menu(struct pxe_context *ctx, char **c, struct pxe_menu *cfg,
unsigned long base, int nest_level)
{
struct token t;
@ -1027,7 +1019,7 @@ static int parse_menu(struct cmd_tbl *cmdtp, char **c, struct pxe_menu *cfg,
break;
case T_INCLUDE:
err = handle_include(cmdtp, c, base, cfg, nest_level + 1);
err = handle_include(ctx, c, base, cfg, nest_level + 1);
break;
case T_BACKGROUND:
@ -1038,7 +1030,6 @@ static int parse_menu(struct cmd_tbl *cmdtp, char **c, struct pxe_menu *cfg,
printf("Ignoring malformed menu command: %.*s\n",
(int)(*c - s), s);
}
if (err < 0)
return err;
@ -1229,7 +1220,7 @@ static int parse_label(char **c, struct pxe_menu *cfg)
*
* Returns 1 on success, < 0 on error.
*/
static int parse_pxefile_top(struct cmd_tbl *cmdtp, char *p, unsigned long base,
static int parse_pxefile_top(struct pxe_context *ctx, char *p, unsigned long base,
struct pxe_menu *cfg, int nest_level)
{
struct token t;
@ -1252,7 +1243,7 @@ static int parse_pxefile_top(struct cmd_tbl *cmdtp, char *p, unsigned long base,
switch (t.type) {
case T_MENU:
cfg->prompt = 1;
err = parse_menu(cmdtp, &p, cfg,
err = parse_menu(ctx, &p, cfg,
base + ALIGN(strlen(b) + 1, 4),
nest_level);
break;
@ -1279,7 +1270,7 @@ static int parse_pxefile_top(struct cmd_tbl *cmdtp, char *p, unsigned long base,
break;
case T_INCLUDE:
err = handle_include(cmdtp, &p,
err = handle_include(ctx, &p,
base + ALIGN(strlen(b), 4), cfg,
nest_level + 1);
break;
@ -1306,18 +1297,14 @@ static int parse_pxefile_top(struct cmd_tbl *cmdtp, char *p, unsigned long base,
}
/*
* Free the memory used by a pxe_menu and its labels.
*/
void destroy_pxe_menu(struct pxe_menu *cfg)
{
struct list_head *pos, *n;
struct pxe_label *label;
if (cfg->title)
free(cfg->title);
if (cfg->default_label)
free(cfg->default_label);
free(cfg->title);
free(cfg->default_label);
list_for_each_safe(pos, n, &cfg->labels) {
label = list_entry(pos, struct pxe_label, list);
@ -1328,23 +1315,13 @@ void destroy_pxe_menu(struct pxe_menu *cfg)
free(cfg);
}
/*
* Entry point for parsing a pxe file. This is only used for the top level
* file.
*
* Returns NULL if there is an error, otherwise, returns a pointer to a
* pxe_menu struct populated with the results of parsing the pxe file (and any
* files it includes). The resulting pxe_menu struct can be free()'d by using
* the destroy_pxe_menu() function.
*/
struct pxe_menu *parse_pxefile(struct cmd_tbl *cmdtp, unsigned long menucfg)
struct pxe_menu *parse_pxefile(struct pxe_context *ctx, unsigned long menucfg)
{
struct pxe_menu *cfg;
char *buf;
int r;
cfg = malloc(sizeof(struct pxe_menu));
if (!cfg)
return NULL;
@ -1353,9 +1330,8 @@ struct pxe_menu *parse_pxefile(struct cmd_tbl *cmdtp, unsigned long menucfg)
INIT_LIST_HEAD(&cfg->labels);
buf = map_sysmem(menucfg, 0);
r = parse_pxefile_top(cmdtp, buf, menucfg, cfg, 1);
r = parse_pxefile_top(ctx, buf, menucfg, cfg, 1);
unmap_sysmem(buf);
if (r < 0) {
destroy_pxe_menu(cfg);
return NULL;
@ -1382,7 +1358,6 @@ static struct menu *pxe_menu_to_menu(struct pxe_menu *cfg)
*/
m = menu_create(cfg->title, DIV_ROUND_UP(cfg->timeout, 10),
cfg->prompt, NULL, label_print, NULL, NULL);
if (!m)
return NULL;
@ -1421,7 +1396,8 @@ static struct menu *pxe_menu_to_menu(struct pxe_menu *cfg)
/*
* Try to boot any labels we have yet to attempt to boot.
*/
static void boot_unattempted_labels(struct cmd_tbl *cmdtp, struct pxe_menu *cfg)
static void boot_unattempted_labels(struct pxe_context *ctx,
struct pxe_menu *cfg)
{
struct list_head *pos;
struct pxe_label *label;
@ -1430,23 +1406,11 @@ static void boot_unattempted_labels(struct cmd_tbl *cmdtp, struct pxe_menu *cfg)
label = list_entry(pos, struct pxe_label, list);
if (!label->attempted)
label_boot(cmdtp, label);
label_boot(ctx, label);
}
}
/*
* Boot the system as prescribed by a pxe_menu.
*
* Use the menu system to either get the user's choice or the default, based
* on config or user input. If there is no default or user's choice,
* attempted to boot labels in the order they were given in pxe files.
* If the default or user's choice fails to boot, attempt to boot other
* labels in the order they were given in pxe files.
*
* If this function returns, there weren't any labels that successfully
* booted, or the user interrupted the menu selection via ctrl+c.
*/
void handle_pxe_menu(struct cmd_tbl *cmdtp, struct pxe_menu *cfg)
void handle_pxe_menu(struct pxe_context *ctx, struct pxe_menu *cfg)
{
void *choice;
struct menu *m;
@ -1455,7 +1419,7 @@ void handle_pxe_menu(struct cmd_tbl *cmdtp, struct pxe_menu *cfg)
if (IS_ENABLED(CONFIG_CMD_BMP)) {
/* display BMP if available */
if (cfg->bmp) {
if (get_relfile(cmdtp, cfg->bmp, image_load_addr)) {
if (get_relfile(ctx, cfg->bmp, image_load_addr, NULL)) {
if (CONFIG_IS_ENABLED(CMD_CLS))
run_command("cls", 0);
bmp_display(image_load_addr,
@ -1472,7 +1436,6 @@ void handle_pxe_menu(struct cmd_tbl *cmdtp, struct pxe_menu *cfg)
return;
err = menu_get_choice(m, &choice);
menu_destroy(m);
/*
@ -1487,12 +1450,67 @@ void handle_pxe_menu(struct cmd_tbl *cmdtp, struct pxe_menu *cfg)
*/
if (err == 1) {
err = label_boot(cmdtp, choice);
err = label_boot(ctx, choice);
if (!err)
return;
} else if (err != -ENOENT) {
return;
}
boot_unattempted_labels(cmdtp, cfg);
boot_unattempted_labels(ctx, cfg);
}
int pxe_setup_ctx(struct pxe_context *ctx, struct cmd_tbl *cmdtp,
pxe_getfile_func getfile, void *userdata,
bool allow_abs_path, const char *bootfile)
{
const char *last_slash;
size_t path_len = 0;
memset(ctx, '\0', sizeof(*ctx));
ctx->cmdtp = cmdtp;
ctx->getfile = getfile;
ctx->userdata = userdata;
ctx->allow_abs_path = allow_abs_path;
/* figure out the boot directory, if there is one */
if (bootfile && strlen(bootfile) >= MAX_TFTP_PATH_LEN)
return -ENOSPC;
ctx->bootdir = strdup(bootfile ? bootfile : "");
if (!ctx->bootdir)
return -ENOMEM;
if (bootfile) {
last_slash = strrchr(bootfile, '/');
if (last_slash)
path_len = (last_slash - bootfile) + 1;
}
ctx->bootdir[path_len] = '\0';
return 0;
}
void pxe_destroy_ctx(struct pxe_context *ctx)
{
free(ctx->bootdir);
}
int pxe_process(struct pxe_context *ctx, ulong pxefile_addr_r, bool prompt)
{
struct pxe_menu *cfg;
cfg = parse_pxefile(ctx, pxefile_addr_r);
if (!cfg) {
printf("Error parsing config file\n");
return 1;
}
if (prompt)
cfg->prompt = 1;
handle_pxe_menu(ctx, cfg);
destroy_pxe_menu(cfg);
return 0;
}

View File

@ -123,7 +123,7 @@ obj-$(CONFIG_CMD_PINMUX) += pinmux.o
obj-$(CONFIG_CMD_PMC) += pmc.o
obj-$(CONFIG_CMD_PSTORE) += pstore.o
obj-$(CONFIG_CMD_PWM) += pwm.o
obj-$(CONFIG_CMD_PXE) += pxe.o pxe_utils.o
obj-$(CONFIG_CMD_PXE) += pxe.o
obj-$(CONFIG_CMD_WOL) += wol.o
obj-$(CONFIG_CMD_QFW) += qfw.o
obj-$(CONFIG_CMD_READ) += read.o
@ -145,7 +145,7 @@ obj-$(CONFIG_CMD_SETEXPR_FMT) += printf.o
obj-$(CONFIG_CMD_SPI) += spi.o
obj-$(CONFIG_CMD_STRINGS) += strings.o
obj-$(CONFIG_CMD_SMC) += smccc.o
obj-$(CONFIG_CMD_SYSBOOT) += sysboot.o pxe_utils.o
obj-$(CONFIG_CMD_SYSBOOT) += sysboot.o
obj-$(CONFIG_CMD_STACKPROTECTOR_TEST) += stackprot_test.o
obj-$(CONFIG_CMD_TERMINAL) += terminal.o
obj-$(CONFIG_CMD_TIME) += time.o

136
cmd/pxe.c
View File

@ -24,16 +24,21 @@ const char *pxe_default_paths[] = {
NULL
};
static int do_get_tftp(struct cmd_tbl *cmdtp, const char *file_path,
char *file_addr)
static int do_get_tftp(struct pxe_context *ctx, const char *file_path,
char *file_addr, ulong *sizep)
{
char *tftp_argv[] = {"tftp", NULL, NULL, NULL};
int ret;
tftp_argv[1] = file_addr;
tftp_argv[2] = (void *)file_path;
if (do_tftpb(cmdtp, 0, 3, tftp_argv))
if (do_tftpb(ctx->cmdtp, 0, 3, tftp_argv))
return -ENOENT;
ret = pxe_get_file_size(sizep);
if (ret)
return log_msg_ret("tftp", ret);
ctx->pxe_file_size = *sizep;
return 1;
}
@ -43,7 +48,7 @@ static int do_get_tftp(struct cmd_tbl *cmdtp, const char *file_path,
*
* Returns 1 on success or < 0 on error.
*/
static int pxe_uuid_path(struct cmd_tbl *cmdtp, unsigned long pxefile_addr_r)
static int pxe_uuid_path(struct pxe_context *ctx, unsigned long pxefile_addr_r)
{
char *uuid_str;
@ -52,7 +57,7 @@ static int pxe_uuid_path(struct cmd_tbl *cmdtp, unsigned long pxefile_addr_r)
if (!uuid_str)
return -ENOENT;
return get_pxelinux_path(cmdtp, uuid_str, pxefile_addr_r);
return get_pxelinux_path(ctx, uuid_str, pxefile_addr_r);
}
/*
@ -61,7 +66,7 @@ static int pxe_uuid_path(struct cmd_tbl *cmdtp, unsigned long pxefile_addr_r)
*
* Returns 1 on success or < 0 on error.
*/
static int pxe_mac_path(struct cmd_tbl *cmdtp, unsigned long pxefile_addr_r)
static int pxe_mac_path(struct pxe_context *ctx, unsigned long pxefile_addr_r)
{
char mac_str[21];
int err;
@ -71,7 +76,7 @@ static int pxe_mac_path(struct cmd_tbl *cmdtp, unsigned long pxefile_addr_r)
if (err < 0)
return err;
return get_pxelinux_path(cmdtp, mac_str, pxefile_addr_r);
return get_pxelinux_path(ctx, mac_str, pxefile_addr_r);
}
/*
@ -81,7 +86,7 @@ static int pxe_mac_path(struct cmd_tbl *cmdtp, unsigned long pxefile_addr_r)
*
* Returns 1 on success or < 0 on error.
*/
static int pxe_ipaddr_paths(struct cmd_tbl *cmdtp, unsigned long pxefile_addr_r)
static int pxe_ipaddr_paths(struct pxe_context *ctx, unsigned long pxefile_addr_r)
{
char ip_addr[9];
int mask_pos, err;
@ -89,7 +94,7 @@ static int pxe_ipaddr_paths(struct cmd_tbl *cmdtp, unsigned long pxefile_addr_r)
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);
err = get_pxelinux_path(ctx, ip_addr, pxefile_addr_r);
if (err > 0)
return err;
@ -99,6 +104,49 @@ static int pxe_ipaddr_paths(struct cmd_tbl *cmdtp, unsigned long pxefile_addr_r)
return -ENOENT;
}
int pxe_get(ulong pxefile_addr_r, char **bootdirp, ulong *sizep)
{
struct cmd_tbl cmdtp[] = {}; /* dummy */
struct pxe_context ctx;
int i;
if (pxe_setup_ctx(&ctx, cmdtp, do_get_tftp, NULL, false,
env_get("bootfile")))
return -ENOMEM;
/*
* Keep trying paths until we successfully get a file we're looking
* for.
*/
if (pxe_uuid_path(&ctx, pxefile_addr_r) > 0 ||
pxe_mac_path(&ctx, pxefile_addr_r) > 0 ||
pxe_ipaddr_paths(&ctx, pxefile_addr_r) > 0)
goto done;
i = 0;
while (pxe_default_paths[i]) {
if (get_pxelinux_path(&ctx, pxe_default_paths[i],
pxefile_addr_r) > 0)
goto done;
i++;
}
pxe_destroy_ctx(&ctx);
return -ENOENT;
done:
*bootdirp = env_get("bootfile");
/*
* The PXE file size is returned but not the name. It is probably not
* that useful.
*/
*sizep = ctx.pxe_file_size;
pxe_destroy_ctx(&ctx);
return 0;
}
/*
* Entry point for the 'pxe get' command.
* This Follows pxelinux's rules to download a config file from a tftp server.
@ -117,10 +165,10 @@ static int
do_pxe_get(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
{
char *pxefile_addr_str;
unsigned long pxefile_addr_r;
int err, i = 0;
do_getfile = do_get_tftp;
ulong pxefile_addr_r;
char *fname;
ulong size;
int ret;
if (argc != 1)
return CMD_RET_USAGE;
@ -130,35 +178,25 @@ do_pxe_get(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
if (!pxefile_addr_str)
return 1;
err = strict_strtoul(pxefile_addr_str, 16,
ret = strict_strtoul(pxefile_addr_str, 16,
(unsigned long *)&pxefile_addr_r);
if (err < 0)
if (ret < 0)
return 1;
/*
* Keep trying paths until we successfully get a file we're looking
* for.
*/
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;
ret = pxe_get(pxefile_addr_r, &fname, &size);
switch (ret) {
case 0:
printf("Config file '%s' found\n", fname);
break;
case -ENOMEM:
printf("Out of memory\n");
return CMD_RET_FAILURE;
default:
printf("Config file not found\n");
return CMD_RET_FAILURE;
}
while (pxe_default_paths[i]) {
if (get_pxelinux_path(cmdtp, pxe_default_paths[i],
pxefile_addr_r) > 0) {
printf("Config file found\n");
return 0;
}
i++;
}
printf("Config file not found\n");
return 1;
return 0;
}
/*
@ -170,10 +208,9 @@ static int
do_pxe_boot(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
{
unsigned long pxefile_addr_r;
struct pxe_menu *cfg;
char *pxefile_addr_str;
do_getfile = do_get_tftp;
struct pxe_context ctx;
int ret;
if (argc == 1) {
pxefile_addr_str = from_env("pxefile_addr_r");
@ -191,16 +228,15 @@ do_pxe_boot(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
return 1;
}
cfg = parse_pxefile(cmdtp, pxefile_addr_r);
if (!cfg) {
printf("Error parsing config file\n");
return 1;
if (pxe_setup_ctx(&ctx, cmdtp, do_get_tftp, NULL, false,
env_get("bootfile"))) {
printf("Out of memory\n");
return CMD_RET_FAILURE;
}
handle_pxe_menu(cmdtp, cfg);
destroy_pxe_menu(cfg);
ret = pxe_process(&ctx, pxefile_addr_r, false);
pxe_destroy_ctx(&ctx);
if (ret)
return CMD_RET_FAILURE;
copy_filename(net_boot_file_name, "", sizeof(net_boot_file_name));
@ -233,8 +269,6 @@ static int do_pxe(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
if (argc < 2)
return CMD_RET_USAGE;
is_pxe = true;
/* drop initial "pxe" arg */
argc--;
argv++;

View File

@ -1,91 +0,0 @@
/* SPDX-License-Identifier: GPL-2.0+ */
#ifndef __PXE_UTILS_H
#define __PXE_UTILS_H
#include <linux/list.h>
/*
* A note on the pxe file parser.
*
* We're parsing files that use syslinux grammar, which has a few quirks.
* String literals must be recognized based on context - there is no
* quoting or escaping support. There's also nothing to explicitly indicate
* when a label section completes. We deal with that by ending a label
* section whenever we see a line that doesn't include.
*
* As with the syslinux family, this same file format could be reused in the
* future for non pxe purposes. The only action it takes during parsing that
* would throw this off is handling of include files. It assumes we're using
* pxe, and does a tftp download of a file listed as an include file in the
* middle of the parsing operation. That could be handled by refactoring it to
* take a 'include file getter' function.
*/
/*
* Describes a single label given in a pxe file.
*
* Create these with the 'label_create' function given below.
*
* name - the name of the menu as given on the 'menu label' line.
* kernel - the path to the kernel file to use for this label.
* append - kernel command line to use when booting this label
* initrd - path to the initrd to use for this label.
* attempted - 0 if we haven't tried to boot this label, 1 if we have.
* localboot - 1 if this label specified 'localboot', 0 otherwise.
* list - lets these form a list, which a pxe_menu struct will hold.
*/
struct pxe_label {
char num[4];
char *name;
char *menu;
char *kernel;
char *config;
char *append;
char *initrd;
char *fdt;
char *fdtdir;
char *fdtoverlays;
int ipappend;
int attempted;
int localboot;
int localboot_val;
struct list_head list;
};
/*
* Describes a pxe menu as given via pxe files.
*
* 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
* interrupted. If 1, always prompt for a choice regardless of
* timeout.
* labels - a list of labels defined for the menu.
*/
struct pxe_menu {
char *title;
char *default_label;
char *bmp;
int timeout;
int prompt;
struct list_head labels;
};
extern bool is_pxe;
extern int (*do_getfile)(struct cmd_tbl *cmdtp, const char *file_path,
char *file_addr);
void destroy_pxe_menu(struct pxe_menu *cfg);
int get_pxe_file(struct cmd_tbl *cmdtp, const char *file_path,
unsigned long file_addr);
int get_pxelinux_path(struct cmd_tbl *cmdtp, const char *file,
unsigned long pxefile_addr_r);
void handle_pxe_menu(struct cmd_tbl *cmdtp, struct pxe_menu *cfg);
struct pxe_menu *parse_pxefile(struct cmd_tbl *cmdtp, unsigned long menucfg);
int format_mac_pxe(char *outbuf, size_t outbuf_len);
#endif /* __PXE_UTILS_H */

View File

@ -4,50 +4,42 @@
#include <command.h>
#include <env.h>
#include <fs.h>
#include "pxe_utils.h"
#include <pxe_utils.h>
static char *fs_argv[5];
/**
* struct sysboot_info - useful information for sysboot helpers
*
* @fstype: Filesystem type (FS_TYPE_...)
* @ifname: Interface name (e.g. "ide", "scsi")
* @dev_part_str is in the format:
* <dev>.<hw_part>:<part> where <dev> is the device number,
* <hw_part> is the optional hardware partition number and
* <part> is the partition number
*/
struct sysboot_info {
int fstype;
const char *ifname;
const char *dev_part_str;
};
static int do_get_ext2(struct cmd_tbl *cmdtp, const char *file_path,
char *file_addr)
static int sysboot_read_file(struct pxe_context *ctx, const char *file_path,
char *file_addr, ulong *sizep)
{
#ifdef CONFIG_CMD_EXT2
fs_argv[0] = "ext2load";
fs_argv[3] = file_addr;
fs_argv[4] = (void *)file_path;
struct sysboot_info *info = ctx->userdata;
loff_t len_read;
ulong addr;
int ret;
if (!do_ext2load(cmdtp, 0, 5, fs_argv))
return 1;
#endif
return -ENOENT;
}
addr = simple_strtoul(file_addr, NULL, 16);
ret = fs_set_blk_dev(info->ifname, info->dev_part_str, info->fstype);
if (ret)
return ret;
ret = fs_read(file_path, addr, 0, 0, &len_read);
if (ret)
return ret;
*sizep = len_read;
static int do_get_fat(struct cmd_tbl *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(cmdtp, 0, 5, fs_argv))
return 1;
#endif
return -ENOENT;
}
static int do_get_any(struct cmd_tbl *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;
return 0;
}
/*
@ -59,12 +51,12 @@ static int do_sysboot(struct cmd_tbl *cmdtp, int flag, int argc,
char *const argv[])
{
unsigned long pxefile_addr_r;
struct pxe_menu *cfg;
struct pxe_context ctx;
char *pxefile_addr_str;
struct sysboot_info info;
char *filename;
int prompt = 0;
is_pxe = false;
int ret;
if (argc > 1 && strstr(argv[1], "-p")) {
prompt = 1;
@ -91,41 +83,39 @@ static int do_sysboot(struct cmd_tbl *cmdtp, int flag, int argc,
}
if (strstr(argv[3], "ext2")) {
do_getfile = do_get_ext2;
info.fstype = FS_TYPE_EXT;
} else if (strstr(argv[3], "fat")) {
do_getfile = do_get_fat;
info.fstype = FS_TYPE_FAT;
} else if (strstr(argv[3], "any")) {
do_getfile = do_get_any;
info.fstype = FS_TYPE_ANY;
} else {
printf("Invalid filesystem: %s\n", argv[3]);
return 1;
}
fs_argv[1] = argv[1];
fs_argv[2] = argv[2];
info.ifname = argv[1];
info.dev_part_str = 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 (get_pxe_file(cmdtp, filename, pxefile_addr_r) < 0) {
if (pxe_setup_ctx(&ctx, cmdtp, sysboot_read_file, &info, 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;
}
cfg = parse_pxefile(cmdtp, pxefile_addr_r);
if (!cfg) {
printf("Error parsing config file\n");
return 1;
}
if (prompt)
cfg->prompt = 1;
handle_pxe_menu(cmdtp, cfg);
destroy_pxe_menu(cfg);
ret = pxe_process(&ctx, pxefile_addr_r, prompt);
pxe_destroy_ctx(&ctx);
if (ret)
return CMD_RET_FAILURE;
return 0;
}

View File

@ -1,5 +1,3 @@
source "common/Kconfig.boot"
menu "Console"
config MENU

View File

@ -11,21 +11,12 @@ obj-y += exports.o
obj-$(CONFIG_HUSH_PARSER) += cli_hush.o
obj-$(CONFIG_AUTOBOOT) += autoboot.o
# This option is not just y/n - it can have a numeric value
ifdef CONFIG_BOOT_RETRY_TIME
obj-y += bootretry.o
endif
# # boards
obj-y += board_f.o
obj-y += board_r.o
obj-$(CONFIG_DISPLAY_BOARDINFO) += board_info.o
obj-$(CONFIG_DISPLAY_BOARDINFO_LATE) += board_info.o
obj-$(CONFIG_CMD_BOOTM) += bootm.o bootm_os.o
obj-$(CONFIG_CMD_BOOTZ) += bootm.o bootm_os.o
obj-$(CONFIG_CMD_BOOTI) += bootm.o bootm_os.o
obj-$(CONFIG_CMD_BEDBUG) += bedbug.o
obj-$(CONFIG_$(SPL_TPL_)OF_LIBFDT) += fdt_support.o
obj-$(CONFIG_MII) += miiphyutil.o
@ -50,7 +41,6 @@ obj-$(CONFIG_LCD) += lcd.o lcd_console.o
endif
obj-$(CONFIG_LCD_ROTATION) += lcd_console_rotation.o
obj-$(CONFIG_LCD_DT_SIMPLEFB) += lcd_simplefb.o
obj-$(CONFIG_LYNXKDI) += lynxkdi.o
obj-$(CONFIG_MENU) += menu.o
obj-$(CONFIG_UPDATE_COMMON) += update.o
obj-$(CONFIG_USB_KEYBOARD) += usb_kbd.o
@ -65,7 +55,6 @@ ifdef CONFIG_SPL_BUILD
ifdef CONFIG_SPL_DFU
obj-$(CONFIG_DFU_OVER_USB) += dfu.o
endif
obj-$(CONFIG_SPL_LOAD_FIT) += common_fit.o
obj-$(CONFIG_SPL_NET) += miiphyutil.o
obj-$(CONFIG_$(SPL_TPL_)OF_LIBFDT) += fdt_support.o
@ -101,23 +90,11 @@ obj-y += malloc_simple.o
endif
endif
obj-y += image.o image-board.o
obj-$(CONFIG_$(SPL_TPL_)HASH) += hash.o
obj-$(CONFIG_ANDROID_AB) += android_ab.o
obj-$(CONFIG_ANDROID_BOOT_IMAGE) += image-android.o image-android-dt.o
obj-$(CONFIG_$(SPL_TPL_)OF_LIBFDT) += image-fdt.o
obj-$(CONFIG_$(SPL_TPL_)FIT_SIGNATURE) += fdt_region.o
obj-$(CONFIG_$(SPL_TPL_)FIT) += image-fit.o
obj-$(CONFIG_$(SPL_)MULTI_DTB_FIT) += boot_fit.o common_fit.o
obj-$(CONFIG_$(SPL_TPL_)IMAGE_SIGN_INFO) += image-sig.o
obj-$(CONFIG_$(SPL_TPL_)FIT_SIGNATURE) += image-fit-sig.o
obj-$(CONFIG_$(SPL_TPL_)FIT_CIPHER) += image-cipher.o
obj-$(CONFIG_IO_TRACE) += iotrace.o
obj-y += memsize.o
obj-y += stdio.o
obj-$(CONFIG_CMD_ADTIMG) += image-android-dt.o
ifdef CONFIG_CMD_EEPROM_LAYOUT
obj-y += eeprom/eeprom_field.o eeprom/eeprom_layout.o
endif

View File

@ -1,23 +0,0 @@
/*
* Copyright (c) Orbacom Systems, Inc <www.orbacom.com>
* All rights reserved.
*
* Redistribution and use in source and binary forms are freely
* permitted provided that the above copyright notice and this
* paragraph and the following disclaimer are duplicated in all
* such forms.
*
* This software is provided "AS IS" and without any express or
* implied warranties, including, without limitation, the implied
* warranties of merchantability and fitness for a particular
* purpose.
*/
#include <common.h>
#include <asm/processor.h>
#include <image.h>
#include <net.h>
#include <lynxkdi.h>
#error "Lynx KDI support not implemented for configured CPU"

View File

@ -27,6 +27,8 @@ CONFIG_SPL_LOAD_FIT=y
# CONFIG_USE_SPL_FIT_GENERATOR is not set
CONFIG_OF_BOARD_SETUP=y
CONFIG_BOOTSTAGE=y
CONFIG_SHOW_BOOT_PROGRESS=y
CONFIG_SPL_SHOW_BOOT_PROGRESS=y
CONFIG_CONSOLE_MUX=y
# CONFIG_DISPLAY_CPUINFO is not set
CONFIG_SPL_BOARD_INIT=y

View File

@ -1,57 +0,0 @@
LYNX KDI SUPPORT
Last Update: July 20, 2003
=======================================================================
This file describes support for LynuxWorks KDI within U-Boot. Support
is enabled by defining CONFIG_LYNXKDI.
LYNXOS AND BLUECAT SUPPORTED
============================
Both LynxOS and BlueCat linux KDIs are supported. The implementation
automatically detects which is being booted. When you use mkimage
you should specify "lynxos" for both (see target-specific notes).
SUPPORTED ARCHITECTURE/TARGETS
==============================
The following targets have been tested:
-PowerPC MPC8260ADS
FILES TO LOOK AT
================
include/lynxkdi.h -defines a simple struct passed to a kdi.
common/lynxkdi.c -implements the call to the kdi.
common/cmd_bootm.c -top-level command implementation ("bootm").
====================================================================
TARGET SPECIFIC NOTES
====================================================================
MPC8260ADS
===========
The default LynxOS and BlueCat implementations require some
modifications to the config file.
Edit include/configs/MPC8260ADS.h to use the following:
#define CONFIG_SYS_IMMR 0xFA200000
#define CONFIG_SYS_BCSR 0xFA100000
#define CONFIG_SYS_BR1_PRELIM 0xFA101801
When creating a LynxOS or BlueCat u-boot image using mkimage,
you must specify the following:
Both: -A ppc -O lynxos -T kernel -C none
LynxOS: -a 0x00004000 -e 0x00004020
BlueCat: -a 0x00500000 -e 0x00507000
To pass the MAC address to BlueCat you should define the
"fcc2_ether_addr" parameter in the "bootargs" environment
variable. E.g.:
==> setenv bootargs fcc2_ether_addr=00:11:22:33:44:55:66

View File

@ -139,7 +139,7 @@ overview on the whole Android 10 boot process can be found at [8]_.
C API for working with Android Boot Image format
------------------------------------------------
.. kernel-doc:: common/image-android.c
.. kernel-doc:: boot/image-android.c
:internal:
References

View File

@ -1,9 +1,4 @@
SPDX-License-Identifier: GPL-2.0+
/*
* (C) Copyright 2014 Red Hat Inc.
* Copyright (c) 2014-2015, NVIDIA CORPORATION. All rights reserved.
* Copyright (C) 2015 K. Merker <merker@debian.org>
*/
.. SPDX-License-Identifier: GPL-2.0+
Generic Distro Configuration Concept
====================================
@ -73,9 +68,8 @@ Boot Configuration Files
The standard format for boot configuration files is that of extlinux.conf, as
handled by U-Boot's "syslinux" (disk) or "pxe boot" (network). This is roughly
as specified at:
as specified at BootLoaderSpec_:
http://www.freedesktop.org/wiki/Specifications/BootLoaderSpec/
... with the exceptions that the BootLoaderSpec document:
@ -87,73 +81,70 @@ http://www.freedesktop.org/wiki/Specifications/BootLoaderSpec/
* Does not document the fdtdir option, which automatically selects the DTB to
pass to the kernel.
One example extlinux.conf generated by the Fedora installer is:
One example extlinux.conf generated by the Fedora installer is::
------------------------------------------------------------
# extlinux.conf generated by anaconda
# extlinux.conf generated by anaconda
ui menu.c32
ui menu.c32
menu autoboot Welcome to Fedora. Automatic boot in # second{,s}. Press a key for options.
menu title Fedora Boot Options.
menu hidden
menu autoboot Welcome to Fedora. Automatic boot in # second{,s}. Press a key for options.
menu title Fedora Boot Options.
menu hidden
timeout 50
#totaltimeout 9000
timeout 50
#totaltimeout 9000
default Fedora (3.17.0-0.rc4.git2.1.fc22.armv7hl+lpae) 22 (Rawhide)
default Fedora (3.17.0-0.rc4.git2.1.fc22.armv7hl+lpae) 22 (Rawhide)
label Fedora (3.17.0-0.rc4.git2.1.fc22.armv7hl) 22 (Rawhide)
kernel /boot/vmlinuz-3.17.0-0.rc4.git2.1.fc22.armv7hl
append ro root=UUID=8eac677f-8ea8-4270-8479-d5ddbb797450 console=ttyS0,115200n8 LANG=en_US.UTF-8 drm.debug=0xf
fdtdir /boot/dtb-3.17.0-0.rc4.git2.1.fc22.armv7hl
initrd /boot/initramfs-3.17.0-0.rc4.git2.1.fc22.armv7hl.img
label Fedora (3.17.0-0.rc4.git2.1.fc22.armv7hl) 22 (Rawhide)
kernel /boot/vmlinuz-3.17.0-0.rc4.git2.1.fc22.armv7hl
append ro root=UUID=8eac677f-8ea8-4270-8479-d5ddbb797450 console=ttyS0,115200n8 LANG=en_US.UTF-8 drm.debug=0xf
fdtdir /boot/dtb-3.17.0-0.rc4.git2.1.fc22.armv7hl
initrd /boot/initramfs-3.17.0-0.rc4.git2.1.fc22.armv7hl.img
label Fedora (3.17.0-0.rc4.git2.1.fc22.armv7hl+lpae) 22 (Rawhide)
kernel /boot/vmlinuz-3.17.0-0.rc4.git2.1.fc22.armv7hl+lpae
append ro root=UUID=8eac677f-8ea8-4270-8479-d5ddbb797450 console=ttyS0,115200n8 LANG=en_US.UTF-8 drm.debug=0xf
fdtdir /boot/dtb-3.17.0-0.rc4.git2.1.fc22.armv7hl+lpae
initrd /boot/initramfs-3.17.0-0.rc4.git2.1.fc22.armv7hl+lpae.img
label Fedora (3.17.0-0.rc4.git2.1.fc22.armv7hl+lpae) 22 (Rawhide)
kernel /boot/vmlinuz-3.17.0-0.rc4.git2.1.fc22.armv7hl+lpae
append ro root=UUID=8eac677f-8ea8-4270-8479-d5ddbb797450 console=ttyS0,115200n8 LANG=en_US.UTF-8 drm.debug=0xf
fdtdir /boot/dtb-3.17.0-0.rc4.git2.1.fc22.armv7hl+lpae
initrd /boot/initramfs-3.17.0-0.rc4.git2.1.fc22.armv7hl+lpae.img
label Fedora-0-rescue-8f6ba7b039524e0eb957d2c9203f04bc (0-rescue-8f6ba7b039524e0eb957d2c9203f04bc)
kernel /boot/vmlinuz-0-rescue-8f6ba7b039524e0eb957d2c9203f04bc
initrd /boot/initramfs-0-rescue-8f6ba7b039524e0eb957d2c9203f04bc.img
append ro root=UUID=8eac677f-8ea8-4270-8479-d5ddbb797450 console=ttyS0,115200n8
fdtdir /boot/dtb-3.16.0-0.rc6.git1.1.fc22.armv7hl+lpae
------------------------------------------------------------
label Fedora-0-rescue-8f6ba7b039524e0eb957d2c9203f04bc (0-rescue-8f6ba7b039524e0eb957d2c9203f04bc)
kernel /boot/vmlinuz-0-rescue-8f6ba7b039524e0eb957d2c9203f04bc
initrd /boot/initramfs-0-rescue-8f6ba7b039524e0eb957d2c9203f04bc.img
append ro root=UUID=8eac677f-8ea8-4270-8479-d5ddbb797450 console=ttyS0,115200n8
fdtdir /boot/dtb-3.16.0-0.rc6.git1.1.fc22.armv7hl+lpae
Another hand-crafted network boot configuration file is:
------------------------------------------------------------
TIMEOUT 100
Another hand-crafted network boot configuration file is::
MENU TITLE TFTP boot options
TIMEOUT 100
LABEL jetson-tk1-emmc
MENU LABEL ../zImage root on Jetson TK1 eMMC
LINUX ../zImage
FDTDIR ../
APPEND console=ttyS0,115200n8 console=tty1 loglevel=8 rootwait rw earlyprintk root=PARTUUID=80a5a8e9-c744-491a-93c1-4f4194fd690b
MENU TITLE TFTP boot options
LABEL venice2-emmc
MENU LABEL ../zImage root on Venice2 eMMC
LINUX ../zImage
FDTDIR ../
APPEND console=ttyS0,115200n8 console=tty1 loglevel=8 rootwait rw earlyprintk root=PARTUUID=5f71e06f-be08-48ed-b1ef-ee4800cc860f
LABEL jetson-tk1-emmc
MENU LABEL ../zImage root on Jetson TK1 eMMC
LINUX ../zImage
FDTDIR ../
APPEND console=ttyS0,115200n8 console=tty1 loglevel=8 rootwait rw earlyprintk root=PARTUUID=80a5a8e9-c744-491a-93c1-4f4194fd690b
LABEL sdcard
MENU LABEL ../zImage, root on 2GB sdcard
LINUX ../zImage
FDTDIR ../
APPEND console=ttyS0,115200n8 console=tty1 loglevel=8 rootwait rw earlyprintk root=PARTUUID=b2f82cda-2535-4779-b467-094a210fbae7
LABEL venice2-emmc
MENU LABEL ../zImage root on Venice2 eMMC
LINUX ../zImage
FDTDIR ../
APPEND console=ttyS0,115200n8 console=tty1 loglevel=8 rootwait rw earlyprintk root=PARTUUID=5f71e06f-be08-48ed-b1ef-ee4800cc860f
LABEL fedora-installer-fk
MENU LABEL Fedora installer w/ Fedora kernel
LINUX fedora-installer/vmlinuz
INITRD fedora-installer/initrd.img.orig
FDTDIR fedora-installer/dtb
APPEND loglevel=8 ip=dhcp inst.repo=http://10.0.0.2/mirrors/fedora/linux/development/rawhide/armhfp/os/ rd.shell cma=64M
------------------------------------------------------------
LABEL sdcard
MENU LABEL ../zImage, root on 2GB sdcard
LINUX ../zImage
FDTDIR ../
APPEND console=ttyS0,115200n8 console=tty1 loglevel=8 rootwait rw earlyprintk root=PARTUUID=b2f82cda-2535-4779-b467-094a210fbae7
LABEL fedora-installer-fk
MENU LABEL Fedora installer w/ Fedora kernel
LINUX fedora-installer/vmlinuz
INITRD fedora-installer/initrd.img.orig
FDTDIR fedora-installer/dtb
APPEND loglevel=8 ip=dhcp inst.repo=http://10.0.0.2/mirrors/fedora/linux/development/rawhide/armhfp/os/ rd.shell cma=64M
U-Boot Implementation
=====================
@ -166,13 +157,11 @@ a line with "CONFIG_DISTRO_DEFAULTS=y". If you want to enable this
from Kconfig itself, for e.g. all boards using a specific SoC then
add a "imply DISTRO_DEFAULTS" to your SoC CONFIG option.
In your board configuration file, include the following:
In your board configuration file, include the following::
------------------------------------------------------------
#ifndef CONFIG_SPL_BUILD
#include <config_distro_bootcmd.h>
#endif
------------------------------------------------------------
#ifndef CONFIG_SPL_BUILD
#include <config_distro_bootcmd.h>
#endif
The first of those headers primarily enables a core set of U-Boot features,
such as support for MBR and GPT partitions, ext* and FAT filesystems, booting
@ -205,7 +194,6 @@ CONFIG_EXTRA_ENV_SETTINGS in the board's U-Boot configuration file, so that
the user doesn't have to configure them.
fdt_addr:
Mandatory for any system that provides the DTB in HW (e.g. ROM) and wishes
to pass that DTB to Linux, rather than loading a DTB from the boot
filesystem. Prohibited for any other system.
@ -214,7 +202,6 @@ fdt_addr:
address.
fdt_addr_r:
Mandatory. The location in RAM where the DTB will be loaded or copied to when
processing the fdtdir/devicetreedir or fdt/devicetree options in
extlinux.conf.
@ -225,7 +212,6 @@ fdt_addr_r:
A size of 1MB for the FDT/DTB seems reasonable.
fdtfile:
Mandatory. the name of the DTB file for the specific board for instance
the espressobin v5 board the value is "marvell/armada-3720-espressobin.dtb"
while on a clearfog pro it is "armada-388-clearfog-pro.dtb" in the case of
@ -236,16 +222,14 @@ fdtfile:
SoC vendor directories.
ramdisk_addr_r:
Mandatory. The location in RAM where the initial ramdisk will be loaded to
when processing the initrd option in extlinux.conf.
It is recommended that this location be highest in RAM out of fdt_addr_,
It is recommended that this location be highest in RAM out of fdt_addr_r,
kernel_addr_r, and ramdisk_addr_r, so that the RAM disk can vary in size
and use any available RAM.
kernel_addr_r:
Mandatory. The location in RAM where the kernel will be loaded to when
processing the kernel option in the extlinux.conf.
@ -270,14 +254,12 @@ kernel_comp_size:
size has to at least the size of loaded image for decompression to succeed.
pxefile_addr_r:
Mandatory. The location in RAM where extlinux.conf will be loaded to prior
to processing.
A size of 1MB for extlinux.conf is more than adequate.
scriptaddr:
Mandatory, if the boot script is boot.scr rather than extlinux.conf. The
location in RAM where boot.scr will be loaded to prior to execution.
@ -292,24 +274,22 @@ MEM_LAYOUT_ENV_SETTINGS in include/configs/tegra124-common.h.
Boot Target Configuration
-------------------------
<config_distro_bootcmd.h> defines $bootcmd and many helper command variables
that automatically search attached disks for boot configuration files and
execute them. Boards must provide configure <config_distro_bootcmd.h> so that
it supports the correct set of possible boot device types. To provide this
The `config_distro_bootcmd.h` file defines $bootcmd and many helper command
variables that automatically search attached disks for boot configuration files
and execute them. Boards must provide configure <config_distro_bootcmd.h> so
that it supports the correct set of possible boot device types. To provide this
configuration, simply define macro BOOT_TARGET_DEVICES prior to including
<config_distro_bootcmd.h>. For example:
<config_distro_bootcmd.h>. For example::
------------------------------------------------------------
#ifndef CONFIG_SPL_BUILD
#define BOOT_TARGET_DEVICES(func) \
func(MMC, mmc, 1) \
func(MMC, mmc, 0) \
func(USB, usb, 0) \
func(PXE, pxe, na) \
func(DHCP, dhcp, na)
#include <config_distro_bootcmd.h>
#endif
------------------------------------------------------------
#ifndef CONFIG_SPL_BUILD
#define BOOT_TARGET_DEVICES(func) \
func(MMC, mmc, 1) \
func(MMC, mmc, 0) \
func(USB, usb, 0) \
func(PXE, pxe, na) \
func(DHCP, dhcp, na)
#include <config_distro_bootcmd.h>
#endif
Each entry in the macro defines a single boot device (e.g. a specific eMMC
device or SD card) or type of boot device (e.g. USB disk). The parameters to
@ -328,7 +308,6 @@ up by <config_distro_bootcmd.h>. After this, various environment variables may
be altered to influence the boot process:
boot_targets:
The list of boot locations searched.
Example: mmc0, mmc1, usb, pxe
@ -336,7 +315,6 @@ boot_targets:
Entries may be removed or re-ordered in this list to affect the boot order.
boot_prefixes:
For disk-based booting, the list of directories within a partition that are
searched for boot configuration files (extlinux.conf, boot.scr).
@ -346,7 +324,6 @@ boot_prefixes:
directories which are searched.
boot_scripts:
The name of U-Boot style boot.scr files that $bootcmd searches for.
Example: boot.scr.uimg boot.scr
@ -358,17 +335,14 @@ boot_scripts:
filenames which are supported.
scan_dev_for_extlinux:
If you want to disable extlinux.conf on all disks, set the value to something
innocuous, e.g. setenv scan_dev_for_extlinux true.
scan_dev_for_scripts:
If you want to disable boot.scr on all disks, set the value to something
innocuous, e.g. setenv scan_dev_for_scripts true.
boot_net_usb_start:
If you want to prevent USB enumeration by distro boot commands which execute
network operations, set the value to something innocuous, e.g. setenv
boot_net_usb_start true. This would be useful if you know your Ethernet
@ -376,7 +350,6 @@ boot_net_usb_start:
avoiding unnecessary actions.
boot_net_pci_enum:
If you want to prevent PCI enumeration by distro boot commands which execute
network operations, set the value to something innocuous, e.g. setenv
boot_net_pci_enum true. This would be useful if you know your Ethernet
@ -412,10 +385,12 @@ Examples:
The list of possible targets consists of:
- network targets
* dhcp
* pxe
- storage targets (to which a device number must be appended)
* mmc
* sata
* scsi
@ -428,3 +403,9 @@ of the boot environment and are not guaranteed to exist or work in the same
way in future u-boot versions. In particular the <device type>_boot
variables (e.g. mmc_boot, usb_boot) are a strictly internal implementation
detail and must not be used as a public interface.
.. _BootLoaderSpec: http://www.freedesktop.org/wiki/Specifications/BootLoaderSpec/
.. sectionauthor:: (C) Copyright 2014 Red Hat Inc.
.. sectionauthor:: Copyright (c) 2014-2015, NVIDIA CORPORATION. All rights reserved.
.. sectionauthor:: Copyright (C) 2015 K. Merker <merker@debian.org>

View File

@ -14,6 +14,7 @@ Implementation
commands
config_binding
devicetree/index
distro
driver-model/index
global_data
logging

View File

@ -306,7 +306,7 @@ static const struct rtc_ops ds1337_rtc_ops = {
static const struct udevice_id ds1337_rtc_ids[] = {
{ .compatible = "ds1337" },
{ .compatible = "ds1338" },
{ .compatible = "ds1338" },
{ .compatible = "ds1339" },
{ }
};

View File

@ -39,7 +39,6 @@ extern boot_os_fn do_bootm_linux;
extern boot_os_fn do_bootm_vxworks;
int do_bootelf(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]);
void lynxkdi_boot(image_header_t *hdr);
boot_os_fn *bootm_os_get_boot_func(int os);

View File

@ -1,24 +0,0 @@
/* SPDX-License-Identifier: GPL-2.0+ */
/*
* (C) Copyright 2003
* Orbacom Systems, Inc.
*/
#ifndef __LYNXKDI_H__
#define __LYNXKDI_H__
/* Boot parameter struct passed to kernel
*/
typedef struct lynxos_bootparms_t {
uint8_t rsvd1[2]; /* Reserved */
uint8_t ethaddr[6]; /* Ethernet address */
uint16_t flags; /* Boot flags */
uint32_t rate; /* System frequency */
uint32_t clock_ref; /* Time reference */
uint32_t dramsz; /* DRAM size */
uint32_t rsvd2; /* Reserved */
} lynxos_bootparms_t;
#endif /* __LYNXKDI_H__ */

253
include/pxe_utils.h Normal file
View File

@ -0,0 +1,253 @@
/* SPDX-License-Identifier: GPL-2.0+ */
#ifndef __PXE_UTILS_H
#define __PXE_UTILS_H
#include <linux/list.h>
/*
* A note on the pxe file parser.
*
* We're parsing files that use syslinux grammar, which has a few quirks.
* String literals must be recognized based on context - there is no
* quoting or escaping support. There's also nothing to explicitly indicate
* when a label section completes. We deal with that by ending a label
* section whenever we see a line that doesn't include.
*
* As with the syslinux family, this same file format could be reused in the
* future for non pxe purposes. The only action it takes during parsing that
* would throw this off is handling of include files. It assumes we're using
* pxe, and does a tftp download of a file listed as an include file in the
* middle of the parsing operation. That could be handled by refactoring it to
* take a 'include file getter' function.
*/
/*
* Describes a single label given in a pxe file.
*
* Create these with the 'label_create' function given below.
*
* name - the name of the menu as given on the 'menu label' line.
* kernel - the path to the kernel file to use for this label.
* append - kernel command line to use when booting this label
* initrd - path to the initrd to use for this label.
* attempted - 0 if we haven't tried to boot this label, 1 if we have.
* localboot - 1 if this label specified 'localboot', 0 otherwise.
* list - lets these form a list, which a pxe_menu struct will hold.
*/
struct pxe_label {
char num[4];
char *name;
char *menu;
char *kernel;
char *config;
char *append;
char *initrd;
char *fdt;
char *fdtdir;
char *fdtoverlays;
int ipappend;
int attempted;
int localboot;
int localboot_val;
struct list_head list;
};
/*
* Describes a pxe menu as given via pxe files.
*
* 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
* interrupted. If 1, always prompt for a choice regardless of
* timeout.
* labels - a list of labels defined for the menu.
*/
struct pxe_menu {
char *title;
char *default_label;
char *bmp;
int timeout;
int prompt;
struct list_head labels;
};
struct pxe_context;
typedef int (*pxe_getfile_func)(struct pxe_context *ctx, const char *file_path,
char *file_addr, ulong *filesizep);
/**
* struct pxe_context - context information for PXE parsing
*
* @cmdtp: Pointer to command table to use when calling other commands
* @getfile: Function called by PXE to read a file
* @userdata: Data the caller requires for @getfile
* @allow_abs_path: true to allow absolute paths
* @bootdir: Directory that files are loaded from ("" if no directory). This is
* allocated
* @pxe_file_size: Size of the PXE file
*/
struct pxe_context {
struct cmd_tbl *cmdtp;
/**
* getfile() - read a file
*
* @ctx: PXE context
* @file_path: Path to the file
* @file_addr: String containing the hex address to put the file in
* memory
* @filesizep: Returns the file size in bytes
* Return 0 if OK, -ve on error
*/
pxe_getfile_func getfile;
void *userdata;
bool allow_abs_path;
char *bootdir;
ulong pxe_file_size;
};
/**
* destroy_pxe_menu() - Destroy an allocated pxe structure
*
* Free the memory used by a pxe_menu and its labels
*
* @cfg: Config to destroy, previous returned from parse_pxefile()
*/
void destroy_pxe_menu(struct pxe_menu *cfg);
/**
* get_pxe_file() - Read a file
*
* Retrieve the file at 'file_path' to the locate given by 'file_addr'. If
* 'bootfile' was specified in the environment, the path to bootfile will be
* prepended to 'file_path' and the resulting path will be used.
*
* @ctx: PXE context
* @file_path: Path to file
* @file_addr: Address to place file
* Returns 1 on success, or < 0 for error
*/
int get_pxe_file(struct pxe_context *ctx, const char *file_path,
ulong file_addr);
/**
* get_pxelinux_path() - Read a file from the same place as pxelinux.cfg
*
* Retrieves a file in the 'pxelinux.cfg' folder. Since this uses get_pxe_file()
* to do the hard work, the location of the 'pxelinux.cfg' folder is generated
* from the bootfile path, as described in get_pxe_file().
*
* @ctx: PXE context
* @file: Relative path to file
* @pxefile_addr_r: Address to load file
* Returns 1 on success or < 0 on error.
*/
int get_pxelinux_path(struct pxe_context *ctx, const char *file,
ulong pxefile_addr_r);
/**
* handle_pxe_menu() - Boot the system as prescribed by a pxe_menu.
*
* Use the menu system to either get the user's choice or the default, based
* on config or user input. If there is no default or user's choice,
* attempted to boot labels in the order they were given in pxe files.
* If the default or user's choice fails to boot, attempt to boot other
* labels in the order they were given in pxe files.
*
* If this function returns, there weren't any labels that successfully
* booted, or the user interrupted the menu selection via ctrl+c.
*
* @ctx: PXE context
* @cfg: PXE menu
*/
void handle_pxe_menu(struct pxe_context *ctx, struct pxe_menu *cfg);
/**
* parse_pxefile() - Parsing a pxe file
*
* This is only used for the top-level file.
*
* @ctx: PXE context (provided by the caller)
* Returns NULL if there is an error, otherwise, returns a pointer to a
* pxe_menu struct populated with the results of parsing the pxe file (and any
* files it includes). The resulting pxe_menu struct can be free()'d by using
* the destroy_pxe_menu() function.
*/
struct pxe_menu *parse_pxefile(struct pxe_context *ctx, ulong menucfg);
/**
* format_mac_pxe() - Convert a MAC address to PXE format
*
* Convert an ethaddr from the environment to the format used by pxelinux
* filenames based on mac addresses. Convert's ':' to '-', and adds "01-" to
* the beginning of the ethernet address to indicate a hardware type of
* Ethernet. Also converts uppercase hex characters into lowercase, to match
* pxelinux's behavior.
*
* @outbuf: Buffer to hold the output (must hold 22 bytes)
* @outbuf_len: Length of buffer
* Returns 1 for success, -ENOENT if 'ethaddr' is undefined in the
* environment, or some other value < 0 on error.
*/
int format_mac_pxe(char *outbuf, size_t outbuf_len);
/**
* pxe_setup_ctx() - Setup a new PXE context
*
* @ctx: Context to set up
* @cmdtp: Command table entry which started this action
* @getfile: Function to call to read a file
* @userdata: Data the caller requires for @getfile - stored in ctx->userdata
* @allow_abs_path: true to allow absolute paths
* @bootfile: Bootfile whose directory loaded files are relative to, NULL if
* none
* @return 0 if OK, -ENOMEM if out of memory, -E2BIG if bootfile is larger than
* MAX_TFTP_PATH_LEN bytes
*/
int pxe_setup_ctx(struct pxe_context *ctx, struct cmd_tbl *cmdtp,
pxe_getfile_func getfile, void *userdata,
bool allow_abs_path, const char *bootfile);
/**
* pxe_destroy_ctx() - Destroy a PXE context
*
* @ctx: Context to destroy
*/
void pxe_destroy_ctx(struct pxe_context *ctx);
/**
* pxe_process() - Process a PXE file through to boot
*
* @ctx: PXE context created with pxe_setup_ctx()
* @pxefile_addr_r: Address to load file
* @prompt: Force a prompt for the user
*/
int pxe_process(struct pxe_context *ctx, ulong pxefile_addr_r, bool prompt);
/**
* pxe_get_file_size() - Read the value of the 'filesize' environment variable
*
* @sizep: Place to put the value
* @return 0 if OK, -ENOENT if no such variable, -EINVAL if format is invalid
*/
int pxe_get_file_size(ulong *sizep);
/**
* pxe_get() - Get the PXE file from the server
*
* This tries various filenames to obtain a PXE file
*
* @pxefile_addr_r: Address to put file
* @bootdirp: Returns the boot filename, or NULL if none. This is the 'bootfile'
* option provided by the DHCP server. If none, returns NULL. For example,
* "rpi/info", which indicates that all files should be fetched from the
* "rpi/" subdirectory
* @sizep: Size of the PXE file (not bootfile)
*/
int pxe_get(ulong pxefile_addr_r, char **bootdirp, ulong *sizep);
#endif /* __PXE_UTILS_H */

View File

@ -172,7 +172,30 @@ int sprintf(char *buf, const char *fmt, ...)
* See the vsprintf() documentation for format string extensions over C99.
*/
int vsprintf(char *buf, const char *fmt, va_list args);
char *simple_itoa(ulong i);
/**
* simple_itoa() - convert an unsigned integer to a string
*
* This returns a static string containing the decimal representation of the
* given value. The returned value may be overwritten by other calls to other
* simple_... functions, so should be used immediately
*
* @val: Value to convert
* @return string containing the decimal representation of @val
*/
char *simple_itoa(ulong val);
/**
* simple_xtoa() - convert an unsigned integer to a hex string
*
* This returns a static string containing the hexadecimal representation of the
* given value. The returned value may be overwritten by other calls to other
* simple_... functions, so should be used immediately
*
* @val: Value to convert
* @return string containing the hexecimal representation of @val
*/
char *simple_xtoa(ulong num);
/**
* Format a string and place it in a buffer

View File

@ -816,11 +816,12 @@ int vprintf(const char *fmt, va_list args)
}
#endif
static char local_toa[22];
char *simple_itoa(ulong i)
{
/* 21 digits plus null terminator, good for 64-bit or smaller ints */
static char local[22];
char *p = &local[21];
char *p = &local_toa[21];
*p-- = '\0';
do {
@ -830,6 +831,21 @@ char *simple_itoa(ulong i)
return p + 1;
}
char *simple_xtoa(ulong num)
{
/* 16 digits plus nul terminator, good for 64-bit or smaller ints */
char *p = &local_toa[17];
*--p = '\0';
do {
p -= 2;
hex_byte_pack(p, num & 0xff);
num >>= 8;
} while (num > 0);
return p;
}
/* We don't seem to have %'d in U-Boot */
void print_grouped_ull(unsigned long long int_val, int digits)
{

View File

@ -92,10 +92,10 @@ libs-y += common/init/
# Special handling for a few options which support SPL/TPL
ifeq ($(CONFIG_TPL_BUILD),y)
libs-$(CONFIG_TPL_LIBCOMMON_SUPPORT) += common/ cmd/ env/
libs-$(CONFIG_TPL_LIBCOMMON_SUPPORT) += boot/ common/ cmd/ env/
libs-$(CONFIG_TPL_LIBGENERIC_SUPPORT) += lib/
else
libs-$(CONFIG_SPL_LIBCOMMON_SUPPORT) += common/ cmd/ env/
libs-$(CONFIG_SPL_LIBCOMMON_SUPPORT) += boot/ common/ cmd/ env/
libs-$(CONFIG_SPL_LIBGENERIC_SUPPORT) += lib/
ifdef CONFIG_SPL_FRAMEWORK
libs-$(CONFIG_PARTITIONS) += disk/

View File

@ -741,7 +741,6 @@ CONFIG_LQ038J7DH53
CONFIG_LS102XA_STREAM_ID
CONFIG_LSCHLV2
CONFIG_LSXHL
CONFIG_LYNXKDI
CONFIG_M41T94_SPI_CS
CONFIG_M520x
CONFIG_M5301x

View File

@ -10,6 +10,7 @@
#include <log.h>
#include <mapmem.h>
#include <version_string.h>
#include <vsprintf.h>
#include <test/suites.h>
#include <test/test.h>
#include <test/ut.h>
@ -328,6 +329,46 @@ static int print_do_hex_dump(struct unit_test_state *uts)
}
PRINT_TEST(print_do_hex_dump, UT_TESTF_CONSOLE_REC);
static int print_itoa(struct unit_test_state *uts)
{
ut_asserteq_str("123", simple_itoa(123));
ut_asserteq_str("0", simple_itoa(0));
ut_asserteq_str("2147483647", simple_itoa(0x7fffffff));
ut_asserteq_str("4294967295", simple_itoa(0xffffffff));
/* Use #ifdef here to avoid a compiler warning on 32-bit machines */
#ifdef CONFIG_PHYS_64BIT
if (sizeof(ulong) == 8) {
ut_asserteq_str("9223372036854775807",
simple_itoa((1UL << 63) - 1));
ut_asserteq_str("18446744073709551615", simple_itoa(-1));
}
#endif /* CONFIG_PHYS_64BIT */
return 0;
}
PRINT_TEST(print_itoa, 0);
static int print_xtoa(struct unit_test_state *uts)
{
ut_asserteq_str("7f", simple_xtoa(127));
ut_asserteq_str("00", simple_xtoa(0));
ut_asserteq_str("7fffffff", simple_xtoa(0x7fffffff));
ut_asserteq_str("ffffffff", simple_xtoa(0xffffffff));
/* Use #ifdef here to avoid a compiler warning on 32-bit machines */
#ifdef CONFIG_PHYS_64BIT
if (sizeof(ulong) == 8) {
ut_asserteq_str("7fffffffffffffff",
simple_xtoa((1UL << 63) - 1));
ut_asserteq_str("ffffffffffffffff", simple_xtoa(-1));
}
#endif /* CONFIG_PHYS_64BIT */
return 0;
}
PRINT_TEST(print_xtoa, 0);
int do_ut_print(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
{
struct unit_test *tests = UNIT_TEST_SUITE_START(print_test);

View File

@ -76,9 +76,9 @@ hostprogs-$(CONFIG_TOOLS_LIBCRYPTO) += fit_info fit_check_sign
hostprogs-$(CONFIG_CMD_BOOTEFI_SELFTEST) += file2include
FIT_OBJS-y := fit_common.o fit_image.o image-host.o common/image-fit.o
FIT_SIG_OBJS-$(CONFIG_TOOLS_LIBCRYPTO) := image-sig-host.o common/image-fit-sig.o
FIT_CIPHER_OBJS-$(CONFIG_TOOLS_LIBCRYPTO) := common/image-cipher.o
FIT_OBJS-y := fit_common.o fit_image.o image-host.o boot/image-fit.o
FIT_SIG_OBJS-$(CONFIG_TOOLS_LIBCRYPTO) := image-sig-host.o boot/image-fit-sig.o
FIT_CIPHER_OBJS-$(CONFIG_TOOLS_LIBCRYPTO) := boot/image-cipher.o
# The following files are synced with upstream DTC.
# Use synced versions from scripts/dtc/libfdt/.
@ -106,14 +106,14 @@ dumpimage-mkimage-objs := aisimage.o \
$(FIT_OBJS-y) \
$(FIT_SIG_OBJS-y) \
$(FIT_CIPHER_OBJS-y) \
common/fdt_region.o \
common/bootm.o \
boot/fdt_region.o \
boot/bootm.o \
lib/crc32.o \
default_image.o \
lib/fdtdec_common.o \
lib/fdtdec.o \
common/image.o \
common/image-host.o \
boot/image.o \
boot/image-host.o \
imagetool.o \
imximage.o \
imx8image.o \
@ -227,7 +227,7 @@ hostprogs-$(CONFIG_ARCH_OCTEON) += update_octeon_header
update_octeon_header-objs := update_octeon_header.o lib/crc32.o
hostprogs-y += fdtgrep
fdtgrep-objs += $(LIBFDT_OBJS) common/fdt_region.o fdtgrep.o
fdtgrep-objs += $(LIBFDT_OBJS) boot/fdt_region.o fdtgrep.o
ifneq ($(TOOLS_ONLY),y)
hostprogs-y += spl_size_limit
@ -254,7 +254,7 @@ HOSTCFLAGS_sha512.o := -pedantic -DCONFIG_SHA512 -DCONFIG_SHA384
quiet_cmd_wrap = WRAP $@
cmd_wrap = echo "\#include <../$(patsubst $(obj)/%,%,$@)>" >$@
$(obj)/lib/%.c $(obj)/common/%.c $(obj)/env/%.c:
$(obj)/boot/%.c $(obj)/common/%.c $(obj)/env/%.c $(obj)/lib/%.c:
$(call cmd,wrap)
clean-dirs := lib common