summaryrefslogtreecommitdiff
path: root/boot
diff options
context:
space:
mode:
Diffstat (limited to 'boot')
-rw-r--r--boot/Kconfig28
-rw-r--r--boot/Makefile6
-rw-r--r--boot/android_ab.c18
-rw-r--r--boot/bootdev-uclass.c14
-rw-r--r--boot/bootflow.c6
-rw-r--r--boot/bootflow_menu.c1
-rw-r--r--boot/bootm.c750
-rw-r--r--boot/bootm_os.c124
-rw-r--r--boot/bootmeth_efi.c46
-rw-r--r--boot/bootmeth_efi_mgr.c4
-rw-r--r--boot/bootmeth_extlinux.c2
-rw-r--r--boot/fdt_support.c1
-rw-r--r--boot/image-board.c69
-rw-r--r--boot/image-fdt.c84
-rw-r--r--boot/image-fit.c2
-rw-r--r--boot/image.c15
-rw-r--r--boot/prog_boot.c51
-rw-r--r--boot/pxe_utils.c5
18 files changed, 661 insertions, 565 deletions
diff --git a/boot/Kconfig b/boot/Kconfig
index ef71883a502..71ee41645f3 100644
--- a/boot/Kconfig
+++ b/boot/Kconfig
@@ -426,6 +426,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:
@@ -459,6 +460,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
@@ -511,7 +524,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
@@ -546,7 +559,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)"
@@ -1502,6 +1515,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
@@ -1666,7 +1688,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 3fd048bb41a..f0a279cde16 100644
--- a/boot/Makefile
+++ b/boot/Makefile
@@ -25,17 +25,19 @@ 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) += 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
ifdef CONFIG_$(SPL_TPL_)BOOTSTD_FULL
-obj-$(CONFIG_CMD_BOOTEFI_BOOTMGR) += bootmeth_efi_mgr.o
+obj-$(CONFIG_EFI_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..c9df6d2b4b1 100644
--- a/boot/android_ab.c
+++ b/boot/android_ab.c
@@ -336,7 +336,14 @@ 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 ANDROID_AB_BACKUP_OFFSET
+ free(backup_abc);
+#endif
+ free(abc);
+ return ret;
+ }
}
#if ANDROID_AB_BACKUP_OFFSET
@@ -345,8 +352,13 @@ int ab_select_slot(struct blk_desc *dev_desc, struct disk_partition *part_info,
* to the backup offset
*/
if (memcmp(backup_abc, abc, sizeof(*abc)) != 0) {
- ab_control_store(dev_desc, part_info, abc,
- ANDROID_AB_BACKUP_OFFSET);
+ ret = ab_control_store(dev_desc, part_info, abc,
+ ANDROID_AB_BACKUP_OFFSET);
+ if (ret < 0) {
+ free(backup_abc);
+ free(abc);
+ return ret;
+ }
}
free(backup_abc);
#endif
diff --git a/boot/bootdev-uclass.c b/boot/bootdev-uclass.c
index 4926a50da85..35afb93c0e7 100644
--- a/boot/bootdev-uclass.c
+++ b/boot/bootdev-uclass.c
@@ -632,7 +632,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 +682,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;
}
}
diff --git a/boot/bootflow.c b/boot/bootflow.c
index 1ea2966ae9a..05484fd5b1b 100644
--- a/boot/bootflow.c
+++ b/boot/bootflow.c
@@ -361,7 +361,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 +371,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 cb61485c226..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>
@@ -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)
+ * check_overlap() - Check if an image overlaps the OS
*
- * Note: bootm_find_images will skip an image if it is not found
- *
- * @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,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,
@@ -466,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;
@@ -743,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;
@@ -783,16 +1005,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 +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
@@ -866,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
@@ -881,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 |
@@ -929,196 +1183,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)
-{
- 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)
+void bootm_init(struct bootm_info *bmi)
{
-#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 30296eb27d7..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,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,
@@ -472,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;
+ ret = efi_binary_run(image_buf, images->os.image_len,
+ images->ft_len
+ ? images->ft_addr : EFI_FDT_USE_INTERNAL);
- image_buf = map_sysmem(images->ep, images->os.image_len);
-
- efi_ret = efi_run_image(image_buf, images->os.image_len);
- if (efi_ret != EFI_SUCCESS)
- return 1;
- return 0;
+ return ret;
}
#endif
@@ -582,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 9ba7734911e..c4eb331d69e 100644
--- a/boot/bootmeth_efi.c
+++ b/boot/bootmeth_efi.c
@@ -160,7 +160,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);
@@ -313,6 +312,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 +323,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 +339,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 +360,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 +391,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 +403,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 +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);
@@ -423,13 +435,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 +452,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;
}
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/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/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 <sjg@chromium.org>
+ */
+
+#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)