diff options
Diffstat (limited to 'boot')
-rw-r--r-- | boot/Kconfig | 41 | ||||
-rw-r--r-- | boot/Makefile | 4 | ||||
-rw-r--r-- | boot/android_ab.c | 97 | ||||
-rw-r--r-- | boot/bootdev-uclass.c | 50 | ||||
-rw-r--r-- | boot/bootflow.c | 9 | ||||
-rw-r--r-- | boot/bootflow_menu.c | 1 | ||||
-rw-r--r-- | boot/bootm.c | 189 | ||||
-rw-r--r-- | boot/bootm_os.c | 110 | ||||
-rw-r--r-- | boot/bootmeth_cros.c | 6 | ||||
-rw-r--r-- | boot/bootmeth_efi.c | 92 | ||||
-rw-r--r-- | boot/bootmeth_efi_mgr.c | 6 | ||||
-rw-r--r-- | boot/bootmeth_extlinux.c | 2 | ||||
-rw-r--r-- | boot/bootmeth_pxe.c | 2 | ||||
-rw-r--r-- | boot/fdt_support.c | 1 | ||||
-rw-r--r-- | boot/image-board.c | 2 | ||||
-rw-r--r-- | boot/image-fdt.c | 49 | ||||
-rw-r--r-- | boot/image-fit.c | 2 | ||||
-rw-r--r-- | boot/image-sig.c | 8 | ||||
-rw-r--r-- | boot/image.c | 15 | ||||
-rw-r--r-- | boot/pxe_utils.c | 34 |
20 files changed, 422 insertions, 298 deletions
diff --git a/boot/Kconfig b/boot/Kconfig index d83047acbd0..777e408e243 100644 --- a/boot/Kconfig +++ b/boot/Kconfig @@ -408,6 +408,7 @@ config VPL_BOOTSTD config BOOTSTD_FULL bool "Enhanced features for standard boot" default y if SANDBOX + imply BOOTSTD_DEFAULTS help This enables various useful features for standard boot, which are not essential for operation: @@ -505,7 +506,7 @@ config BOOTMETH_EXTLINUX_PXE config BOOTMETH_EFILOADER bool "Bootdev support for EFI boot" - depends on CMD_BOOTEFI + depends on EFI_BINARY_EXEC default y help Enables support for EFI boot using bootdevs. This makes the @@ -524,6 +525,16 @@ config BOOTMETH_EFILOADER This provides a way to try out standard boot on an existing boot flow. +config BOOTMETH_EFI_BOOTMGR + bool "Bootdev support for EFI boot manager" + depends on EFI_BOOTMGR + select BOOTMETH_GLOBAL + default y + help + Enable booting via the UEFI boot manager. Based on the EFI variables + the EFI binary to be launched is determined. To set the EFI variables + use the eficonfig command. + config BOOTMETH_VBE bool "Bootdev support for Verified Boot for Embedded" depends on FIT @@ -540,7 +551,7 @@ config BOOTMETH_DISTRO 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 CMD_BOOTEFI # E.g. Ubuntu uses this + select BOOTMETH_EFILOADER if EFI_BINARY_EXEC # E.g. Ubuntu uses this config SPL_BOOTMETH_VBE bool "Bootdev support for Verified Boot for Embedded (SPL)" @@ -756,6 +767,21 @@ config TIMESTAMP loaded that does not, the message 'Wrong FIT format: no timestamp' is shown. +config BUTTON_CMD + bool "Support for running a command if a button is held during boot" + depends on CMDLINE + depends on BUTTON + help + For many embedded devices it's useful to enter a special flashing mode + such as fastboot mode when a button is held during boot. This option + allows arbitrary commands to be assigned to specific buttons. These will + be run after "preboot" if the button is held. Configuration is done via + the environment variables "button_cmd_N_name" and "button_cmd_N" where n is + the button number (starting from 0). e.g: + + "button_cmd_0_name=vol_down" + "button_cmd_0=fastboot usb 0" + config LEGACY_IMAGE_FORMAT bool "Enable support for the legacy image format" default y if !FIT_SIGNATURE && !TI_SECURE_DEVICE @@ -1575,6 +1601,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 @@ -1739,7 +1774,7 @@ menu "Configuration editor" config CEDIT bool "Configuration editor" - depends on BOOTSTD + depends on EXPO help Provides a way to deal with board configuration and present it to the user for adjustment. diff --git a/boot/Makefile b/boot/Makefile index a4ea2f9e062..bf767fd5356 100644 --- a/boot/Makefile +++ b/boot/Makefile @@ -33,11 +33,11 @@ obj-$(CONFIG_$(SPL_TPL_)BOOTMETH_EFILOADER) += bootmeth_efi.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 +obj-$(CONFIG_$(SPL_TPL_)CEDIT) += cedit.o +obj-$(CONFIG_$(SPL_TPL_)BOOTMETH_EFI_BOOTMGR) += bootmeth_efi_mgr.o ifdef CONFIG_$(SPL_TPL_)BOOTSTD_FULL -obj-$(CONFIG_CMD_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 endif obj-$(CONFIG_$(SPL_TPL_)OF_LIBFDT) += fdt_support.o diff --git a/boot/android_ab.c b/boot/android_ab.c index 0f20a34e511..1e5aa81b750 100644 --- a/boot/android_ab.c +++ b/boot/android_ab.c @@ -187,13 +187,12 @@ int ab_select_slot(struct blk_desc *dev_desc, struct disk_partition *part_info, bool dec_tries) { struct bootloader_control *abc = NULL; + struct bootloader_control *backup_abc = NULL; u32 crc32_le; int slot, i, ret; bool store_needed = false; + bool valid_backup = false; char slot_suffix[4]; -#if ANDROID_AB_BACKUP_OFFSET - struct bootloader_control *backup_abc = NULL; -#endif ret = ab_control_create_from_disk(dev_desc, part_info, &abc, 0); if (ret < 0) { @@ -205,53 +204,49 @@ int ab_select_slot(struct blk_desc *dev_desc, struct disk_partition *part_info, return ret; } -#if ANDROID_AB_BACKUP_OFFSET - ret = ab_control_create_from_disk(dev_desc, part_info, &backup_abc, - ANDROID_AB_BACKUP_OFFSET); - if (ret < 0) { - free(abc); - return ret; + if (CONFIG_ANDROID_AB_BACKUP_OFFSET) { + ret = ab_control_create_from_disk(dev_desc, part_info, &backup_abc, + CONFIG_ANDROID_AB_BACKUP_OFFSET); + if (ret < 0) { + free(abc); + return ret; + } } -#endif crc32_le = ab_control_compute_crc(abc); if (abc->crc32_le != crc32_le) { log_err("ANDROID: Invalid CRC-32 (expected %.8x, found %.8x),", crc32_le, abc->crc32_le); -#if ANDROID_AB_BACKUP_OFFSET - crc32_le = ab_control_compute_crc(backup_abc); - if (backup_abc->crc32_le != crc32_le) { - log_err("ANDROID: Invalid backup CRC-32 ") - log_err("expected %.8x, found %.8x),", - crc32_le, backup_abc->crc32_le); -#endif - - log_err("re-initializing A/B metadata.\n"); + if (CONFIG_ANDROID_AB_BACKUP_OFFSET) { + crc32_le = ab_control_compute_crc(backup_abc); + if (backup_abc->crc32_le != crc32_le) { + log_err(" ANDROID: Invalid backup CRC-32 "); + log_err("(expected %.8x, found %.8x),", + crc32_le, backup_abc->crc32_le); + } else { + valid_backup = true; + log_info(" copying A/B metadata from backup.\n"); + memcpy(abc, backup_abc, sizeof(*abc)); + } + } + if (!valid_backup) { + log_err(" re-initializing A/B metadata.\n"); ret = ab_control_default(abc); if (ret < 0) { -#if ANDROID_AB_BACKUP_OFFSET - free(backup_abc); -#endif + if (CONFIG_ANDROID_AB_BACKUP_OFFSET) + free(backup_abc); free(abc); return -ENODATA; } -#if ANDROID_AB_BACKUP_OFFSET - } else { - /* - * Backup is valid. Copy it to the primary - */ - memcpy(abc, backup_abc, sizeof(*abc)); } -#endif store_needed = true; } if (abc->magic != BOOT_CTRL_MAGIC) { log_err("ANDROID: Unknown A/B metadata: %.8x\n", abc->magic); -#if ANDROID_AB_BACKUP_OFFSET - free(backup_abc); -#endif + if (CONFIG_ANDROID_AB_BACKUP_OFFSET) + free(backup_abc); free(abc); return -ENODATA; } @@ -259,9 +254,8 @@ int ab_select_slot(struct blk_desc *dev_desc, struct disk_partition *part_info, if (abc->version > BOOT_CTRL_VERSION) { log_err("ANDROID: Unsupported A/B metadata version: %.8x\n", abc->version); -#if ANDROID_AB_BACKUP_OFFSET - free(backup_abc); -#endif + if (CONFIG_ANDROID_AB_BACKUP_OFFSET) + free(backup_abc); free(abc); return -ENODATA; } @@ -336,20 +330,31 @@ int ab_select_slot(struct blk_desc *dev_desc, struct disk_partition *part_info, if (store_needed) { abc->crc32_le = ab_control_compute_crc(abc); - ab_control_store(dev_desc, part_info, abc, 0); + ret = ab_control_store(dev_desc, part_info, abc, 0); + if (ret < 0) { + if (CONFIG_ANDROID_AB_BACKUP_OFFSET) + free(backup_abc); + free(abc); + return ret; + } } -#if ANDROID_AB_BACKUP_OFFSET - /* - * If the backup doesn't match the primary, write the primary - * to the backup offset - */ - if (memcmp(backup_abc, abc, sizeof(*abc)) != 0) { - ab_control_store(dev_desc, part_info, abc, - ANDROID_AB_BACKUP_OFFSET); + if (CONFIG_ANDROID_AB_BACKUP_OFFSET) { + /* + * If the backup doesn't match the primary, write the primary + * to the backup offset + */ + if (memcmp(backup_abc, abc, sizeof(*abc)) != 0) { + ret = ab_control_store(dev_desc, part_info, abc, + CONFIG_ANDROID_AB_BACKUP_OFFSET); + if (ret < 0) { + free(backup_abc); + free(abc); + return ret; + } + } + free(backup_abc); } - free(backup_abc); -#endif free(abc); diff --git a/boot/bootdev-uclass.c b/boot/bootdev-uclass.c index 4926a50da85..46815ea2fdb 100644 --- a/boot/bootdev-uclass.c +++ b/boot/bootdev-uclass.c @@ -39,7 +39,6 @@ int bootdev_add_bootflow(struct bootflow *bflow) struct bootflow *new; int ret; - assert(bflow->dev); ret = bootstd_get_priv(&std); if (ret) return ret; @@ -173,8 +172,10 @@ int bootdev_find_in_blk(struct udevice *dev, struct udevice *blk, */ iter->max_part = MAX_PART_PER_BOOTDEV; - /* If this is the whole disk, check if we have bootable partitions */ - if (!iter->part) { + if (iter->flags & BOOTFLOWIF_SINGLE_PARTITION) { + /* a particular partition was specified, scan it without checking */ + } else if (!iter->part) { + /* This is the whole disk, check if we have bootable partitions */ iter->first_bootable = part_get_bootable(desc); log_debug("checking bootable=%d\n", iter->first_bootable); } else if (allow_any_part) { @@ -632,7 +633,7 @@ int bootdev_next_label(struct bootflow_iter *iter, struct udevice **devp, int bootdev_next_prio(struct bootflow_iter *iter, struct udevice **devp) { - struct udevice *dev = *devp; + struct udevice *dev = *devp, *last_dev = NULL; bool found; int ret; @@ -682,9 +683,19 @@ int bootdev_next_prio(struct bootflow_iter *iter, struct udevice **devp) } } else { ret = device_probe(dev); + if (!ret) + last_dev = dev; if (ret) { - log_debug("Device '%s' failed to probe\n", + log_warning("Device '%s' failed to probe\n", dev->name); + if (last_dev == dev) { + /* + * We have already tried this device + * and it failed to probe. Give up. + */ + return log_msg_ret("probe", ret); + } + last_dev = dev; dev = NULL; } } @@ -701,8 +712,37 @@ int bootdev_setup_iter(struct bootflow_iter *iter, const char *label, struct udevice *bootstd, *dev = NULL; bool show = iter->flags & BOOTFLOWIF_SHOW; int method_flags; + char buf[32]; int ret; + if (label) { + const char *end = strchr(label, ':'); + + if (end) { + size_t len = (size_t)(end - label); + const char *part = end + 1; + + if (len + 1 > sizeof(buf)) { + log_err("label \"%s\" is way too long\n", label); + return -EINVAL; + } + + memcpy(buf, label, len); + buf[len] = '\0'; + label = buf; + + unsigned long tmp; + + if (strict_strtoul(part, 0, &tmp)) { + log_err("Invalid partition number: %s\n", part); + return -EINVAL; + } + + iter->flags |= BOOTFLOWIF_SINGLE_PARTITION; + iter->part = tmp; + } + } + ret = uclass_first_device_err(UCLASS_BOOTSTD, &bootstd); if (ret) { log_err("Missing bootstd device\n"); diff --git a/boot/bootflow.c b/boot/bootflow.c index 1ea2966ae9a..68bf99329ab 100644 --- a/boot/bootflow.c +++ b/boot/bootflow.c @@ -217,6 +217,9 @@ static int iter_incr(struct bootflow_iter *iter) } } + if (iter->flags & BOOTFLOWIF_SINGLE_PARTITION) + return BF_NO_MORE_DEVICES; + /* No more bootmeths; start at the first one, and... */ iter->cur_method = 0; iter->method = iter->method_order[iter->cur_method]; @@ -361,7 +364,7 @@ static int bootflow_check(struct bootflow_iter *iter, struct bootflow *bflow) } /* Unless there is nothing more to try, move to the next device */ - else if (ret != BF_NO_MORE_PARTS && ret != -ENOSYS) { + if (ret != BF_NO_MORE_PARTS && ret != -ENOSYS) { log_debug("Bootdev '%s' part %d method '%s': Error %d\n", dev->name, iter->part, iter->method->name, ret); /* @@ -371,10 +374,8 @@ static int bootflow_check(struct bootflow_iter *iter, struct bootflow *bflow) if (iter->flags & BOOTFLOWIF_ALL) return log_msg_ret("all", ret); } - if (ret) - return log_msg_ret("check", ret); - return 0; + return log_msg_ret("check", ret); } int bootflow_scan_first(struct udevice *dev, const char *label, diff --git a/boot/bootflow_menu.c b/boot/bootflow_menu.c index 7c1abe5772c..16f9cd8f8ca 100644 --- a/boot/bootflow_menu.c +++ b/boot/bootflow_menu.c @@ -120,7 +120,6 @@ int bootflow_menu_new(struct expo **expp) if (ret < 0) return log_msg_ret("itm", -EINVAL); - ret = 0; priv->num_bootflows++; } diff --git a/boot/bootm.c b/boot/bootm.c index a0d17be7742..d071537d692 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> @@ -443,24 +444,8 @@ static int bootm_find_os(const char *cmd_name, const char *addr_fit) } 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); @@ -645,6 +630,25 @@ 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; + images->ep = 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, @@ -685,6 +689,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; @@ -962,35 +991,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; @@ -1005,17 +1008,18 @@ int do_bootm_states(struct cmd_tbl *cmdtp, int flag, int argc, ret = bootm_start(); if (!ret && (states & BOOTM_STATE_PRE_LOAD)) - ret = bootm_pre_load(argv[0]); + ret = bootm_pre_load(bmi->addr_img); if (!ret && (states & BOOTM_STATE_FINDOS)) - ret = bootm_find_os(cmdtp->name, argv[0]); + ret = bootm_find_os(bmi->cmd_name, bmi->addr_img); if (!ret && (states & BOOTM_STATE_FINDOTHER)) { ulong img_addr; - img_addr = argc ? hextoul(argv[0], NULL) : image_load_addr; - ret = bootm_find_other(img_addr, cmd_arg1(argc, argv), - cmd_arg2(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 && @@ -1069,20 +1073,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 @@ -1090,10 +1097,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 @@ -1105,37 +1111,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(sjg@chromium.org): 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 | @@ -1153,11 +1183,22 @@ 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; } +void bootm_init(struct bootm_info *bmi) +{ + memset(bmi, '\0', sizeof(struct bootm_info)); + bmi->boot_progress = true; + if (IS_ENABLED(CONFIG_CMD_BOOTM)) + bmi->images = &images; +} + /** * switch_to_non_secure_mode() - switch to non-secure mode * diff --git a/boot/bootm_os.c b/boot/bootm_os.c index b92422171a8..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,9 +311,10 @@ 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; @@ -322,8 +323,7 @@ static int do_bootm_vxworks_legacy(int flag, int argc, char *const argv[], 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; @@ -348,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; @@ -376,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 */ /* @@ -396,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) @@ -429,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) @@ -455,9 +455,9 @@ 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; /* Validate OPTEE header */ @@ -468,51 +468,35 @@ static int do_bootm_tee(int flag, int argc, char *const argv[], 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) { - efi_status_t efi_ret; + struct bootm_headers *images = bmi->images; + int ret; void *image_buf; if (flag != BOOTM_STATE_OS_GO) return 0; - /* 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 @@ -566,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_cros.c b/boot/bootmeth_cros.c index cd72db8250c..f015f2e1c75 100644 --- a/boot/bootmeth_cros.c +++ b/boot/bootmeth_cros.c @@ -432,9 +432,9 @@ static int cros_boot(struct udevice *dev, struct bootflow *bflow) } if (IS_ENABLED(CONFIG_X86)) { - ret = zboot_start(map_to_sysmem(bflow->buf), bflow->size, 0, 0, - map_to_sysmem(bflow->x86_setup), - bflow->cmdline); + ret = zboot_run(map_to_sysmem(bflow->buf), bflow->size, 0, 0, + map_to_sysmem(bflow->x86_setup), + bflow->cmdline); } else { ret = bootm_boot_start(map_to_sysmem(bflow->buf), bflow->cmdline); diff --git a/boot/bootmeth_efi.c b/boot/bootmeth_efi.c index 9ba7734911e..aebc5207fc0 100644 --- a/boot/bootmeth_efi.c +++ b/boot/bootmeth_efi.c @@ -14,6 +14,7 @@ #include <bootmeth.h> #include <command.h> #include <dm.h> +#include <efi_default_filename.h> #include <efi_loader.h> #include <fs.h> #include <malloc.h> @@ -23,43 +24,7 @@ #include <pxe_utils.h> #include <linux/sizes.h> -#define EFI_DIRNAME "efi/boot/" - -/** - * get_efi_leafname() - Get the leaf name for the EFI file we expect - * - * @str: Place to put leaf name for this architecture, e.g. "bootaa64.efi". - * Must have at least 16 bytes of space - * @max_len: Length of @str, must be >=16 - */ -static int get_efi_leafname(char *str, int max_len) -{ - const char *base; - - if (max_len < 16) - return log_msg_ret("spc", -ENOSPC); - if (IS_ENABLED(CONFIG_ARM64)) - base = "bootaa64"; - else if (IS_ENABLED(CONFIG_ARM)) - base = "bootarm"; - else if (IS_ENABLED(CONFIG_X86_RUN_32BIT)) - base = "bootia32"; - else if (IS_ENABLED(CONFIG_X86_RUN_64BIT)) - base = "bootx64"; - else if (IS_ENABLED(CONFIG_ARCH_RV32I)) - base = "bootriscv32"; - else if (IS_ENABLED(CONFIG_ARCH_RV64I)) - base = "bootriscv64"; - else if (IS_ENABLED(CONFIG_SANDBOX)) - base = "bootsbox"; - else - return -EINVAL; - - strcpy(str, base); - strcat(str, ".efi"); - - return 0; -} +#define EFI_DIRNAME "/EFI/BOOT/" static int get_efi_pxe_arch(void) { @@ -160,7 +125,6 @@ static int efiload_read_file(struct bootflow *bflow, ulong addr) if (ret) return log_msg_ret("read", ret); bflow->buf = map_sysmem(addr, bflow->size); - bflow->flags |= BOOTFLOWF_STATIC_BUF; set_efi_bootdev(desc, bflow); @@ -260,10 +224,7 @@ static int distro_efi_try_bootflow_files(struct udevice *dev, return -ENOENT; strcpy(fname, EFI_DIRNAME); - ret = get_efi_leafname(fname + strlen(fname), - sizeof(fname) - strlen(fname)); - if (ret) - return log_msg_ret("leaf", ret); + strcat(fname, BOOTEFI_NAME); if (bflow->blk) desc = dev_get_uclass_plat(bflow->blk); @@ -313,6 +274,7 @@ static int distro_efi_try_bootflow_files(struct udevice *dev, */ } else { log_debug("No device tree available\n"); + bflow->flags |= BOOTFLOWF_USE_BUILTIN_FDT; } return 0; @@ -323,7 +285,7 @@ static int distro_efi_read_bootflow_net(struct bootflow *bflow) char file_addr[17], fname[256]; char *tftp_argv[] = {"tftp", file_addr, fname, NULL}; struct cmd_tbl cmdtp = {}; /* dummy */ - const char *addr_str, *fdt_addr_str; + const char *addr_str, *fdt_addr_str, *bootfile_name; int ret, arch, size; ulong addr, fdt_addr; char str[36]; @@ -339,7 +301,7 @@ static int distro_efi_read_bootflow_net(struct bootflow *bflow) ret = env_set("bootp_vci", str); if (ret) return log_msg_ret("vcs", ret); - ret = env_set_ulong("bootp_arch", arch); + ret = env_set_hex("bootp_arch", arch); if (ret) return log_msg_ret("ars", ret); @@ -360,6 +322,12 @@ static int distro_efi_read_bootflow_net(struct bootflow *bflow) return log_msg_ret("sz", -EINVAL); bflow->size = size; + /* bootfile should be setup by dhcp*/ + bootfile_name = env_get("bootfile"); + if (!bootfile_name) + return log_msg_ret("bootfile_name", ret); + bflow->fname = strdup(bootfile_name); + /* do the hideous EFI hack */ efi_set_bootdev("Net", "", bflow->fname, map_sysmem(addr, 0), bflow->size); @@ -385,6 +353,7 @@ static int distro_efi_read_bootflow_net(struct bootflow *bflow) bflow->fdt_addr = fdt_addr; } else { log_debug("No device tree available\n"); + bflow->flags |= BOOTFLOWF_USE_BUILTIN_FDT; } bflow->state = BOOTFLOWST_READY; @@ -396,6 +365,12 @@ static int distro_efi_read_bootflow(struct udevice *dev, struct bootflow *bflow) { int ret; + /* + * bootmeth_efi doesn't allocate any buffer neither for blk nor net device + * set flag to avoid freeing static buffer. + */ + bflow->flags |= BOOTFLOWF_STATIC_BUF; + if (bootmeth_uses_network(bflow)) { /* we only support reading from one device, so ignore 'dev' */ ret = distro_efi_read_bootflow_net(bflow); @@ -413,7 +388,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); @@ -423,13 +397,11 @@ static int distro_efi_boot(struct udevice *dev, struct bootflow *bflow) return log_msg_ret("read", ret); /* - * use the provided device tree if available, else fall back to - * the control FDT + * use the provided device tree if not using the built-in fdt */ - if (bflow->fdt_fname) + if (bflow->flags & ~BOOTFLOWF_USE_BUILTIN_FDT) fdt = bflow->fdt_addr; - else - fdt = (ulong)map_to_sysmem(gd->fdt_blob); + } else { /* * This doesn't actually work for network devices: @@ -442,13 +414,17 @@ 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. - */ - snprintf(cmd, sizeof(cmd), "bootefi %lx %lx", kernel, fdt); - if (run_command(cmd, 0)) - return log_msg_ret("run", -EINVAL); + if (bflow->flags & BOOTFLOWF_USE_BUILTIN_FDT) { + log_debug("Booting with built-in fdt\n"); + 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"); + if (efi_binary_run(map_sysmem(kernel, 0), bflow->size, + map_sysmem(fdt, 0))) + return log_msg_ret("run", -EINVAL); + } return 0; } @@ -475,7 +451,7 @@ static const struct udevice_id distro_efi_bootmeth_ids[] = { { } }; -U_BOOT_DRIVER(bootmeth_efi) = { +U_BOOT_DRIVER(bootmeth_4efi) = { .name = "bootmeth_efi", .id = UCLASS_BOOTMETH, .of_match = distro_efi_bootmeth_ids, diff --git a/boot/bootmeth_efi_mgr.c b/boot/bootmeth_efi_mgr.c index e6c42d41fb8..b7d429f2c3d 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; } @@ -112,7 +114,7 @@ static const struct udevice_id efi_mgr_bootmeth_ids[] = { { } }; -U_BOOT_DRIVER(bootmeth_efi_mgr) = { +U_BOOT_DRIVER(bootmeth_3efi_mgr) = { .name = "bootmeth_efi_mgr", .id = UCLASS_BOOTMETH, .of_match = efi_mgr_bootmeth_ids, diff --git a/boot/bootmeth_extlinux.c b/boot/bootmeth_extlinux.c index aa2a4591ebd..ae0ad1d53e3 100644 --- a/boot/bootmeth_extlinux.c +++ b/boot/bootmeth_extlinux.c @@ -82,7 +82,7 @@ static int extlinux_fill_info(struct bootflow *bflow) log_debug("parsing bflow file size %x\n", bflow->size); membuff_init(&mb, bflow->buf, bflow->size); membuff_putraw(&mb, bflow->size, true, &data); - while (len = membuff_readline(&mb, line, sizeof(line) - 1, ' '), len) { + while (len = membuff_readline(&mb, line, sizeof(line) - 1, ' ', true), len) { char *tok, *p = line; tok = strsep(&p, " "); diff --git a/boot/bootmeth_pxe.c b/boot/bootmeth_pxe.c index 8d489a11aa4..70f693aa239 100644 --- a/boot/bootmeth_pxe.c +++ b/boot/bootmeth_pxe.c @@ -184,7 +184,7 @@ static const struct udevice_id extlinux_bootmeth_pxe_ids[] = { { } }; -U_BOOT_DRIVER(bootmeth_pxe) = { +U_BOOT_DRIVER(bootmeth_zpxe) = { .name = "bootmeth_pxe", .id = UCLASS_BOOTMETH, .of_match = extlinux_bootmeth_pxe_ids, 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 bb0ca9d7f22..75f6906cd56 100644 --- a/boot/image-board.c +++ b/boot/image-board.c @@ -908,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 08fca08b710..5e4aa9de0d2 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) @@ -219,14 +217,14 @@ int boot_relocate_fdt(struct lmb *lmb, char **of_flat_tree, ulong *of_size) if (start + size < low) continue; - usable = min(size, (u64)mapsize); + usable = min(start + size, (u64)(low + mapsize)); /* * At least part of this DRAM bank is usable, try * using it for LMB allocation. */ of_start = map_sysmem((ulong)lmb_alloc_base(lmb, - of_len, 0x1000, start + usable), of_len); + of_len, 0x1000, usable), of_len); /* Allocation succeeded, use this block. */ if (of_start != NULL) break; @@ -575,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"); @@ -637,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; @@ -654,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-sig.c b/boot/image-sig.c index b5692d58b24..0421a61b040 100644 --- a/boot/image-sig.c +++ b/boot/image-sig.c @@ -17,6 +17,7 @@ DECLARE_GLOBAL_DATA_PTR; #define IMAGE_MAX_HASHED_NODES 100 struct checksum_algo checksum_algos[] = { +#if CONFIG_IS_ENABLED(SHA1) { .name = "sha1", .checksum_len = SHA1_SUM_LEN, @@ -24,6 +25,8 @@ struct checksum_algo checksum_algos[] = { .der_prefix = sha1_der_prefix, .calculate = hash_calculate, }, +#endif +#if CONFIG_IS_ENABLED(SHA256) { .name = "sha256", .checksum_len = SHA256_SUM_LEN, @@ -31,7 +34,8 @@ struct checksum_algo checksum_algos[] = { .der_prefix = sha256_der_prefix, .calculate = hash_calculate, }, -#ifdef CONFIG_SHA384 +#endif +#if CONFIG_IS_ENABLED(SHA384) { .name = "sha384", .checksum_len = SHA384_SUM_LEN, @@ -40,7 +44,7 @@ struct checksum_algo checksum_algos[] = { .calculate = hash_calculate, }, #endif -#ifdef CONFIG_SHA512 +#if CONFIG_IS_ENABLED(SHA512) { .name = "sha512", .checksum_len = SHA512_SUM_LEN, 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/pxe_utils.c b/boot/pxe_utils.c index 5ceabfd04ee..d5e1bead125 100644 --- a/boot/pxe_utils.c +++ b/boot/pxe_utils.c @@ -587,7 +587,12 @@ static int label_run_boot(struct pxe_context *ctx, struct pxe_label *label, char *fdtfilefree = NULL; if (label->fdt) { - fdtfile = label->fdt; + if (IS_ENABLED(CONFIG_SUPPORT_PASSING_ATAGS)) { + if (strcmp("-", label->fdt)) + fdtfile = label->fdt; + } else { + fdtfile = label->fdt; + } } else if (label->fdtdir) { fdtfilefree = calc_fdt_fname(label->fdtdir); if (!fdtfilefree) @@ -608,6 +613,11 @@ static int label_run_boot(struct pxe_context *ctx, struct pxe_label *label, label->name); return -ENOENT; } + + if (label->fdtdir) { + printf("Skipping fdtdir %s for failure retrieving dts\n", + label->fdtdir); + } } if (label->kaslrseed) @@ -622,19 +632,31 @@ static int label_run_boot(struct pxe_context *ctx, struct pxe_label *label, } } - bmi.addr_fit = kernel_addr; + bmi.addr_img = kernel_addr; if (initrd_addr_str) bmi.conf_ramdisk = initrd_str; - if (!fdt_addr) - fdt_addr = env_get("fdt_addr"); + if (!fdt_addr) { + if (IS_ENABLED(CONFIG_SUPPORT_PASSING_ATAGS)) { + if (strcmp("-", label->fdt)) + fdt_addr = env_get("fdt_addr"); + } else { + fdt_addr = env_get("fdt_addr"); + } + } kernel_addr_r = genimg_get_kernel_addr(kernel_addr); buf = map_sysmem(kernel_addr_r, 0); - if (!fdt_addr && genimg_get_format(buf) != IMAGE_FORMAT_FIT) - fdt_addr = env_get("fdtcontroladdr"); + if (!fdt_addr && genimg_get_format(buf) != IMAGE_FORMAT_FIT) { + if (IS_ENABLED(CONFIG_SUPPORT_PASSING_ATAGS)) { + if (strcmp("-", label->fdt)) + fdt_addr = env_get("fdtcontroladdr"); + } else { + fdt_addr = env_get("fdtcontroladdr"); + } + } bmi.conf_fdt = fdt_addr; |