diff options
| author | Tom Rini <[email protected]> | 2024-01-08 12:00:18 -0500 |
|---|---|---|
| committer | Tom Rini <[email protected]> | 2024-01-08 12:00:18 -0500 |
| commit | 93d91e9485d902a1836a22e72d1a545b587adf36 (patch) | |
| tree | f368b4e3c2220e7cd34c83bf192d8b674158d16b /boot | |
| parent | 866ca972d6c3cabeaf6dbac431e8e08bb30b3c8e (diff) | |
| parent | f28a77589e7505535a4eebdc7269df98f67dbe68 (diff) | |
Merge branch 'next'
Diffstat (limited to 'boot')
| -rw-r--r-- | boot/Kconfig | 94 | ||||
| -rw-r--r-- | boot/Makefile | 6 | ||||
| -rw-r--r-- | boot/bootm.c | 749 | ||||
| -rw-r--r-- | boot/bootm_os.c | 131 | ||||
| -rw-r--r-- | boot/bootmeth_efi.c | 16 | ||||
| -rw-r--r-- | boot/bootmeth_efi_mgr.c | 4 | ||||
| -rw-r--r-- | boot/fdt_support.c | 1 | ||||
| -rw-r--r-- | boot/image-board.c | 69 | ||||
| -rw-r--r-- | boot/image-fdt.c | 84 | ||||
| -rw-r--r-- | boot/image-fit.c | 2 | ||||
| -rw-r--r-- | boot/image.c | 15 | ||||
| -rw-r--r-- | boot/prog_boot.c | 51 | ||||
| -rw-r--r-- | boot/pxe_utils.c | 5 |
13 files changed, 654 insertions, 573 deletions
diff --git a/boot/Kconfig b/boot/Kconfig index fbc49c5bca4..9f5b8a0cb2c 100644 --- a/boot/Kconfig +++ b/boot/Kconfig @@ -346,8 +346,16 @@ config PXE_UTILS help Utilities for parsing PXE file formats. -config BOOT_DEFAULTS - bool # Common defaults for standard boot and distroboot +config BOOT_DEFAULTS_FEATURES + bool + select SUPPORT_RAW_INITRD + select ENV_VARS_UBOOT_CONFIG + imply USB_STORAGE + imply EFI_PARTITION + imply ISO_PARTITION + +config BOOT_DEFAULTS_CMDS + bool imply USE_BOOTCOMMAND select CMD_ENV_EXISTS select CMD_EXT2 @@ -358,14 +366,14 @@ config BOOT_DEFAULTS select CMD_DHCP if CMD_NET select CMD_PING if CMD_NET select CMD_PXE if CMD_NET - select SUPPORT_RAW_INITRD - select ENV_VARS_UBOOT_CONFIG select CMD_BOOTI if ARM64 select CMD_BOOTZ if ARM && !ARM64 imply CMD_MII if NET - imply USB_STORAGE - imply EFI_PARTITION - imply ISO_PARTITION + +config BOOT_DEFAULTS + bool # Common defaults for standard boot and distroboot + select BOOT_DEFAULTS_FEATURES + select BOOT_DEFAULTS_CMDS if CMDLINE help These are not required but are commonly needed to support a good selection of booting methods. Enable this to improve the capability @@ -431,7 +439,6 @@ config BOOTSTD_FULL config BOOTSTD_DEFAULTS bool "Select some common defaults for standard boot" depends on BOOTSTD - imply USE_BOOTCOMMAND select BOOT_DEFAULTS select BOOTMETH_DISTRO help @@ -452,6 +459,18 @@ config BOOTSTD_BOOTCOMMAND standard boot does not support all of the features of distro boot yet. +config BOOTSTD_PROG + bool "Use programmatic boot" + depends on !CMDLINE + default y + help + Enable this to provide a board_run_command() function which can boot + a systen without using commands. If the boot fails, then U-Boot will + panic. + + Note: This currently has many limitations and is not a useful booting + solution. Future work will eventually make this a viable option. + config BOOTMETH_GLOBAL bool help @@ -504,7 +523,7 @@ config BOOTMETH_EXTLINUX_PXE config BOOTMETH_EFILOADER bool "Bootdev support for EFI boot" - depends on EFI_LOADER + depends on BOOTEFI_BOOTMGR default y help Enables support for EFI boot using bootdevs. This makes the @@ -536,10 +555,10 @@ config BOOTMETH_VBE config BOOTMETH_DISTRO bool # Options needed to boot any distro - select BOOTMETH_SCRIPT # E.g. Armbian uses scripts + select BOOTMETH_SCRIPT if CMDLINE # E.g. Armbian uses scripts select BOOTMETH_EXTLINUX # E.g. Debian uses these select BOOTMETH_EXTLINUX_PXE if CMD_PXE && CMD_NET && DM_ETH - select BOOTMETH_EFILOADER if EFI_LOADER # E.g. Ubuntu uses this + select BOOTMETH_EFILOADER if BOOTEFI_BOOTMGR # E.g. Ubuntu uses this config SPL_BOOTMETH_VBE bool "Bootdev support for Verified Boot for Embedded (SPL)" @@ -664,6 +683,7 @@ config BOOTMETH_SANDBOX config BOOTMETH_SCRIPT bool "Bootdev support for U-Boot scripts" default y if BOOTSTD_FULL + depends on CMDLINE select HUSH_PARSER help Enables support for booting a distro via a U-Boot script. This makes @@ -717,6 +737,17 @@ if MEASURED_BOOT event log memory region. endif # MEASURED_BOOT +config SYS_BOOTM_LEN + hex "Maximum size of a decompresed OS image" + depends on CMD_BOOTM || CMD_BOOTI || CMD_BOOTZ || \ + LEGACY_IMAGE_FORMAT || SPL_LEGACY_IMAGE_FORMAT + default 0x4000000 if PPC || ARM64 + default 0x1000000 if X86 || ARCH_MX6 || ARCH_MX7 + default 0x800000 + help + This is the maximum size of the buffer that is used to decompress the OS + image in to if attempting to boot a compressed image. + config SUPPORT_RAW_INITRD bool "Enable raw initrd images" help @@ -809,6 +840,7 @@ endmenu # Boot images config DISTRO_DEFAULTS bool "(deprecated) Script-based booting of Linux distributions" + select CMDLINE select BOOT_DEFAULTS select AUTO_COMPLETE select CMDLINE_EDITING @@ -1194,14 +1226,16 @@ menu "Autoboot options" config AUTOBOOT bool "Autoboot" + depends on CMDLINE default y help This enables the autoboot. See doc/README.autoboot for detail. +if AUTOBOOT + config BOOTDELAY int "delay in seconds before automatically booting" default 2 - depends on AUTOBOOT help Delay before automatically running bootcmd; set to 0 to autoboot with no delay, but you can stop it by key input. @@ -1223,9 +1257,11 @@ config AUTOBOOT_KEYED U-Boot automatic booting process and bring the device to the U-Boot prompt for user input. +if AUTOBOOT_KEYED + config AUTOBOOT_FLUSH_STDIN bool "Enable flushing stdin before starting to read the password" - depends on AUTOBOOT_KEYED && !SANDBOX + depends on !SANDBOX help When this option is enabled stdin buffer will be flushed before starting to read the password. @@ -1234,7 +1270,6 @@ config AUTOBOOT_FLUSH_STDIN config AUTOBOOT_PROMPT string "Autoboot stop prompt" - depends on AUTOBOOT_KEYED default "Autoboot in %d seconds\\n" help This string is displayed before the boot delay selected by @@ -1250,7 +1285,6 @@ config AUTOBOOT_PROMPT config AUTOBOOT_ENCRYPTION bool "Enable encryption in autoboot stopping" - depends on AUTOBOOT_KEYED help This option allows a string to be entered into U-Boot to stop the autoboot. @@ -1277,7 +1311,7 @@ config AUTOBOOT_SHA256_FALLBACK config AUTOBOOT_DELAY_STR string "Delay autobooting via specific input key / string" - depends on AUTOBOOT_KEYED && !AUTOBOOT_ENCRYPTION + depends on !AUTOBOOT_ENCRYPTION help This option delays the automatic boot feature by issuing a specific input key or string. If CONFIG_AUTOBOOT_DELAY_STR @@ -1289,7 +1323,7 @@ config AUTOBOOT_DELAY_STR config AUTOBOOT_STOP_STR string "Stop autobooting via specific input key / string" - depends on AUTOBOOT_KEYED && !AUTOBOOT_ENCRYPTION + depends on !AUTOBOOT_ENCRYPTION help This option enables stopping (aborting) of the automatic boot feature only by issuing a specific input key or @@ -1301,7 +1335,7 @@ config AUTOBOOT_STOP_STR config AUTOBOOT_KEYED_CTRLC bool "Enable Ctrl-C autoboot interruption" - depends on AUTOBOOT_KEYED && !AUTOBOOT_ENCRYPTION + depends on !AUTOBOOT_ENCRYPTION help This option allows for the boot sequence to be interrupted by ctrl-c, in addition to the "bootdelaykey" and "bootstopkey". @@ -1310,7 +1344,7 @@ config AUTOBOOT_KEYED_CTRLC config AUTOBOOT_NEVER_TIMEOUT bool "Make the password entry never time-out" - depends on AUTOBOOT_KEYED && AUTOBOOT_ENCRYPTION && CRYPT_PW + depends on AUTOBOOT_ENCRYPTION && CRYPT_PW help This option removes the timeout from the password entry when the user first presses the <Enter> key before entering @@ -1318,7 +1352,7 @@ config AUTOBOOT_NEVER_TIMEOUT config AUTOBOOT_STOP_STR_ENABLE bool "Enable fixed string to stop autobooting" - depends on AUTOBOOT_KEYED && AUTOBOOT_ENCRYPTION + depends on AUTOBOOT_ENCRYPTION help This option enables the feature to add a fixed stop string that is defined at compile time. @@ -1349,9 +1383,12 @@ config AUTOBOOT_STOP_STR_SHA256 includes a ":", the portion prior to the ":" will be treated as a salt value. +endif # AUTOBOOT_KEYED + +if !AUTOBOOT_KEYED + config AUTOBOOT_USE_MENUKEY bool "Allow a specify key to run a menu from the environment" - depends on !AUTOBOOT_KEYED help If a specific key is pressed to stop autoboot, then the commands in the environment variable 'menucmd' are executed before boot starts. @@ -1366,6 +1403,10 @@ config AUTOBOOT_MENUKEY For example, 33 means "!" in ASCII, so pressing ! at boot would take this action. +endif + +endif # AUTOBOOT + config AUTOBOOT_MENU_SHOW bool "Show a menu on boot" depends on CMD_BOOTMENU @@ -1473,6 +1514,15 @@ if OF_LIBFDT menu "Devicetree fixup" +config OF_ENV_SETUP + bool "Run a command from environment to set up device tree before boot" + depends on CMD_FDT + help + This causes U-Boot to run a command from the environment variable + fdt_fixup before booting into the operating system, which can use the + fdt command to modify the device tree. The device tree is then passed + to the OS. + config OF_BOARD_SETUP bool "Set up board-specific details in device tree before boot" help @@ -1561,6 +1611,7 @@ config BOOTARGS_SUBST config USE_BOOTCOMMAND bool "Enable a default value for bootcmd" + depends on CMDLINE help Provide a default value for the bootcmd entry in the environment. If autoboot is enabled this is what will be run automatically. Enable @@ -1580,6 +1631,7 @@ config BOOTCOMMAND config USE_PREBOOT bool "Enable preboot" + depends on CMDLINE help When this option is enabled, the existence of the environment variable "preboot" will be checked immediately before starting the diff --git a/boot/Makefile b/boot/Makefile index ad608598d29..a90ebea5a86 100644 --- a/boot/Makefile +++ b/boot/Makefile @@ -25,14 +25,16 @@ obj-$(CONFIG_$(SPL_TPL_)BOOTSTD) += bootflow.o obj-$(CONFIG_$(SPL_TPL_)BOOTSTD) += bootmeth-uclass.o obj-$(CONFIG_$(SPL_TPL_)BOOTSTD) += bootstd-uclass.o +obj-$(CONFIG_$(SPL_TPL_)BOOTSTD_PROG) += prog_boot.o + obj-$(CONFIG_$(SPL_TPL_)BOOTMETH_EXTLINUX) += bootmeth_extlinux.o obj-$(CONFIG_$(SPL_TPL_)BOOTMETH_EXTLINUX_PXE) += bootmeth_pxe.o obj-$(CONFIG_$(SPL_TPL_)BOOTMETH_EFILOADER) += bootmeth_efi.o -obj-$(CONFIG_$(SPL_TPL_)BOOTMETH_CROS) += bootmeth_cros.o +obj-$(CONFIG_$(SPL_TPL_)BOOTMETH_CROS) += bootm.o bootm_os.o bootmeth_cros.o obj-$(CONFIG_$(SPL_TPL_)BOOTMETH_SANDBOX) += bootmeth_sandbox.o obj-$(CONFIG_$(SPL_TPL_)BOOTMETH_SCRIPT) += bootmeth_script.o ifdef CONFIG_$(SPL_TPL_)BOOTSTD_FULL -obj-$(CONFIG_CMD_BOOTEFI_BOOTMGR) += bootmeth_efi_mgr.o +obj-$(CONFIG_BOOTEFI_BOOTMGR) += bootmeth_efi_mgr.o obj-$(CONFIG_$(SPL_TPL_)EXPO) += bootflow_menu.o obj-$(CONFIG_$(SPL_TPL_)BOOTSTD) += bootflow_menu.o obj-$(CONFIG_$(SPL_TPL_)CEDIT) += cedit.o diff --git a/boot/bootm.c b/boot/bootm.c index cb61485c226..7a050ed41a7 100644 --- a/boot/bootm.c +++ b/boot/bootm.c @@ -6,6 +6,7 @@ #ifndef USE_HOSTCC #include <common.h> +#include <bootm.h> #include <bootstage.h> #include <cli.h> #include <command.h> @@ -44,14 +45,200 @@ DECLARE_GLOBAL_DATA_PTR; struct bootm_headers images; /* pointers to os/initrd/fdt images */ -static const void *boot_get_kernel(struct cmd_tbl *cmdtp, int flag, int argc, - char *const argv[], struct bootm_headers *images, - ulong *os_data, ulong *os_len); - __weak void board_quiesce_devices(void) { } +#if CONFIG_IS_ENABLED(LEGACY_IMAGE_FORMAT) +/** + * image_get_kernel - verify legacy format kernel image + * @img_addr: in RAM address of the legacy format image to be verified + * @verify: data CRC verification flag + * + * image_get_kernel() verifies legacy image integrity and returns pointer to + * legacy image header if image verification was completed successfully. + * + * returns: + * pointer to a legacy image header if valid image was found + * otherwise return NULL + */ +static struct legacy_img_hdr *image_get_kernel(ulong img_addr, int verify) +{ + struct legacy_img_hdr *hdr = (struct legacy_img_hdr *)img_addr; + + if (!image_check_magic(hdr)) { + puts("Bad Magic Number\n"); + bootstage_error(BOOTSTAGE_ID_CHECK_MAGIC); + return NULL; + } + bootstage_mark(BOOTSTAGE_ID_CHECK_HEADER); + + if (!image_check_hcrc(hdr)) { + puts("Bad Header Checksum\n"); + bootstage_error(BOOTSTAGE_ID_CHECK_HEADER); + return NULL; + } + + bootstage_mark(BOOTSTAGE_ID_CHECK_CHECKSUM); + image_print_contents(hdr); + + if (verify) { + puts(" Verifying Checksum ... "); + if (!image_check_dcrc(hdr)) { + printf("Bad Data CRC\n"); + bootstage_error(BOOTSTAGE_ID_CHECK_CHECKSUM); + return NULL; + } + puts("OK\n"); + } + bootstage_mark(BOOTSTAGE_ID_CHECK_ARCH); + + if (!image_check_target_arch(hdr)) { + printf("Unsupported Architecture 0x%x\n", image_get_arch(hdr)); + bootstage_error(BOOTSTAGE_ID_CHECK_ARCH); + return NULL; + } + return hdr; +} +#endif + +/** + * boot_get_kernel() - find kernel image + * + * @addr_fit: first argument to bootm: address, fit configuration, etc. + * @os_data: pointer to a ulong variable, will hold os data start address + * @os_len: pointer to a ulong variable, will hold os data length + * address and length, otherwise NULL + * pointer to image header if valid image was found, plus kernel start + * @kernp: image header if valid image was found, otherwise NULL + * + * boot_get_kernel() tries to find a kernel image, verifies its integrity + * and locates kernel data. + * + * Return: 0 on success, -ve on error. -EPROTOTYPE means that the image is in + * a wrong or unsupported format + */ +static int boot_get_kernel(const char *addr_fit, struct bootm_headers *images, + ulong *os_data, ulong *os_len, const void **kernp) +{ +#if CONFIG_IS_ENABLED(LEGACY_IMAGE_FORMAT) + struct legacy_img_hdr *hdr; +#endif + ulong img_addr; + const void *buf; + const char *fit_uname_config = NULL, *fit_uname_kernel = NULL; +#if CONFIG_IS_ENABLED(FIT) + int os_noffset; +#endif + +#ifdef CONFIG_ANDROID_BOOT_IMAGE + const void *boot_img; + const void *vendor_boot_img; +#endif + img_addr = genimg_get_kernel_addr_fit(addr_fit, &fit_uname_config, + &fit_uname_kernel); + + if (IS_ENABLED(CONFIG_CMD_BOOTM_PRE_LOAD)) + img_addr += image_load_offset; + + bootstage_mark(BOOTSTAGE_ID_CHECK_MAGIC); + + /* check image type, for FIT images get FIT kernel node */ + *os_data = *os_len = 0; + buf = map_sysmem(img_addr, 0); + switch (genimg_get_format(buf)) { +#if CONFIG_IS_ENABLED(LEGACY_IMAGE_FORMAT) + case IMAGE_FORMAT_LEGACY: + printf("## Booting kernel from Legacy Image at %08lx ...\n", + img_addr); + hdr = image_get_kernel(img_addr, images->verify); + if (!hdr) + return -EINVAL; + bootstage_mark(BOOTSTAGE_ID_CHECK_IMAGETYPE); + + /* get os_data and os_len */ + switch (image_get_type(hdr)) { + case IH_TYPE_KERNEL: + case IH_TYPE_KERNEL_NOLOAD: + *os_data = image_get_data(hdr); + *os_len = image_get_data_size(hdr); + break; + case IH_TYPE_MULTI: + image_multi_getimg(hdr, 0, os_data, os_len); + break; + case IH_TYPE_STANDALONE: + *os_data = image_get_data(hdr); + *os_len = image_get_data_size(hdr); + break; + default: + bootstage_error(BOOTSTAGE_ID_CHECK_IMAGETYPE); + return -EPROTOTYPE; + } + + /* + * copy image header to allow for image overwrites during + * kernel decompression. + */ + memmove(&images->legacy_hdr_os_copy, hdr, + sizeof(struct legacy_img_hdr)); + + /* save pointer to image header */ + images->legacy_hdr_os = hdr; + + images->legacy_hdr_valid = 1; + bootstage_mark(BOOTSTAGE_ID_DECOMP_IMAGE); + break; +#endif +#if CONFIG_IS_ENABLED(FIT) + case IMAGE_FORMAT_FIT: + os_noffset = fit_image_load(images, img_addr, + &fit_uname_kernel, &fit_uname_config, + IH_ARCH_DEFAULT, IH_TYPE_KERNEL, + BOOTSTAGE_ID_FIT_KERNEL_START, + FIT_LOAD_IGNORED, os_data, os_len); + if (os_noffset < 0) + return -ENOENT; + + images->fit_hdr_os = map_sysmem(img_addr, 0); + images->fit_uname_os = fit_uname_kernel; + images->fit_uname_cfg = fit_uname_config; + images->fit_noffset_os = os_noffset; + break; +#endif +#ifdef CONFIG_ANDROID_BOOT_IMAGE + case IMAGE_FORMAT_ANDROID: { + int ret; + + boot_img = buf; + vendor_boot_img = NULL; + if (IS_ENABLED(CONFIG_CMD_ABOOTIMG)) { + boot_img = map_sysmem(get_abootimg_addr(), 0); + vendor_boot_img = map_sysmem(get_avendor_bootimg_addr(), 0); + } + printf("## Booting Android Image at 0x%08lx ...\n", img_addr); + ret = android_image_get_kernel(boot_img, vendor_boot_img, + images->verify, os_data, os_len); + if (IS_ENABLED(CONFIG_CMD_ABOOTIMG)) { + unmap_sysmem(vendor_boot_img); + unmap_sysmem(boot_img); + } + if (ret) + return ret; + break; + } +#endif + default: + bootstage_error(BOOTSTAGE_ID_CHECK_IMAGETYPE); + return -EPROTOTYPE; + } + + debug(" kernel data at 0x%08lx, len = 0x%08lx (%ld)\n", + *os_data, *os_len, *os_len); + *kernp = buf; + + return 0; +} + #ifdef CONFIG_LMB static void boot_start_lmb(struct bootm_headers *images) { @@ -69,8 +256,7 @@ static void boot_start_lmb(struct bootm_headers *images) static inline void boot_start_lmb(struct bootm_headers *images) { } #endif -static int bootm_start(struct cmd_tbl *cmdtp, int flag, int argc, - char *const argv[]) +static int bootm_start(void) { memset((void *)&images, 0, sizeof(images)); images.verify = env_get_yesno("verify"); @@ -83,22 +269,31 @@ static int bootm_start(struct cmd_tbl *cmdtp, int flag, int argc, return 0; } -static ulong bootm_data_addr(int argc, char *const argv[]) +static ulong bootm_data_addr(const char *addr_str) { ulong addr; - if (argc > 0) - addr = simple_strtoul(argv[0], NULL, 16); + if (addr_str) + addr = hextoul(addr_str, NULL); else addr = image_load_addr; return addr; } -static int bootm_pre_load(struct cmd_tbl *cmdtp, int flag, int argc, - char *const argv[]) +/** + * bootm_pre_load() - Handle the pre-load processing + * + * This can be used to do a full signature check of the image, for example. + * It calls image_pre_load() with the data address of the image to check. + * + * @addr_str: String containing load address in hex, or NULL to use + * image_load_addr + * Return: 0 if OK, CMD_RET_FAILURE on failure + */ +static int bootm_pre_load(const char *addr_str) { - ulong data_addr = bootm_data_addr(argc, argv); + ulong data_addr = bootm_data_addr(addr_str); int ret = 0; if (IS_ENABLED(CONFIG_CMD_BOOTM_PRE_LOAD)) @@ -110,8 +305,14 @@ static int bootm_pre_load(struct cmd_tbl *cmdtp, int flag, int argc, return ret; } -static int bootm_find_os(struct cmd_tbl *cmdtp, int flag, int argc, - char *const argv[]) +/** + * bootm_find_os(): Find the OS to boot + * + * @cmd_name: Command name that started this boot, e.g. "bootm" + * @addr_fit: Address and/or FIT specifier (first arg of bootm command) + * Return: 0 on success, -ve on error + */ +static int bootm_find_os(const char *cmd_name, const char *addr_fit) { const void *os_hdr; #ifdef CONFIG_ANDROID_BOOT_IMAGE @@ -122,10 +323,13 @@ static int bootm_find_os(struct cmd_tbl *cmdtp, int flag, int argc, int ret; /* get kernel image header, start address and length */ - os_hdr = boot_get_kernel(cmdtp, flag, argc, argv, - &images, &images.os.image_start, &images.os.image_len); - if (images.os.image_len == 0) { - puts("ERROR: can't get kernel image!\n"); + ret = boot_get_kernel(addr_fit, &images, &images.os.image_start, + &images.os.image_len, &os_hdr); + if (ret) { + if (ret == -EPROTOTYPE) + printf("Wrong Image Type for %s command\n", cmd_name); + + printf("ERROR %dE: can't get kernel image!\n", ret); return 1; } @@ -240,24 +444,8 @@ static int bootm_find_os(struct cmd_tbl *cmdtp, int flag, int argc, } if (images.os.type == IH_TYPE_KERNEL_NOLOAD) { - if (IS_ENABLED(CONFIG_CMD_BOOTI) && - images.os.arch == IH_ARCH_ARM64 && - images.os.os == IH_OS_LINUX) { - ulong image_addr; - ulong image_size; - - ret = booti_setup(images.os.image_start, &image_addr, - &image_size, true); - if (ret != 0) - return 1; - - images.os.type = IH_TYPE_KERNEL; - images.os.load = image_addr; - images.ep = image_addr; - } else { - images.os.load = images.os.image_start; - images.ep += images.os.image_start; - } + images.os.load = images.os.image_start; + images.ep += images.os.image_start; } images.os.start = map_to_sysmem(os_hdr); @@ -266,30 +454,58 @@ static int bootm_find_os(struct cmd_tbl *cmdtp, int flag, int argc, } /** - * bootm_find_images - wrapper to find and locate various images - * @flag: Ignored Argument - * @argc: command argument count - * @argv: command argument list - * @start: OS image start address - * @size: OS image size - * - * boot_find_images() will attempt to load an available ramdisk, - * flattened device tree, as well as specifically marked - * "loadable" images (loadables are FIT only) - * - * Note: bootm_find_images will skip an image if it is not found + * check_overlap() - Check if an image overlaps the OS * - * @return: - * 0, if all existing images were loaded correctly - * 1, if an image is found but corrupted, or invalid + * @name: Name of image to check (used to print error) + * @base: Base address of image + * @end: End address of image (+1) + * @os_start: Start of OS + * @os_size: Size of OS in bytes + * Return: 0 if OK, -EXDEV if the image overlaps the OS */ -int bootm_find_images(int flag, int argc, char *const argv[], ulong start, - ulong size) +static int check_overlap(const char *name, ulong base, ulong end, + ulong os_start, ulong os_size) { + ulong os_end; + + if (!base) + return 0; + os_end = os_start + os_size; + + if ((base >= os_start && base < os_end) || + (end > os_start && end <= os_end) || + (base < os_start && end >= os_end)) { + printf("ERROR: %s image overlaps OS image (OS=%lx..%lx)\n", + name, os_start, os_end); + + return -EXDEV; + } + + return 0; +} + +int bootm_find_images(ulong img_addr, const char *conf_ramdisk, + const char *conf_fdt, ulong start, ulong size) +{ + const char *select = conf_ramdisk; + char addr_str[17]; + void *buf; int ret; + if (IS_ENABLED(CONFIG_ANDROID_BOOT_IMAGE)) { + /* Look for an Android boot image */ + buf = map_sysmem(images.os.start, 0); + if (buf && genimg_get_format(buf) == IMAGE_FORMAT_ANDROID) { + strcpy(addr_str, simple_xtoa(img_addr)); + select = addr_str; + } + } + + if (conf_ramdisk) + select = conf_ramdisk; + /* find ramdisk */ - ret = boot_get_ramdisk(argc, argv, &images, IH_INITRD_ARCH, + ret = boot_get_ramdisk(select, &images, IH_INITRD_ARCH, &images.rd_start, &images.rd_end); if (ret) { puts("Ramdisk image is corrupt or invalid\n"); @@ -297,46 +513,33 @@ int bootm_find_images(int flag, int argc, char *const argv[], ulong start, } /* check if ramdisk overlaps OS image */ - if (images.rd_start && (((ulong)images.rd_start >= start && - (ulong)images.rd_start < start + size) || - ((ulong)images.rd_end > start && - (ulong)images.rd_end <= start + size) || - ((ulong)images.rd_start < start && - (ulong)images.rd_end >= start + size))) { - printf("ERROR: RD image overlaps OS image (OS=0x%lx..0x%lx)\n", - start, start + size); + if (check_overlap("RD", images.rd_start, images.rd_end, start, size)) return 1; - } -#if CONFIG_IS_ENABLED(OF_LIBFDT) - /* find flattened device tree */ - ret = boot_get_fdt(flag, argc, argv, IH_ARCH_DEFAULT, &images, - &images.ft_addr, &images.ft_len); - if (ret) { - puts("Could not find a valid device tree\n"); - return 1; - } + if (CONFIG_IS_ENABLED(OF_LIBFDT)) { + buf = map_sysmem(img_addr, 0); - /* check if FDT overlaps OS image */ - if (images.ft_addr && - (((ulong)images.ft_addr >= start && - (ulong)images.ft_addr < start + size) || - ((ulong)images.ft_addr + images.ft_len >= start && - (ulong)images.ft_addr + images.ft_len < start + size))) { - printf("ERROR: FDT image overlaps OS image (OS=0x%lx..0x%lx)\n", - start, start + size); - return 1; - } + /* find flattened device tree */ + ret = boot_get_fdt(buf, conf_fdt, IH_ARCH_DEFAULT, &images, + &images.ft_addr, &images.ft_len); + if (ret) { + puts("Could not find a valid device tree\n"); + return 1; + } - if (IS_ENABLED(CONFIG_CMD_FDT)) - set_working_fdt_addr(map_to_sysmem(images.ft_addr)); -#endif + /* check if FDT overlaps OS image */ + if (check_overlap("FDT", map_to_sysmem(images.ft_addr), + images.ft_len, start, size)) + return 1; + + if (IS_ENABLED(CONFIG_CMD_FDT)) + set_working_fdt_addr(map_to_sysmem(images.ft_addr)); + } #if CONFIG_IS_ENABLED(FIT) if (IS_ENABLED(CONFIG_FPGA)) { /* find bitstreams */ - ret = boot_get_fpga(argc, argv, &images, IH_ARCH_DEFAULT, - NULL, NULL); + ret = boot_get_fpga(&images); if (ret) { printf("FPGA image is corrupted or invalid\n"); return 1; @@ -344,8 +547,7 @@ int bootm_find_images(int flag, int argc, char *const argv[], ulong start, } /* find all of the loadables */ - ret = boot_get_loadable(argc, argv, &images, IH_ARCH_DEFAULT, - NULL, NULL); + ret = boot_get_loadable(&images); if (ret) { printf("Loadable(s) is corrupt or invalid\n"); return 1; @@ -355,15 +557,17 @@ int bootm_find_images(int flag, int argc, char *const argv[], ulong start, return 0; } -static int bootm_find_other(struct cmd_tbl *cmdtp, int flag, int argc, - char *const argv[]) +static int bootm_find_other(ulong img_addr, const char *conf_ramdisk, + const char *conf_fdt) { - if (((images.os.type == IH_TYPE_KERNEL) || - (images.os.type == IH_TYPE_KERNEL_NOLOAD) || - (images.os.type == IH_TYPE_MULTI)) && - (images.os.os == IH_OS_LINUX || - images.os.os == IH_OS_VXWORKS)) - return bootm_find_images(flag, argc, argv, 0, 0); + if ((images.os.type == IH_TYPE_KERNEL || + images.os.type == IH_TYPE_KERNEL_NOLOAD || + images.os.type == IH_TYPE_MULTI) && + (images.os.os == IH_OS_LINUX || images.os.os == IH_OS_VXWORKS || + images.os.os == IH_OS_EFI || images.os.os == IH_OS_TEE)) { + return bootm_find_images(img_addr, conf_ramdisk, conf_fdt, 0, + 0); + } return 0; } @@ -426,6 +630,24 @@ static int bootm_load_os(struct bootm_headers *images, int boot_progress) void *load_buf, *image_buf; int err; + /* + * For a "noload" compressed kernel we need to allocate a buffer large + * enough to decompress in to and use that as the load address now. + * Assume that the kernel compression is at most a factor of 4 since + * zstd almost achieves that. + * Use an alignment of 2MB since this might help arm64 + */ + if (os.type == IH_TYPE_KERNEL_NOLOAD && os.comp != IH_COMP_NONE) { + ulong req_size = ALIGN(image_len * 4, SZ_1M); + + load = lmb_alloc(&images->lmb, req_size, SZ_2M); + if (!load) + return 1; + os.load = load; + debug("Allocated %lx bytes at %lx for kernel (size %lx) decompression\n", + req_size, load, image_len); + } + load_buf = map_sysmem(load, 0); image_buf = map_sysmem(os.image_start, image_len); err = image_decomp(os.comp, load, os.image_start, os.type, @@ -466,6 +688,31 @@ static int bootm_load_os(struct bootm_headers *images, int boot_progress) } } + if (IS_ENABLED(CONFIG_CMD_BOOTI) && images->os.arch == IH_ARCH_ARM64 && + images->os.os == IH_OS_LINUX) { + ulong relocated_addr; + ulong image_size; + int ret; + + ret = booti_setup(load, &relocated_addr, &image_size, false); + if (ret) { + printf("Failed to prep arm64 kernel (err=%d)\n", ret); + return BOOTM_ERR_RESET; + } + + /* Handle BOOTM_STATE_LOADOS */ + if (relocated_addr != load) { + printf("Moving Image from 0x%lx to 0x%lx, end=%lx\n", + load, relocated_addr, + relocated_addr + image_size); + memmove((void *)relocated_addr, load_buf, image_size); + } + + images->ep = relocated_addr; + images->os.start = relocated_addr; + images->os.end = relocated_addr + image_size; + } + lmb_reserve(&images->lmb, images->os.load, (load_end - images->os.load)); return 0; @@ -743,35 +990,9 @@ unmap_image: return ret; } -/** - * Execute selected states of the bootm command. - * - * Note the arguments to this state must be the first argument, Any 'bootm' - * or sub-command arguments must have already been taken. - * - * Note that if states contains more than one flag it MUST contain - * BOOTM_STATE_START, since this handles and consumes the command line args. - * - * Also note that aside from boot_os_fn functions and bootm_load_os no other - * functions we store the return value of in 'ret' may use a negative return - * value, without special handling. - * - * @param cmdtp Pointer to bootm command table entry - * @param flag Command flags (CMD_FLAG_...) - * @param argc Number of subcommand arguments (0 = no arguments) - * @param argv Arguments - * @param states Mask containing states to run (BOOTM_STATE_...) - * @param images Image header information - * @param boot_progress 1 to show boot progress, 0 to not do this - * Return: 0 if ok, something else on error. Some errors will cause this - * function to perform a reboot! If states contains BOOTM_STATE_OS_GO - * then the intent is to boot an OS, so this function will not return - * unless the image type is standalone. - */ -int do_bootm_states(struct cmd_tbl *cmdtp, int flag, int argc, - char *const argv[], int states, struct bootm_headers *images, - int boot_progress) +int bootm_run_states(struct bootm_info *bmi, int states) { + struct bootm_headers *images = bmi->images; boot_os_fn *boot_fn; ulong iflag = 0; int ret = 0, need_boot_fn; @@ -783,16 +1004,22 @@ int do_bootm_states(struct cmd_tbl *cmdtp, int flag, int argc, * any error. */ if (states & BOOTM_STATE_START) - ret = bootm_start(cmdtp, flag, argc, argv); + ret = bootm_start(); if (!ret && (states & BOOTM_STATE_PRE_LOAD)) - ret = bootm_pre_load(cmdtp, flag, argc, argv); + ret = bootm_pre_load(bmi->addr_img); if (!ret && (states & BOOTM_STATE_FINDOS)) - ret = bootm_find_os(cmdtp, flag, argc, argv); + ret = bootm_find_os(bmi->cmd_name, bmi->addr_img); + + if (!ret && (states & BOOTM_STATE_FINDOTHER)) { + ulong img_addr; - if (!ret && (states & BOOTM_STATE_FINDOTHER)) - ret = bootm_find_other(cmdtp, flag, argc, argv); + img_addr = bmi->addr_img ? hextoul(bmi->addr_img, NULL) + : image_load_addr; + ret = bootm_find_other(img_addr, bmi->conf_ramdisk, + bmi->conf_fdt); + } if (IS_ENABLED(CONFIG_MEASURED_BOOT) && !ret && (states & BOOTM_STATE_MEASURE)) @@ -845,20 +1072,23 @@ int do_bootm_states(struct cmd_tbl *cmdtp, int flag, int argc, return 1; } - /* Call various other states that are not generally used */ if (!ret && (states & BOOTM_STATE_OS_CMDLINE)) - ret = boot_fn(BOOTM_STATE_OS_CMDLINE, argc, argv, images); + ret = boot_fn(BOOTM_STATE_OS_CMDLINE, bmi); if (!ret && (states & BOOTM_STATE_OS_BD_T)) - ret = boot_fn(BOOTM_STATE_OS_BD_T, argc, argv, images); + ret = boot_fn(BOOTM_STATE_OS_BD_T, bmi); if (!ret && (states & BOOTM_STATE_OS_PREP)) { - ret = bootm_process_cmdline_env(images->os.os == IH_OS_LINUX); + int flags = 0; + /* For Linux OS do all substitutions at console processing */ + if (images->os.os == IH_OS_LINUX) + flags = BOOTM_CL_ALL; + ret = bootm_process_cmdline_env(flags); if (ret) { printf("Cmdline setup failed (err=%d)\n", ret); ret = CMD_RET_FAILURE; goto err; } - ret = boot_fn(BOOTM_STATE_OS_PREP, argc, argv, images); + ret = boot_fn(BOOTM_STATE_OS_PREP, bmi); } #ifdef CONFIG_TRACE @@ -866,10 +1096,9 @@ int do_bootm_states(struct cmd_tbl *cmdtp, int flag, int argc, if (!ret && (states & BOOTM_STATE_OS_FAKE_GO)) { char *cmd_list = env_get("fakegocmd"); - ret = boot_selected_os(argc, argv, BOOTM_STATE_OS_FAKE_GO, - images, boot_fn); + ret = boot_selected_os(BOOTM_STATE_OS_FAKE_GO, bmi, boot_fn); if (!ret && cmd_list) - ret = run_command_list(cmd_list, -1, flag); + ret = run_command_list(cmd_list, -1, 0); } #endif @@ -881,37 +1110,61 @@ int do_bootm_states(struct cmd_tbl *cmdtp, int flag, int argc, /* Now run the OS! We hope this doesn't return */ if (!ret && (states & BOOTM_STATE_OS_GO)) - ret = boot_selected_os(argc, argv, BOOTM_STATE_OS_GO, - images, boot_fn); + ret = boot_selected_os(BOOTM_STATE_OS_GO, bmi, boot_fn); /* Deal with any fallout */ err: if (iflag) enable_interrupts(); - if (ret == BOOTM_ERR_UNIMPLEMENTED) + if (ret == BOOTM_ERR_UNIMPLEMENTED) { bootstage_error(BOOTSTAGE_ID_DECOMP_UNIMPL); - else if (ret == BOOTM_ERR_RESET) - do_reset(cmdtp, flag, argc, argv); + } else if (ret == BOOTM_ERR_RESET) { + printf("Resetting the board...\n"); + reset_cpu(); + } return ret; } +int boot_run(struct bootm_info *bmi, const char *cmd, int extra_states) +{ + int states; + + bmi->cmd_name = cmd; + states = BOOTM_STATE_MEASURE | BOOTM_STATE_OS_PREP | + BOOTM_STATE_OS_FAKE_GO | BOOTM_STATE_OS_GO; + if (IS_ENABLED(CONFIG_SYS_BOOT_RAMDISK_HIGH)) + states |= BOOTM_STATE_RAMDISK; + states |= extra_states; + + return bootm_run_states(bmi, states); +} + +int bootm_run(struct bootm_info *bmi) +{ + return boot_run(bmi, "bootm", BOOTM_STATE_START | BOOTM_STATE_FINDOS | + BOOTM_STATE_PRE_LOAD | BOOTM_STATE_FINDOTHER | + BOOTM_STATE_LOADOS); +} + +int bootz_run(struct bootm_info *bmi) +{ + return boot_run(bmi, "bootz", 0); +} + +int booti_run(struct bootm_info *bmi) +{ + return boot_run(bmi, "booti", 0); +} + int bootm_boot_start(ulong addr, const char *cmdline) { - static struct cmd_tbl cmd = {"bootm"}; char addr_str[30]; - char *argv[] = {addr_str, NULL}; + struct bootm_info bmi; int states; int ret; - /* - * TODO([email protected]): This uses the command-line interface, but - * should not. To clean this up, the various bootm states need to be - * passed an info structure instead of cmdline flags. Then this can - * set up the required info and move through the states without needing - * the command line. - */ states = BOOTM_STATE_START | BOOTM_STATE_FINDOS | BOOTM_STATE_PRE_LOAD | BOOTM_STATE_FINDOTHER | BOOTM_STATE_LOADOS | BOOTM_STATE_OS_PREP | BOOTM_STATE_OS_FAKE_GO | @@ -929,196 +1182,20 @@ int bootm_boot_start(ulong addr, const char *cmdline) printf("Failed to set cmdline\n"); return ret; } - ret = do_bootm_states(&cmd, 0, 1, argv, states, &images, 1); + bootm_init(&bmi); + bmi.addr_img = addr_str; + bmi.cmd_name = "bootm"; + ret = bootm_run_states(&bmi, states); return ret; } -#if CONFIG_IS_ENABLED(LEGACY_IMAGE_FORMAT) -/** - * image_get_kernel - verify legacy format kernel image - * @img_addr: in RAM address of the legacy format image to be verified - * @verify: data CRC verification flag - * - * image_get_kernel() verifies legacy image integrity and returns pointer to - * legacy image header if image verification was completed successfully. - * - * returns: - * pointer to a legacy image header if valid image was found - * otherwise return NULL - */ -static struct legacy_img_hdr *image_get_kernel(ulong img_addr, int verify) +void bootm_init(struct bootm_info *bmi) { - struct legacy_img_hdr *hdr = (struct legacy_img_hdr *)img_addr; - - if (!image_check_magic(hdr)) { - puts("Bad Magic Number\n"); - bootstage_error(BOOTSTAGE_ID_CHECK_MAGIC); - return NULL; - } - bootstage_mark(BOOTSTAGE_ID_CHECK_HEADER); - - if (!image_check_hcrc(hdr)) { - puts("Bad Header Checksum\n"); - bootstage_error(BOOTSTAGE_ID_CHECK_HEADER); - return NULL; - } - - bootstage_mark(BOOTSTAGE_ID_CHECK_CHECKSUM); - image_print_contents(hdr); - - if (verify) { - puts(" Verifying Checksum ... "); - if (!image_check_dcrc(hdr)) { - printf("Bad Data CRC\n"); - bootstage_error(BOOTSTAGE_ID_CHECK_CHECKSUM); - return NULL; - } - puts("OK\n"); - } - bootstage_mark(BOOTSTAGE_ID_CHECK_ARCH); - - if (!image_check_target_arch(hdr)) { - printf("Unsupported Architecture 0x%x\n", image_get_arch(hdr)); - bootstage_error(BOOTSTAGE_ID_CHECK_ARCH); - return NULL; - } - return hdr; -} -#endif - -/** - * boot_get_kernel - find kernel image - * @os_data: pointer to a ulong variable, will hold os data start address - * @os_len: pointer to a ulong variable, will hold os data length - * - * boot_get_kernel() tries to find a kernel image, verifies its integrity - * and locates kernel data. - * - * returns: - * pointer to image header if valid image was found, plus kernel start - * address and length, otherwise NULL - */ -static const void *boot_get_kernel(struct cmd_tbl *cmdtp, int flag, int argc, - char *const argv[], struct bootm_headers *images, - ulong *os_data, ulong *os_len) -{ -#if CONFIG_IS_ENABLED(LEGACY_IMAGE_FORMAT) - struct legacy_img_hdr *hdr; -#endif - ulong img_addr; - const void *buf; - const char *fit_uname_config = NULL; - const char *fit_uname_kernel = NULL; -#if CONFIG_IS_ENABLED(FIT) - int os_noffset; -#endif - -#ifdef CONFIG_ANDROID_BOOT_IMAGE - const void *boot_img; - const void *vendor_boot_img; -#endif - img_addr = genimg_get_kernel_addr_fit(argc < 1 ? NULL : argv[0], - &fit_uname_config, - &fit_uname_kernel); - - if (IS_ENABLED(CONFIG_CMD_BOOTM_PRE_LOAD)) - img_addr += image_load_offset; - - bootstage_mark(BOOTSTAGE_ID_CHECK_MAGIC); - - /* check image type, for FIT images get FIT kernel node */ - *os_data = *os_len = 0; - buf = map_sysmem(img_addr, 0); - switch (genimg_get_format(buf)) { -#if CONFIG_IS_ENABLED(LEGACY_IMAGE_FORMAT) - case IMAGE_FORMAT_LEGACY: - printf("## Booting kernel from Legacy Image at %08lx ...\n", - img_addr); - hdr = image_get_kernel(img_addr, images->verify); - if (!hdr) - return NULL; - bootstage_mark(BOOTSTAGE_ID_CHECK_IMAGETYPE); - - /* get os_data and os_len */ - switch (image_get_type(hdr)) { - case IH_TYPE_KERNEL: - case IH_TYPE_KERNEL_NOLOAD: - *os_data = image_get_data(hdr); - *os_len = image_get_data_size(hdr); - break; - case IH_TYPE_MULTI: - image_multi_getimg(hdr, 0, os_data, os_len); - break; - case IH_TYPE_STANDALONE: - *os_data = image_get_data(hdr); - *os_len = image_get_data_size(hdr); - break; - default: - printf("Wrong Image Type for %s command\n", - cmdtp->name); - bootstage_error(BOOTSTAGE_ID_CHECK_IMAGETYPE); - return NULL; - } - - /* - * copy image header to allow for image overwrites during - * kernel decompression. - */ - memmove(&images->legacy_hdr_os_copy, hdr, - sizeof(struct legacy_img_hdr)); - - /* save pointer to image header */ - images->legacy_hdr_os = hdr; - - images->legacy_hdr_valid = 1; - bootstage_mark(BOOTSTAGE_ID_DECOMP_IMAGE); - break; -#endif -#if CONFIG_IS_ENABLED(FIT) - case IMAGE_FORMAT_FIT: - os_noffset = fit_image_load(images, img_addr, - &fit_uname_kernel, &fit_uname_config, - IH_ARCH_DEFAULT, IH_TYPE_KERNEL, - BOOTSTAGE_ID_FIT_KERNEL_START, - FIT_LOAD_IGNORED, os_data, os_len); - if (os_noffset < 0) - return NULL; - - images->fit_hdr_os = map_sysmem(img_addr, 0); - images->fit_uname_os = fit_uname_kernel; - images->fit_uname_cfg = fit_uname_config; - images->fit_noffset_os = os_noffset; - break; -#endif -#ifdef CONFIG_ANDROID_BOOT_IMAGE - case IMAGE_FORMAT_ANDROID: - boot_img = buf; - vendor_boot_img = NULL; - if (IS_ENABLED(CONFIG_CMD_ABOOTIMG)) { - boot_img = map_sysmem(get_abootimg_addr(), 0); - vendor_boot_img = map_sysmem(get_avendor_bootimg_addr(), 0); - } - printf("## Booting Android Image at 0x%08lx ...\n", img_addr); - if (android_image_get_kernel(boot_img, vendor_boot_img, images->verify, - os_data, os_len)) - return NULL; - if (IS_ENABLED(CONFIG_CMD_ABOOTIMG)) { - unmap_sysmem(vendor_boot_img); - unmap_sysmem(boot_img); - } - break; -#endif - default: - printf("Wrong Image Format for %s command\n", cmdtp->name); - bootstage_error(BOOTSTAGE_ID_FIT_KERNEL_INFO); - return NULL; - } - - debug(" kernel data at 0x%08lx, len = 0x%08lx (%ld)\n", - *os_data, *os_len, *os_len); - - return buf; + memset(bmi, '\0', sizeof(struct bootm_info)); + bmi->boot_progress = true; + if (IS_ENABLED(CONFIG_CMD_BOOTM)) + bmi->images = &images; } /** diff --git a/boot/bootm_os.c b/boot/bootm_os.c index 9c035b5be88..ccde72d22c1 100644 --- a/boot/bootm_os.c +++ b/boot/bootm_os.c @@ -23,9 +23,9 @@ DECLARE_GLOBAL_DATA_PTR; -static int do_bootm_standalone(int flag, int argc, char *const argv[], - struct bootm_headers *images) +static int do_bootm_standalone(int flag, struct bootm_info *bmi) { + struct bootm_headers *images = bmi->images; int (*appl)(int, char *const[]); if (!env_get_autostart()) { @@ -33,7 +33,7 @@ static int do_bootm_standalone(int flag, int argc, char *const argv[], return 0; } appl = (int (*)(int, char * const []))images->ep; - appl(argc, argv); + appl(bmi->argc, bmi->argv); return 0; } @@ -64,9 +64,9 @@ static void __maybe_unused fit_unsupported_reset(const char *msg) } #ifdef CONFIG_BOOTM_NETBSD -static int do_bootm_netbsd(int flag, int argc, char *const argv[], - struct bootm_headers *images) +static int do_bootm_netbsd(int flag, struct bootm_info *bmi) { + struct bootm_headers *images = bmi->images; void (*loader)(struct bd_info *bd, struct legacy_img_hdr *hdr, char *console, char *cmdline); struct legacy_img_hdr *os_hdr, *hdr; @@ -102,14 +102,14 @@ static int do_bootm_netbsd(int flag, int argc, char *const argv[], os_hdr = hdr; } - if (argc > 0) { + if (bmi->argc > 0) { ulong len; int i; - for (i = 0, len = 0; i < argc; i += 1) - len += strlen(argv[i]) + 1; + for (i = 0, len = 0; i < bmi->argc; i += 1) + len += strlen(bmi->argv[i]) + 1; cmdline = malloc(len); - copy_args(cmdline, argc, argv, ' '); + copy_args(cmdline, bmi->argc, bmi->argv, ' '); } else { cmdline = env_get("bootargs"); if (cmdline == NULL) @@ -137,9 +137,9 @@ static int do_bootm_netbsd(int flag, int argc, char *const argv[], #endif /* CONFIG_BOOTM_NETBSD*/ #ifdef CONFIG_BOOTM_RTEMS -static int do_bootm_rtems(int flag, int argc, char *const argv[], - struct bootm_headers *images) +static int do_bootm_rtems(int flag, struct bootm_info *bmi) { + struct bootm_headers *images = bmi->images; void (*entry_point)(struct bd_info *); if (flag != BOOTM_STATE_OS_GO) @@ -170,9 +170,9 @@ static int do_bootm_rtems(int flag, int argc, char *const argv[], #endif /* CONFIG_BOOTM_RTEMS */ #if defined(CONFIG_BOOTM_OSE) -static int do_bootm_ose(int flag, int argc, char *const argv[], - struct bootm_headers *images) +static int do_bootm_ose(int flag, struct bootm_info *bmi) { + struct bootm_headers *images = bmi->images; void (*entry_point)(void); if (flag != BOOTM_STATE_OS_GO) @@ -203,9 +203,9 @@ static int do_bootm_ose(int flag, int argc, char *const argv[], #endif /* CONFIG_BOOTM_OSE */ #if defined(CONFIG_BOOTM_PLAN9) -static int do_bootm_plan9(int flag, int argc, char *const argv[], - struct bootm_headers *images) +static int do_bootm_plan9(int flag, struct bootm_info *bmi) { + struct bootm_headers *images = bmi->images; void (*entry_point)(void); char *s; @@ -224,8 +224,8 @@ static int do_bootm_plan9(int flag, int argc, char *const argv[], if (s != NULL) { char *confaddr = (char *)hextoul(s, NULL); - if (argc > 0) { - copy_args(confaddr, argc, argv, '\n'); + if (bmi->argc) { + copy_args(confaddr, bmi->argc, bmi->argv, '\n'); } else { s = env_get("bootargs"); if (s != NULL) @@ -311,26 +311,19 @@ static void do_bootvx_fdt(struct bootm_headers *images) puts("## vxWorks terminated\n"); } -static int do_bootm_vxworks_legacy(int flag, int argc, char *const argv[], - struct bootm_headers *images) +static int do_bootm_vxworks_legacy(int flag, struct bootm_info *bmi) { + struct bootm_headers *images = bmi->images; + if (flag != BOOTM_STATE_OS_GO) return 0; -#if defined(CONFIG_FIT) - if (!images->legacy_hdr_valid) { - fit_unsupported_reset("VxWorks"); - return 1; - } -#endif - do_bootvx_fdt(images); return 1; } -int do_bootm_vxworks(int flag, int argc, char *const argv[], - struct bootm_headers *images) +int do_bootm_vxworks(int flag, struct bootm_info *bmi) { char *bootargs; int pos; @@ -355,19 +348,19 @@ int do_bootm_vxworks(int flag, int argc, char *const argv[], if (std_dtb) { if (flag & BOOTM_STATE_OS_PREP) printf(" Using standard DTB\n"); - return do_bootm_linux(flag, argc, argv, images); + return do_bootm_linux(flag, bmi); } else { if (flag & BOOTM_STATE_OS_PREP) printf(" !!! WARNING !!! Using legacy DTB\n"); - return do_bootm_vxworks_legacy(flag, argc, argv, images); + return do_bootm_vxworks_legacy(flag, bmi); } } #endif #if defined(CONFIG_CMD_ELF) -static int do_bootm_qnxelf(int flag, int argc, char *const argv[], - struct bootm_headers *images) +static int do_bootm_qnxelf(int flag, struct bootm_info *bmi) { + struct bootm_headers *images = bmi->images; char *local_args[2]; char str[16]; int dcache; @@ -383,7 +376,7 @@ static int do_bootm_qnxelf(int flag, int argc, char *const argv[], #endif sprintf(str, "%lx", images->ep); /* write entry-point into string */ - local_args[0] = argv[0]; + local_args[0] = bmi->argv[0]; local_args[1] = str; /* and provide it via the arguments */ /* @@ -403,9 +396,9 @@ static int do_bootm_qnxelf(int flag, int argc, char *const argv[], #endif #ifdef CONFIG_INTEGRITY -static int do_bootm_integrity(int flag, int argc, char *const argv[], - struct bootm_headers *images) +static int do_bootm_integrity(int flag, struct bootm_info *bmi) { + struct bootm_headers *images = bmi->images; void (*entry_point)(void); if (flag != BOOTM_STATE_OS_GO) @@ -436,9 +429,9 @@ static int do_bootm_integrity(int flag, int argc, char *const argv[], #endif #ifdef CONFIG_BOOTM_OPENRTOS -static int do_bootm_openrtos(int flag, int argc, char *const argv[], - struct bootm_headers *images) +static int do_bootm_openrtos(int flag, struct bootm_info *bmi) { + struct bootm_headers *images = bmi->images; void (*entry_point)(void); if (flag != BOOTM_STATE_OS_GO) @@ -462,16 +455,11 @@ static int do_bootm_openrtos(int flag, int argc, char *const argv[], #endif #ifdef CONFIG_BOOTM_OPTEE -static int do_bootm_tee(int flag, int argc, char *const argv[], - struct bootm_headers *images) +static int do_bootm_tee(int flag, struct bootm_info *bmi) { + struct bootm_headers *images = bmi->images; int ret; - /* Verify OS type */ - if (images->os.os != IH_OS_TEE) { - return 1; - }; - /* Validate OPTEE header */ ret = optee_verify_bootm_image(images->os.image_start, images->os.load, @@ -479,63 +467,36 @@ static int do_bootm_tee(int flag, int argc, char *const argv[], if (ret) return ret; - /* Locate FDT etc */ - ret = bootm_find_images(flag, argc, argv, 0, 0); - if (ret) - return ret; - /* From here we can run the regular linux boot path */ - return do_bootm_linux(flag, argc, argv, images); + return do_bootm_linux(flag, bmi); } #endif #ifdef CONFIG_BOOTM_EFI -static int do_bootm_efi(int flag, int argc, char *const argv[], - struct bootm_headers *images) +static int do_bootm_efi(int flag, struct bootm_info *bmi) { + struct bootm_headers *images = bmi->images; int ret; - efi_status_t efi_ret; void *image_buf; if (flag != BOOTM_STATE_OS_GO) return 0; - /* Locate FDT, if provided */ - ret = bootm_find_images(flag, argc, argv, 0, 0); - if (ret) - return ret; - - /* Initialize EFI drivers */ - efi_ret = efi_init_obj_list(); - if (efi_ret != EFI_SUCCESS) { - printf("## Failed to initialize UEFI sub-system: r = %lu\n", - efi_ret & ~EFI_ERROR_MASK); - return 1; - } + /* We expect to return */ + images->os.type = IH_TYPE_STANDALONE; - /* Install device tree */ - efi_ret = efi_install_fdt(images->ft_len - ? images->ft_addr : EFI_FDT_USE_INTERNAL); - if (efi_ret != EFI_SUCCESS) { - printf("## Failed to install device tree: r = %lu\n", - efi_ret & ~EFI_ERROR_MASK); - return 1; - } + image_buf = map_sysmem(images->ep, images->os.image_len); /* Run EFI image */ printf("## Transferring control to EFI (at address %08lx) ...\n", images->ep); bootstage_mark(BOOTSTAGE_ID_RUN_OS); - /* We expect to return */ - images->os.type = IH_TYPE_STANDALONE; - - image_buf = map_sysmem(images->ep, images->os.image_len); + ret = efi_binary_run(image_buf, images->os.image_len, + images->ft_len + ? images->ft_addr : EFI_FDT_USE_INTERNAL); - efi_ret = efi_run_image(image_buf, images->os.image_len); - if (efi_ret != EFI_SUCCESS) - return 1; - return 0; + return ret; } #endif @@ -589,15 +550,15 @@ __weak void board_preboot_os(void) /* please define board specific board_preboot_os() */ } -int boot_selected_os(int argc, char *const argv[], int state, - struct bootm_headers *images, boot_os_fn *boot_fn) +int boot_selected_os(int state, struct bootm_info *bmi, boot_os_fn *boot_fn) { arch_preboot_os(); board_preboot_os(); - boot_fn(state, argc, argv, images); + + boot_fn(state, bmi); /* Stand-alone may return when 'autostart' is 'no' */ - if (images->os.type == IH_TYPE_STANDALONE || + if (bmi->images->os.type == IH_TYPE_STANDALONE || IS_ENABLED(CONFIG_SANDBOX) || state == BOOTM_STATE_OS_FAKE_GO) /* We expect to return */ return 0; diff --git a/boot/bootmeth_efi.c b/boot/bootmeth_efi.c index 446cb73140e..c4eb331d69e 100644 --- a/boot/bootmeth_efi.c +++ b/boot/bootmeth_efi.c @@ -426,7 +426,6 @@ static int distro_efi_read_bootflow(struct udevice *dev, struct bootflow *bflow) static int distro_efi_boot(struct udevice *dev, struct bootflow *bflow) { ulong kernel, fdt; - char cmd[50]; int ret; kernel = env_get_hex("kernel_addr_r", 0); @@ -453,21 +452,18 @@ static int distro_efi_boot(struct udevice *dev, struct bootflow *bflow) fdt = env_get_hex("fdt_addr_r", 0); } - /* - * At some point we can add a real interface to bootefi so we can call - * this directly. For now, go through the CLI, like distro boot. - */ if (bflow->flags & BOOTFLOWF_USE_BUILTIN_FDT) { log_debug("Booting with built-in fdt\n"); - snprintf(cmd, sizeof(cmd), "bootefi %lx", kernel); + if (efi_binary_run(map_sysmem(kernel, 0), bflow->size, + EFI_FDT_USE_INTERNAL)) + return log_msg_ret("run", -EINVAL); } else { log_debug("Booting with external fdt\n"); - snprintf(cmd, sizeof(cmd), "bootefi %lx %lx", kernel, fdt); + if (efi_binary_run(map_sysmem(kernel, 0), bflow->size, + map_sysmem(fdt, 0))) + return log_msg_ret("run", -EINVAL); } - if (run_command(cmd, 0)) - return log_msg_ret("run", -EINVAL); - return 0; } diff --git a/boot/bootmeth_efi_mgr.c b/boot/bootmeth_efi_mgr.c index e6c42d41fb8..ed29d7ef021 100644 --- a/boot/bootmeth_efi_mgr.c +++ b/boot/bootmeth_efi_mgr.c @@ -16,6 +16,7 @@ #include <dm.h> #include <efi_loader.h> #include <efi_variable.h> +#include <malloc.h> /** * struct efi_mgr_priv - private info for the efi-mgr driver @@ -65,6 +66,7 @@ static int efi_mgr_read_bootflow(struct udevice *dev, struct bootflow *bflow) bootorder = efi_get_var(u"BootOrder", &efi_global_variable_guid, &size); if (bootorder) { + free(bootorder); bflow->state = BOOTFLOWST_READY; return 0; } @@ -85,7 +87,7 @@ static int efi_mgr_boot(struct udevice *dev, struct bootflow *bflow) int ret; /* Booting is handled by the 'bootefi bootmgr' command */ - ret = run_command("bootefi bootmgr", 0); + ret = efi_bootmgr_run(EFI_FDT_USE_INTERNAL); return 0; } diff --git a/boot/fdt_support.c b/boot/fdt_support.c index b15d07765fe..090d82ee80a 100644 --- a/boot/fdt_support.c +++ b/boot/fdt_support.c @@ -667,7 +667,6 @@ int fdt_record_loadable(void *blob, u32 index, const char *name, return node; } -/* Resize the fdt to its actual size + a bit of padding */ int fdt_shrink_to_minimum(void *blob, uint extrasize) { int i; diff --git a/boot/image-board.c b/boot/image-board.c index d500da1b4b9..75f6906cd56 100644 --- a/boot/image-board.c +++ b/boot/image-board.c @@ -198,22 +198,7 @@ void memmove_wd(void *to, void *from, size_t len, ulong chunksz) } } -/** - * genimg_get_kernel_addr_fit - get the real kernel address and return 2 - * FIT strings - * @img_addr: a string might contain real image address - * @fit_uname_config: double pointer to a char, will hold pointer to a - * configuration unit name - * @fit_uname_kernel: double pointer to a char, will hold pointer to a subimage - * name - * - * genimg_get_kernel_addr_fit get the real kernel start address from a string - * which is normally the first argv of bootm/bootz - * - * returns: - * kernel start address - */ -ulong genimg_get_kernel_addr_fit(char * const img_addr, +ulong genimg_get_kernel_addr_fit(const char *const img_addr, const char **fit_uname_config, const char **fit_uname_kernel) { @@ -471,49 +456,14 @@ static int select_ramdisk(struct bootm_headers *images, const char *select, u8 a return 0; } -/** - * boot_get_ramdisk - main ramdisk handling routine - * @argc: command argument count - * @argv: command argument list - * @images: pointer to the bootm images structure - * @arch: expected ramdisk architecture - * @rd_start: pointer to a ulong variable, will hold ramdisk start address - * @rd_end: pointer to a ulong variable, will hold ramdisk end - * - * boot_get_ramdisk() is responsible for finding a valid ramdisk image. - * Currently supported are the following ramdisk sources: - * - multicomponent kernel/ramdisk image, - * - commandline provided address of decicated ramdisk image. - * - * returns: - * 0, if ramdisk image was found and valid, or skiped - * rd_start and rd_end are set to ramdisk start/end addresses if - * ramdisk image is found and valid - * - * 1, if ramdisk image is found but corrupted, or invalid - * rd_start and rd_end are set to 0 if no ramdisk exists - */ -int boot_get_ramdisk(int argc, char *const argv[], struct bootm_headers *images, - u8 arch, ulong *rd_start, ulong *rd_end) +int boot_get_ramdisk(char const *select, struct bootm_headers *images, + uint arch, ulong *rd_start, ulong *rd_end) { ulong rd_data, rd_len; - const char *select = NULL; *rd_start = 0; *rd_end = 0; - if (IS_ENABLED(CONFIG_ANDROID_BOOT_IMAGE)) { - char *buf; - - /* Look for an Android boot image */ - buf = map_sysmem(images->os.start, 0); - if (buf && genimg_get_format(buf) == IMAGE_FORMAT_ANDROID) - select = (argc == 0) ? env_get("loadaddr") : argv[0]; - } - - if (argc >= 2) - select = argv[1]; - /* * Look for a '-' which indicates to ignore the * ramdisk argument @@ -666,8 +616,7 @@ int boot_get_setup(struct bootm_headers *images, u8 arch, return boot_get_setup_fit(images, arch, setup_start, setup_len); } -int boot_get_fpga(int argc, char *const argv[], struct bootm_headers *images, - u8 arch, const ulong *ld_start, ulong * const ld_len) +int boot_get_fpga(struct bootm_headers *images) { ulong tmp_img_addr, img_data, img_len; void *buf; @@ -709,7 +658,7 @@ int boot_get_fpga(int argc, char *const argv[], struct bootm_headers *images, tmp_img_addr, (const char **)&uname, &images->fit_uname_cfg, - arch, + IH_ARCH_DEFAULT, IH_TYPE_FPGA, BOOTSTAGE_ID_FPGA_INIT, FIT_LOAD_OPTIONAL_NON_ZERO, @@ -769,8 +718,7 @@ static void fit_loadable_process(u8 img_type, fit_loadable_handler->handler(img_data, img_len); } -int boot_get_loadable(int argc, char *const argv[], struct bootm_headers *images, - u8 arch, const ulong *ld_start, ulong * const ld_len) +int boot_get_loadable(struct bootm_headers *images) { /* * These variables are used to hold the current image location @@ -816,7 +764,8 @@ int boot_get_loadable(int argc, char *const argv[], struct bootm_headers *images fit_img_result = fit_image_load(images, tmp_img_addr, &uname, &images->fit_uname_cfg, - arch, IH_TYPE_LOADABLE, + IH_ARCH_DEFAULT, + IH_TYPE_LOADABLE, BOOTSTAGE_ID_FIT_LOADABLE_START, FIT_LOAD_OPTIONAL_NON_ZERO, &img_data, &img_len); @@ -959,7 +908,7 @@ int image_setup_linux(struct bootm_headers *images) } if (CONFIG_IS_ENABLED(OF_LIBFDT) && of_size) { - ret = image_setup_libfdt(images, *of_flat_tree, of_size, lmb); + ret = image_setup_libfdt(images, *of_flat_tree, lmb); if (ret) return ret; } diff --git a/boot/image-fdt.c b/boot/image-fdt.c index f10200f6474..75bdd55f326 100644 --- a/boot/image-fdt.c +++ b/boot/image-fdt.c @@ -9,6 +9,7 @@ */ #include <common.h> +#include <command.h> #include <fdt_support.h> #include <fdtdec.h> #include <env.h> @@ -24,9 +25,6 @@ #include <dm/ofnode.h> #include <tee/optee.h> -/* adding a ramdisk needs 0x44 bytes in version 2008.10 */ -#define FDT_RAMDISK_OVERHEAD 0x80 - DECLARE_GLOBAL_DATA_PTR; static void fdt_error(const char *msg) @@ -447,45 +445,16 @@ static int select_fdt(struct bootm_headers *images, const char *select, u8 arch, return 0; } -/** - * boot_get_fdt - main fdt handling routine - * @argc: command argument count - * @argv: command argument list - * @arch: architecture (IH_ARCH_...) - * @images: pointer to the bootm images structure - * @of_flat_tree: pointer to a char* variable, will hold fdt start address - * @of_size: pointer to a ulong variable, will hold fdt length - * - * boot_get_fdt() is responsible for finding a valid flat device tree image. - * Currently supported are the following ramdisk sources: - * - multicomponent kernel/ramdisk image, - * - commandline provided address of decicated ramdisk image. - * - * returns: - * 0, if fdt image was found and valid, or skipped - * of_flat_tree and of_size are set to fdt start address and length if - * fdt image is found and valid - * - * 1, if fdt image is found but corrupted - * of_flat_tree and of_size are set to 0 if no fdt exists - */ -int boot_get_fdt(int flag, int argc, char *const argv[], uint8_t arch, - struct bootm_headers *images, char **of_flat_tree, ulong *of_size) +int boot_get_fdt(void *buf, const char *select, uint arch, + struct bootm_headers *images, char **of_flat_tree, + ulong *of_size) { - ulong img_addr; - ulong fdt_addr; - char *fdt_blob = NULL; - void *buf; - const char *select = NULL; + char *fdt_blob = NULL; + ulong fdt_addr; *of_flat_tree = NULL; *of_size = 0; - img_addr = (argc == 0) ? image_load_addr : hextoul(argv[0], NULL); - buf = map_sysmem(img_addr, 0); - - if (argc > 2) - select = argv[2]; if (select || genimg_has_config(images)) { int ret; @@ -604,12 +573,26 @@ __weak int arch_fixup_fdt(void *blob) } int image_setup_libfdt(struct bootm_headers *images, void *blob, - int of_size, struct lmb *lmb) + struct lmb *lmb) { ulong *initrd_start = &images->initrd_start; ulong *initrd_end = &images->initrd_end; - int ret = -EPERM; - int fdt_ret; + int ret, fdt_ret, of_size; + + if (IS_ENABLED(CONFIG_OF_ENV_SETUP)) { + const char *fdt_fixup; + + fdt_fixup = env_get("fdt_fixup"); + if (fdt_fixup) { + set_working_fdt_addr(map_to_sysmem(blob)); + ret = run_command_list(fdt_fixup, -1, 0); + if (ret) + printf("WARNING: fdt_fixup command returned %d\n", + ret); + } + } + + ret = -EPERM; if (fdt_root(blob) < 0) { printf("ERROR: root node setup failed\n"); @@ -666,6 +649,14 @@ int image_setup_libfdt(struct bootm_headers *images, void *blob, goto err; } } + + if (fdt_initrd(blob, *initrd_start, *initrd_end)) + goto err; + + if (!ft_verify_fdt(blob)) + goto err; + + /* after here we are using a livetree */ if (!of_live_active() && CONFIG_IS_ENABLED(EVENT)) { struct event_ft_fixup fixup; @@ -683,25 +674,16 @@ int image_setup_libfdt(struct bootm_headers *images, void *blob, /* Delete the old LMB reservation */ if (lmb) - lmb_free(lmb, (phys_addr_t)(u32)(uintptr_t)blob, - (phys_size_t)fdt_totalsize(blob)); + lmb_free(lmb, map_to_sysmem(blob), fdt_totalsize(blob)); ret = fdt_shrink_to_minimum(blob, 0); if (ret < 0) goto err; of_size = ret; - if (*initrd_start && *initrd_end) { - of_size += FDT_RAMDISK_OVERHEAD; - fdt_set_totalsize(blob, of_size); - } /* Create a new LMB reservation */ if (lmb) - lmb_reserve(lmb, (ulong)blob, of_size); - - fdt_initrd(blob, *initrd_start, *initrd_end); - if (!ft_verify_fdt(blob)) - goto err; + lmb_reserve(lmb, map_to_sysmem(blob), of_size); #if defined(CONFIG_ARCH_KEYSTONE) if (IS_ENABLED(CONFIG_OF_BOARD_SETUP)) diff --git a/boot/image-fit.c b/boot/image-fit.c index 3cc556b727f..89e377563ce 100644 --- a/boot/image-fit.c +++ b/boot/image-fit.c @@ -15,6 +15,7 @@ #include <time.h> #include <linux/libfdt.h> #include <u-boot/crc.h> +#include <linux/kconfig.h> #else #include <linux/compiler.h> #include <linux/sizes.h> @@ -36,7 +37,6 @@ DECLARE_GLOBAL_DATA_PTR; #include <bootm.h> #include <image.h> #include <bootstage.h> -#include <linux/kconfig.h> #include <u-boot/crc.h> #include <u-boot/md5.h> #include <u-boot/sha1.h> diff --git a/boot/image.c b/boot/image.c index 88b67bc3a19..073931cd7a3 100644 --- a/boot/image.c +++ b/boot/image.c @@ -42,6 +42,7 @@ DECLARE_GLOBAL_DATA_PTR; #else /* USE_HOSTCC */ #include "mkimage.h" +#include <linux/kconfig.h> #include <u-boot/md5.h> #include <time.h> @@ -62,7 +63,6 @@ DECLARE_GLOBAL_DATA_PTR; #include <relocate.h> #include <linux/lzo.h> #include <linux/zstd.h> -#include <linux/kconfig.h> #include <lzma/LzmaTypes.h> #include <lzma/LzmaDec.h> #include <lzma/LzmaTools.h> @@ -415,15 +415,20 @@ void image_print_contents(const void *ptr) * @type: OS type (IH_OS_...) * @comp_type: Compression type being used (IH_COMP_...) * @is_xip: true if the load address matches the image start + * @load: Load address for printing */ -static void print_decomp_msg(int comp_type, int type, bool is_xip) +static void print_decomp_msg(int comp_type, int type, bool is_xip, + ulong load) { const char *name = genimg_get_type_name(type); + /* Shows "Loading Kernel Image" for example */ if (comp_type == IH_COMP_NONE) - printf(" %s %s\n", is_xip ? "XIP" : "Loading", name); + printf(" %s %s", is_xip ? "XIP" : "Loading", name); else - printf(" Uncompressing %s\n", name); + printf(" Uncompressing %s", name); + + printf(" to %lx\n", load); } int image_decomp_type(const unsigned char *buf, ulong len) @@ -448,7 +453,7 @@ int image_decomp(int comp, ulong load, ulong image_start, int type, int ret = -ENOSYS; *load_end = load; - print_decomp_msg(comp, type, load == image_start); + print_decomp_msg(comp, type, load == image_start, load); /* * Load the image to the right place, decompressing if needed. After diff --git a/boot/prog_boot.c b/boot/prog_boot.c new file mode 100644 index 00000000000..045554b93db --- /dev/null +++ b/boot/prog_boot.c @@ -0,0 +1,51 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright 2021 Google LLC + * Written by Simon Glass <[email protected]> + */ + +#define LOG_CATEGORY UCLASS_BOOTSTD + +#include <bootflow.h> +#include <bootstd.h> +#include <command.h> +#include <dm.h> + +/* + * show_bootmeths() - List available bootmeths + * + * We could refactor this to use do_bootmeth_list() if more detail (or ordering) + * are needed + */ +static void show_bootmeths(void) +{ + struct udevice *dev; + struct uclass *uc; + + printf("Bootmeths: "); + uclass_id_foreach_dev(UCLASS_BOOTMETH, dev, uc) + printf(" %s", dev->name); + printf("\n"); +} + +int bootstd_prog_boot(void) +{ + struct bootflow_iter iter; + struct bootflow bflow; + int ret, flags, i; + + printf("Programmatic boot starting\n"); + show_bootmeths(); + flags = BOOTFLOWIF_HUNT | BOOTFLOWIF_SHOW | BOOTFLOWIF_SKIP_GLOBAL; + + bootstd_clear_glob(); + for (i = 0, ret = bootflow_scan_first(NULL, NULL, &iter, flags, &bflow); + i < 1000 && ret != -ENODEV; + i++, ret = bootflow_scan_next(&iter, &bflow)) { + if (!bflow.err) + bootflow_run_boot(&iter, &bflow); + bootflow_free(&bflow); + } + + return -EFAULT; +} diff --git a/boot/pxe_utils.c b/boot/pxe_utils.c index a92bb896c63..83bc1677856 100644 --- a/boot/pxe_utils.c +++ b/boot/pxe_utils.c @@ -700,6 +700,11 @@ static int label_boot(struct pxe_context *ctx, struct pxe_label *label) label->name); goto cleanup; } + + if (label->fdtdir) { + printf("Skipping fdtdir %s for failure retrieving dts\n", + label->fdtdir); + } } if (label->kaslrseed) |
