Merge patch series "pxe: Allow extlinux booting without CMDLINE enabled"

Simon Glass <sjg@chromium.org> says:

This series is the culmanation of the current line of refactoring
series. It adjusts pxe to call the booting functionality directly
rather than going through the command-line interface.

With this is is possible to boot using the extlinux bootmeth without
the command line enabled.

It also updates fastboot to do a similar thing.
diff --git a/arch/arc/lib/Makefile b/arch/arc/lib/Makefile
index 0eb44bc..bde1c3d 100644
--- a/arch/arc/lib/Makefile
+++ b/arch/arc/lib/Makefile
@@ -12,6 +12,6 @@
 obj-y += ints_low.o
 obj-y += init_helpers.o
 
-obj-$(CONFIG_CMD_BOOTM) += bootm.o
+obj-$(CONFIG_BOOTM) += bootm.o
 
 lib-$(CONFIG_USE_PRIVATE_LIBGCC) += _millicodethunk.o libgcc2.o
diff --git a/arch/arm/lib/Makefile b/arch/arm/lib/Makefile
index 67275fb..b55167e 100644
--- a/arch/arm/lib/Makefile
+++ b/arch/arm/lib/Makefile
@@ -31,7 +31,7 @@
 obj-$(CONFIG_CPU_V7M) += cmd_boot.o
 obj-$(CONFIG_OF_LIBFDT) += bootm-fdt.o
 obj-$(CONFIG_CMD_BOOTI) += bootm.o image.o
-obj-$(CONFIG_CMD_BOOTM) += bootm.o
+obj-$(CONFIG_BOOTM) += bootm.o
 obj-$(CONFIG_CMD_BOOTZ) += bootm.o zimage.o
 else
 obj-$(CONFIG_$(SPL_TPL_)FRAMEWORK) += spl.o
diff --git a/arch/m68k/lib/Makefile b/arch/m68k/lib/Makefile
index 6e1fd93..5ccd954 100644
--- a/arch/m68k/lib/Makefile
+++ b/arch/m68k/lib/Makefile
@@ -8,7 +8,7 @@
 lib-$(CONFIG_USE_PRIVATE_LIBGCC) += lshrdi3.o muldi3.o ashldi3.o ashrdi3.o
 
 obj-y	+= bdinfo.o
-obj-$(CONFIG_CMD_BOOTM) += bootm.o
+obj-$(CONFIG_BOOTM) += bootm.o
 obj-y	+= cache.o
 obj-y	+= interrupts.o
 obj-y	+= time.o
diff --git a/arch/microblaze/lib/Makefile b/arch/microblaze/lib/Makefile
index dfd8135..2f23482 100644
--- a/arch/microblaze/lib/Makefile
+++ b/arch/microblaze/lib/Makefile
@@ -3,6 +3,6 @@
 # (C) Copyright 2003-2006
 # Wolfgang Denk, DENX Software Engineering, wd@denx.de.
 
-obj-$(CONFIG_CMD_BOOTM) += bootm.o
+obj-$(CONFIG_BOOTM) += bootm.o
 obj-$(CONFIG_CMD_BDI) += bdinfo.o
 obj-y	+= muldi3.o
diff --git a/arch/mips/lib/Makefile b/arch/mips/lib/Makefile
index 1621cc9..4386eb4 100644
--- a/arch/mips/lib/Makefile
+++ b/arch/mips/lib/Makefile
@@ -10,7 +10,7 @@
 obj-y	+= stack.o
 obj-y	+= traps.o
 
-obj-$(CONFIG_CMD_BOOTM) += bootm.o
+obj-$(CONFIG_BOOTM) += bootm.o
 obj-$(CONFIG_CMD_GO) += boot.o
 obj-$(CONFIG_SPL_BUILD) += spl.o
 
diff --git a/arch/nios2/lib/Makefile b/arch/nios2/lib/Makefile
index a9f3c71..68a5ca0 100644
--- a/arch/nios2/lib/Makefile
+++ b/arch/nios2/lib/Makefile
@@ -4,5 +4,5 @@
 # Wolfgang Denk, DENX Software Engineering, wd@denx.de.
 
 obj-y	+= cache.o
-obj-$(CONFIG_CMD_BOOTM) += bootm.o
+obj-$(CONFIG_BOOTM) += bootm.o
 obj-y	+= libgcc.o
diff --git a/arch/powerpc/lib/Makefile b/arch/powerpc/lib/Makefile
index bb819dc..dcce983 100644
--- a/arch/powerpc/lib/Makefile
+++ b/arch/powerpc/lib/Makefile
@@ -34,7 +34,7 @@
 endif
 obj-y	+= reloc.o
 
-obj-$(CONFIG_CMD_BOOTM) += bootm.o
+obj-$(CONFIG_BOOTM) += bootm.o
 obj-y	+= cache.o
 obj-y	+= extable.o
 obj-y	+= interrupts.o
diff --git a/arch/riscv/lib/Makefile b/arch/riscv/lib/Makefile
index 9a05b66..0b2c88d 100644
--- a/arch/riscv/lib/Makefile
+++ b/arch/riscv/lib/Makefile
@@ -6,7 +6,7 @@
 # Copyright (C) 2017 Andes Technology Corporation
 # Rick Chen, Andes Technology Corporation <rick@andestech.com>
 
-obj-$(CONFIG_CMD_BOOTM) += bootm.o
+obj-$(CONFIG_BOOTM) += bootm.o
 obj-$(CONFIG_CMD_BOOTI) += bootm.o image.o
 obj-$(CONFIG_CMD_GO) += boot.o
 obj-y	+= cache.o
diff --git a/arch/sandbox/lib/Makefile b/arch/sandbox/lib/Makefile
index a2bc5a7..c4924b2 100644
--- a/arch/sandbox/lib/Makefile
+++ b/arch/sandbox/lib/Makefile
@@ -7,5 +7,5 @@
 
 obj-y	+= fdt_fixup.o interrupts.o sections.o
 obj-$(CONFIG_PCI)	+= pci_io.o
-obj-$(CONFIG_CMD_BOOTM) += bootm.o
+obj-$(CONFIG_BOOTM) += bootm.o
 obj-$(CONFIG_CMD_BOOTZ) += bootm.o
diff --git a/arch/sh/lib/Makefile b/arch/sh/lib/Makefile
index e7520a3..8c3c302 100644
--- a/arch/sh/lib/Makefile
+++ b/arch/sh/lib/Makefile
@@ -6,7 +6,7 @@
 extra-y	+= start.o
 
 obj-y	+= board.o
-obj-$(CONFIG_CMD_BOOTM) += bootm.o
+obj-$(CONFIG_BOOTM) += bootm.o
 obj-y	+= time.o
 obj-$(CONFIG_CMD_SH_ZIMAGEBOOT) += zimageboot.o
 
diff --git a/arch/x86/lib/Makefile b/arch/x86/lib/Makefile
index 8fc35e1..94aa335 100644
--- a/arch/x86/lib/Makefile
+++ b/arch/x86/lib/Makefile
@@ -16,7 +16,7 @@
 endif
 
 ifndef CONFIG_SPL_BUILD
-obj-$(CONFIG_CMD_BOOTM) += bootm.o
+obj-$(CONFIG_BOOTM) += bootm.o
 endif
 obj-y	+= cmd_boot.o
 obj-$(CONFIG_$(SPL_)COREBOOT_SYSINFO)	+= coreboot/
diff --git a/arch/x86/lib/spl.c b/arch/x86/lib/spl.c
index c15f11f..4e4cf18 100644
--- a/arch/x86/lib/spl.c
+++ b/arch/x86/lib/spl.c
@@ -283,7 +283,7 @@
 {
 	int ret;
 
-	printf("Jumping to 64-bit U-Boot: Note many features are missing\n");
+	printf("Jumping to 64-bit U-Boot\n");
 	ret = cpu_jump_to_64bit_uboot(spl_image->entry_point);
 	debug("ret=%d\n", ret);
 	hang();
diff --git a/arch/xtensa/lib/Makefile b/arch/xtensa/lib/Makefile
index ad4fe32..bb9157f 100644
--- a/arch/xtensa/lib/Makefile
+++ b/arch/xtensa/lib/Makefile
@@ -3,6 +3,6 @@
 # (C) Copyright 2007 - 2013 Tensilica Inc.
 # (C) Copyright 2014 - 2016 Cadence Design Systems Inc.
 
-obj-$(CONFIG_CMD_BOOTM) += bootm.o
+obj-$(CONFIG_BOOTM) += bootm.o
 
 obj-y	+= cache.o misc.o relocate.o time.o
diff --git a/boot/Kconfig b/boot/Kconfig
index d9a6c27..777e408 100644
--- a/boot/Kconfig
+++ b/boot/Kconfig
@@ -2,39 +2,6 @@
 
 menu "Boot images"
 
-config ANDROID_BOOT_IMAGE
-	bool "Android Boot Images"
-	default y if FASTBOOT
-	help
-	  This enables support for booting images which use the Android
-	  image format header.
-
-config TIMESTAMP
-	bool "Show image date and time when displaying image information"
-	default y if CMD_DATE
-	help
-	  When CONFIG_TIMESTAMP is selected, the timestamp (date and time) of
-	  an image is printed by image commands like bootm or iminfo. This
-	  is shown as 'Timestamp: xxx' and 'Created: xxx'. If this option is
-	  enabled, then U-Boot requires FITs to have a timestamp. If a FIT is
-	  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"
-
 menuconfig FIT
 	bool "Flattened Image Tree (FIT)"
 	select HASH
@@ -721,6 +688,100 @@
 
 endif # BOOTSTD
 
+config BOOTM
+	bool "Support booting an application image from memory"
+	default y
+	help
+	  This is the main boot implementation in U-Boot, supporting a wide
+	  variety of features including FIT and legacy-image boot, kernel and
+	  FDT selection, setting up of the command line for the OS and many
+	  other features.
+
+	  This option should normally be enabled. It is used to implement the
+	  'bootm' command.
+
+config BOOTM_LINUX
+	bool "Support booting Linux OS images"
+	depends on BOOTM || CMD_BOOTZ || CMD_BOOTI
+	default y
+	help
+	  Support booting the Linux kernel directly via a command such as bootm
+	  or booti or bootz.
+
+config BOOTM_NETBSD
+	bool "Support booting NetBSD (non-EFI) loader images"
+	depends on BOOTM
+	default y
+	help
+	  Support booting NetBSD via the bootm command.
+
+config BOOTM_OPENRTOS
+	bool "Support booting OPENRTOS / FreeRTOS images"
+	depends on BOOTM
+	help
+	  Support booting OPENRTOS / FreeRTOS via the bootm command.
+
+config BOOTM_OSE
+	bool "Support booting Enea OSE images"
+	depends on (ARM && (ARM64 || CPU_V7A || CPU_V7R) || SANDBOX || PPC || X86)
+	depends on BOOTM
+	help
+	  Support booting Enea OSE images via the bootm command.
+
+config BOOTM_PLAN9
+	bool "Support booting Plan9 OS images"
+	depends on BOOTM
+	default y
+	help
+	  Support booting Plan9 images via the bootm command.
+
+config BOOTM_RTEMS
+	bool "Support booting RTEMS OS images"
+	depends on BOOTM
+	default y
+	help
+	  Support booting RTEMS images via the bootm command.
+
+config BOOTM_VXWORKS
+	bool "Support booting VxWorks OS images"
+	depends on BOOTM
+	default y
+	help
+	  Support booting VxWorks images via the bootm command.
+
+config ANDROID_BOOT_IMAGE
+	bool "Android Boot Images"
+	default y if FASTBOOT
+	help
+	  This enables support for booting images which use the Android
+	  image format header.
+
+config TIMESTAMP
+	bool "Show image date and time when displaying image information"
+	default y if CMD_DATE
+	help
+	  When CONFIG_TIMESTAMP is selected, the timestamp (date and time) of
+	  an image is printed by image commands like bootm or iminfo. This
+	  is shown as 'Timestamp: xxx' and 'Created: xxx'. If this option is
+	  enabled, then U-Boot requires FITs to have a timestamp. If a FIT is
+	  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
@@ -765,7 +826,7 @@
 
 config SYS_BOOTM_LEN
 	hex "Maximum size of a decompresed OS image"
-	depends on CMD_BOOTM || CMD_BOOTI || CMD_BOOTZ || \
+	depends on BOOTM || CMD_BOOTI || CMD_BOOTZ || \
 		LEGACY_IMAGE_FORMAT || SPL_LEGACY_IMAGE_FORMAT
 	default 0x4000000 if PPC || ARM64
 	default 0x1000000 if X86 || ARCH_MX6 || ARCH_MX7
diff --git a/boot/Makefile b/boot/Makefile
index 84ccfea..bf767fd 100644
--- a/boot/Makefile
+++ b/boot/Makefile
@@ -6,7 +6,7 @@
 ifndef CONFIG_SPL_BUILD
 
 obj-$(CONFIG_BOOT_RETRY) += bootretry.o
-obj-$(CONFIG_CMD_BOOTM) += bootm.o bootm_os.o
+obj-$(CONFIG_BOOTM) += bootm.o bootm_os.o
 obj-$(CONFIG_CMD_BOOTZ) += bootm.o bootm_os.o
 obj-$(CONFIG_CMD_BOOTI) += bootm.o bootm_os.o
 
diff --git a/boot/pxe_utils.c b/boot/pxe_utils.c
index 9620562..d5e1bea 100644
--- a/boot/pxe_utils.c
+++ b/boot/pxe_utils.c
@@ -5,6 +5,7 @@
  */
 
 #include <common.h>
+#include <bootm.h>
 #include <command.h>
 #include <dm.h>
 #include <env.h>
@@ -470,6 +471,220 @@
 #endif
 
 /**
+ * calc_fdt_fname() - Figure out the filename to use for the FDT
+ *
+ * Determine the path to the FDT filename, based on the "fdtfile" environment
+ * variable. Use <soc>-<board>.dtb as a fallback
+ *
+ * @fdtdir: Directory to use for the FDT file
+ * Return: allocated filename (including directory), or NULL if out of memory
+ */
+static char *calc_fdt_fname(const char *fdtdir)
+{
+	char *fdtfile;
+	char *f1, *f2, *f3, *f4, *slash;
+	int len;
+
+	f1 = env_get("fdtfile");
+	if (f1) {
+		f2 = "";
+		f3 = "";
+		f4 = "";
+	} else {
+		/*
+		 * For complex cases where this code doesn't generate the
+		 * correct filename, the board code should set $fdtfile during
+		 * early boot, or the boot scripts should set $fdtfile before
+		 * invoking "pxe" or "sysboot".
+		 */
+		f1 = env_get("soc");
+		f2 = "-";
+		f3 = env_get("board");
+		f4 = ".dtb";
+		if (!f1) {
+			f1 = "";
+			f2 = "";
+		}
+		if (!f3) {
+			f2 = "";
+			f3 = "";
+		}
+	}
+
+	len = strlen(fdtdir);
+	if (!len)
+		slash = "./";
+	else if (fdtdir[len - 1] != '/')
+		slash = "/";
+	else
+		slash = "";
+
+	len = strlen(fdtdir) + strlen(slash) + strlen(f1) + strlen(f2) +
+		strlen(f3) + strlen(f4) + 1;
+	fdtfile = malloc(len);
+	if (!fdtfile) {
+		printf("malloc fail (FDT filename)\n");
+		return NULL;
+	}
+
+	snprintf(fdtfile, len, "%s%s%s%s%s%s", fdtdir, slash, f1, f2, f3, f4);
+
+	return fdtfile;
+}
+
+/**
+ * label_run_boot() - Run the correct boot procedure
+ *
+ * fdt usage is optional:
+ * It handles the following scenarios.
+ *
+ * Scenario 1: If fdt_addr_r specified and "fdt" or "fdtdir" label is
+ * defined in pxe file, retrieve fdt blob from server. Pass fdt_addr_r to
+ * bootm, and adjust argc appropriately.
+ *
+ * If retrieve fails and no exact fdt blob is specified in pxe file with
+ * "fdt" label, try Scenario 2.
+ *
+ * Scenario 2: If there is an fdt_addr specified, pass it along to
+ * bootm, and adjust argc appropriately.
+ *
+ * Scenario 3: If there is an fdtcontroladdr specified, pass it along to
+ * bootm, and adjust argc appropriately, unless the image type is fitImage.
+ *
+ * Scenario 4: fdt blob is not available.
+ *
+ * @ctx: PXE context
+ * @label: Label to process
+ * @kernel_addr: string containing the kernel address / config
+ * @initrd_str: string containing the initrd address / size
+ * @initrd_addr_str: initrd address, or NULL if none
+ * @initrd_filesize: initrd size in bytes; only valid if initrd_addr_str is not
+ *	NULL
+ * Returns does not return on success, otherwise returns 0 if a localboot
+ *	label was processed, or 1 on error
+ */
+static int label_run_boot(struct pxe_context *ctx, struct pxe_label *label,
+			  char *kernel_addr, char *initrd_str,
+			  char *initrd_addr_str, char *initrd_filesize)
+{
+	struct bootm_info bmi;
+	const char *fdt_addr;
+	ulong kernel_addr_r;
+	void *buf;
+	int ret;
+
+	if (IS_ENABLED(CONFIG_BOOTM))
+		bootm_init(&bmi);
+
+	fdt_addr = env_get("fdt_addr_r");
+
+	/* For FIT, the label can be identical to kernel one */
+	if (label->fdt && !strcmp(label->kernel_label, label->fdt)) {
+		fdt_addr = kernel_addr;
+	/* if fdt label is defined then get fdt from server */
+	} else if (fdt_addr) {
+		char *fdtfile = NULL;
+		char *fdtfilefree = NULL;
+
+		if (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)
+				return -ENOMEM;
+			fdtfile = fdtfilefree;
+		}
+
+		if (fdtfile) {
+			int err = get_relfile_envaddr(ctx, fdtfile,
+						      "fdt_addr_r", NULL);
+
+			free(fdtfilefree);
+			if (err < 0) {
+				fdt_addr = NULL;
+
+				if (label->fdt) {
+					printf("Skipping %s for failure retrieving FDT\n",
+					       label->name);
+					return -ENOENT;
+				}
+
+				if (label->fdtdir) {
+					printf("Skipping fdtdir %s for failure retrieving dts\n",
+						label->fdtdir);
+				}
+			}
+
+			if (label->kaslrseed)
+				label_boot_kaslrseed();
+
+#ifdef CONFIG_OF_LIBFDT_OVERLAY
+			if (label->fdtoverlays)
+				label_boot_fdtoverlay(ctx, label);
+#endif
+		} else {
+			fdt_addr = NULL;
+		}
+	}
+
+	bmi.addr_img = kernel_addr;
+
+	if (initrd_addr_str)
+		bmi.conf_ramdisk = initrd_str;
+
+	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) {
+		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;
+
+	/* Try bootm for legacy and FIT format image */
+	if (genimg_get_format(buf) != IMAGE_FORMAT_INVALID &&
+	    IS_ENABLED(CONFIG_BOOTM))
+		ret = bootm_run(&bmi);
+	/* Try booting an AArch64 Linux kernel image */
+	else if (IS_ENABLED(CONFIG_BOOTM))
+		ret = booti_run(&bmi);
+	/* Try booting a Image */
+	else if (IS_ENABLED(CONFIG_BOOTM))
+		ret = bootz_run(&bmi);
+	/* Try booting an x86_64 Linux kernel image */
+	else if (IS_ENABLED(CONFIG_ZBOOT))
+		ret = zboot_run(hextoul(kernel_addr, NULL), 0,
+				initrd_addr_str ?
+					hextoul(initrd_addr_str, NULL) : 0,
+				initrd_addr_str ?
+					hextoul(initrd_filesize, NULL) : 0,
+				0, NULL);
+
+	unmap_sysmem(buf);
+
+	return 0;
+}
+
+/**
  * label_boot() - Boot according to the contents of a pxe_label
  *
  * If we can't boot for any reason, we return.  A successful boot never
@@ -491,8 +706,6 @@
  */
 static int label_boot(struct pxe_context *ctx, struct pxe_label *label)
 {
-	char *bootm_argv[] = { "bootm", NULL, NULL, NULL, NULL };
-	char *zboot_argv[] = { "zboot", NULL, "0", NULL, NULL };
 	char *kernel_addr = NULL;
 	char *initrd_addr_str = NULL;
 	char initrd_filesize[10];
@@ -500,11 +713,7 @@
 	char mac_str[29] = "";
 	char ip_str[68] = "";
 	char *fit_addr = NULL;
-	int bootm_argc = 2;
-	int zboot_argc = 3;
-	int len = 0;
-	ulong kernel_addr_r;
-	void *buf;
+	int ret;
 
 	label_print(label);
 
@@ -545,9 +754,10 @@
 
 	/* For FIT, the label can be identical to kernel one */
 	if (label->initrd && !strcmp(label->kernel_label, label->initrd)) {
-		initrd_addr_str =  kernel_addr;
+		initrd_addr_str = kernel_addr;
 	} else if (label->initrd) {
 		ulong size;
+
 		if (get_relfile_envaddr(ctx, label->initrd, "ramdisk_addr_r",
 					&size) < 0) {
 			printf("Skipping %s for failure retrieving initrd\n",
@@ -593,7 +803,7 @@
 		}
 
 		if (label->append)
-			strncpy(bootargs, label->append, sizeof(bootargs));
+			strlcpy(bootargs, label->append, sizeof(bootargs));
 
 		strcat(bootargs, ip_str);
 		strcat(bootargs, mac_str);
@@ -604,180 +814,8 @@
 		printf("append: %s\n", finalbootargs);
 	}
 
-	/*
-	 * fdt usage is optional:
-	 * It handles the following scenarios.
-	 *
-	 * Scenario 1: If fdt_addr_r specified and "fdt" or "fdtdir" label is
-	 * defined in pxe file, retrieve fdt blob from server. Pass fdt_addr_r to
-	 * bootm, and adjust argc appropriately.
-	 *
-	 * If retrieve fails and no exact fdt blob is specified in pxe file with
-	 * "fdt" label, try Scenario 2.
-	 *
-	 * Scenario 2: If there is an fdt_addr specified, pass it along to
-	 * bootm, and adjust argc appropriately.
-	 *
-	 * Scenario 3: If there is an fdtcontroladdr specified, pass it along to
-	 * bootm, and adjust argc appropriately, unless the image type is fitImage.
-	 *
-	 * Scenario 4: fdt blob is not available.
-	 */
-	bootm_argv[3] = env_get("fdt_addr_r");
-
-	/* For FIT, the label can be identical to kernel one */
-	if (label->fdt && !strcmp(label->kernel_label, label->fdt)) {
-		bootm_argv[3] = kernel_addr;
-	/* if fdt label is defined then get fdt from server */
-	} else if (bootm_argv[3]) {
-		char *fdtfile = NULL;
-		char *fdtfilefree = NULL;
-
-		if (label->fdt) {
-			if (IS_ENABLED(CONFIG_SUPPORT_PASSING_ATAGS)) {
-				if (strcmp("-", label->fdt))
-					fdtfile = label->fdt;
-			} else {
-				fdtfile = label->fdt;
-			}
-		} else if (label->fdtdir) {
-			char *f1, *f2, *f3, *f4, *slash;
-
-			f1 = env_get("fdtfile");
-			if (f1) {
-				f2 = "";
-				f3 = "";
-				f4 = "";
-			} else {
-				/*
-				 * For complex cases where this code doesn't
-				 * generate the correct filename, the board
-				 * code should set $fdtfile during early boot,
-				 * or the boot scripts should set $fdtfile
-				 * before invoking "pxe" or "sysboot".
-				 */
-				f1 = env_get("soc");
-				f2 = "-";
-				f3 = env_get("board");
-				f4 = ".dtb";
-				if (!f1) {
-					f1 = "";
-					f2 = "";
-				}
-				if (!f3) {
-					f2 = "";
-					f3 = "";
-				}
-			}
-
-			len = strlen(label->fdtdir);
-			if (!len)
-				slash = "./";
-			else if (label->fdtdir[len - 1] != '/')
-				slash = "/";
-			else
-				slash = "";
-
-			len = strlen(label->fdtdir) + strlen(slash) +
-				strlen(f1) + strlen(f2) + strlen(f3) +
-				strlen(f4) + 1;
-			fdtfilefree = malloc(len);
-			if (!fdtfilefree) {
-				printf("malloc fail (FDT filename)\n");
-				goto cleanup;
-			}
-
-			snprintf(fdtfilefree, len, "%s%s%s%s%s%s",
-				 label->fdtdir, slash, f1, f2, f3, f4);
-			fdtfile = fdtfilefree;
-		}
-
-		if (fdtfile) {
-			int err = get_relfile_envaddr(ctx, fdtfile,
-						      "fdt_addr_r", NULL);
-
-			free(fdtfilefree);
-			if (err < 0) {
-				bootm_argv[3] = NULL;
-
-				if (label->fdt) {
-					printf("Skipping %s for failure retrieving FDT\n",
-					       label->name);
-					goto cleanup;
-				}
-
-				if (label->fdtdir) {
-					printf("Skipping fdtdir %s for failure retrieving dts\n",
-						label->fdtdir);
-				}
-			}
-
-			if (label->kaslrseed)
-				label_boot_kaslrseed();
-
-#ifdef CONFIG_OF_LIBFDT_OVERLAY
-			if (label->fdtoverlays)
-				label_boot_fdtoverlay(ctx, label);
-#endif
-		} else {
-			bootm_argv[3] = NULL;
-		}
-	}
-
-	bootm_argv[1] = kernel_addr;
-	zboot_argv[1] = kernel_addr;
-
-	if (initrd_addr_str) {
-		bootm_argv[2] = initrd_str;
-		bootm_argc = 3;
-
-		zboot_argv[3] = initrd_addr_str;
-		zboot_argv[4] = initrd_filesize;
-		zboot_argc = 5;
-	}
-
-	if (!bootm_argv[3]) {
-		if (IS_ENABLED(CONFIG_SUPPORT_PASSING_ATAGS)) {
-			if (strcmp("-", label->fdt))
-				bootm_argv[3] = env_get("fdt_addr");
-		} else {
-			bootm_argv[3] = env_get("fdt_addr");
-		}
-	}
-
-	kernel_addr_r = genimg_get_kernel_addr(kernel_addr);
-	buf = map_sysmem(kernel_addr_r, 0);
-
-	if (!bootm_argv[3] && genimg_get_format(buf) != IMAGE_FORMAT_FIT) {
-		if (IS_ENABLED(CONFIG_SUPPORT_PASSING_ATAGS)) {
-			if (strcmp("-", label->fdt))
-				bootm_argv[3] = env_get("fdtcontroladdr");
-		} else {
-			bootm_argv[3] = env_get("fdtcontroladdr");
-		}
-	}
-
-	if (bootm_argv[3]) {
-		if (!bootm_argv[2])
-			bootm_argv[2] = "-";
-		bootm_argc = 4;
-	}
-
-	/* Try bootm for legacy and FIT format image */
-	if (genimg_get_format(buf) != IMAGE_FORMAT_INVALID &&
-            IS_ENABLED(CONFIG_CMD_BOOTM))
-		do_bootm(ctx->cmdtp, 0, bootm_argc, bootm_argv);
-	/* Try booting an AArch64 Linux kernel image */
-	else if (IS_ENABLED(CONFIG_CMD_BOOTI))
-		do_booti(ctx->cmdtp, 0, bootm_argc, bootm_argv);
-	/* Try booting a Image */
-	else if (IS_ENABLED(CONFIG_CMD_BOOTZ))
-		do_bootz(ctx->cmdtp, 0, bootm_argc, bootm_argv);
-	/* Try booting an x86_64 Linux kernel image */
-	else if (IS_ENABLED(CONFIG_CMD_ZBOOT))
-		do_zboot_parent(ctx->cmdtp, 0, zboot_argc, zboot_argv, NULL);
-
-	unmap_sysmem(buf);
+	ret = label_run_boot(ctx, label, kernel_addr, initrd_str,
+			     initrd_addr_str, initrd_filesize);
 
 cleanup:
 	free(fit_addr);
diff --git a/cmd/Kconfig b/cmd/Kconfig
index 2e56354..3830519 100644
--- a/cmd/Kconfig
+++ b/cmd/Kconfig
@@ -262,6 +262,7 @@
 
 config CMD_BOOTM
 	bool "bootm"
+	depends on BOOTM
 	default y
 	help
 	  Boot an application image from the memory.
@@ -333,48 +334,6 @@
 	help
 	  Boot an AArch64 Linux Kernel image from memory.
 
-config BOOTM_LINUX
-	bool "Support booting Linux OS images"
-	depends on CMD_BOOTM || CMD_BOOTZ || CMD_BOOTI
-	default y
-	help
-	  Support booting the Linux kernel directly via a command such as bootm
-	  or booti or bootz.
-
-config BOOTM_NETBSD
-	bool "Support booting NetBSD (non-EFI) loader images"
-	depends on CMD_BOOTM
-	default y
-	help
-	  Support booting NetBSD via the bootm command.
-
-config BOOTM_OPENRTOS
-	bool "Support booting OPENRTOS / FreeRTOS images"
-	depends on CMD_BOOTM
-	help
-	  Support booting OPENRTOS / FreeRTOS via the bootm command.
-
-config BOOTM_OSE
-	bool "Support booting Enea OSE images"
-	depends on (ARM && (ARM64 || CPU_V7A || CPU_V7R) || SANDBOX || PPC || X86)
-	depends on CMD_BOOTM
-	help
-	  Support booting Enea OSE images via the bootm command.
-
-config BOOTM_PLAN9
-	bool "Support booting Plan9 OS images"
-	depends on CMD_BOOTM
-	default y
-	help
-	  Support booting Plan9 images via the bootm command.
-
-config BOOTM_RTEMS
-	bool "Support booting RTEMS OS images"
-	depends on CMD_BOOTM
-	default y
-	help
-	  Support booting RTEMS images via the bootm command.
-
 config CMD_SEAMA
 	bool "Support read SEAMA NAND images"
 	depends on MTD_RAW_NAND
@@ -391,13 +350,6 @@
 	  is used to boot. Updating the parameters is not currently
 	  supported.
 
-config BOOTM_VXWORKS
-	bool "Support booting VxWorks OS images"
-	depends on CMD_BOOTM
-	default y
-	help
-	  Support booting VxWorks images via the bootm command.
-
 config CMD_BOOTEFI
 	bool "bootefi"
 	depends on EFI_LOADER
diff --git a/cmd/fastboot.c b/cmd/fastboot.c
index c3c1923..792e83d 100644
--- a/cmd/fastboot.c
+++ b/cmd/fastboot.c
@@ -159,7 +159,7 @@
 		return CMD_RET_USAGE;
 	}
 
-	fastboot_init((void *)buf_addr, buf_size);
+	fastboot_init(buf_addr, buf_size);
 
 	if (!strcmp(argv[1], "udp"))
 		return do_fastboot_udp(argc, argv, buf_addr, buf_size);
diff --git a/configs/colibri_vf_defconfig b/configs/colibri_vf_defconfig
index a5e6bcb..0249dc3 100644
--- a/configs/colibri_vf_defconfig
+++ b/configs/colibri_vf_defconfig
@@ -17,6 +17,7 @@
 CONFIG_ENV_VARS_UBOOT_CONFIG=y
 CONFIG_HAS_BOARD_SIZE_LIMIT=y
 CONFIG_BOARD_SIZE_LIMIT=520192
+# CONFIG_BOOTM is not set
 CONFIG_BOOTDELAY=1
 CONFIG_FDT_FIXUP_PARTITIONS=y
 CONFIG_USE_BOOTCOMMAND=y
@@ -33,7 +34,6 @@
 # CONFIG_SYS_LONGHELP is not set
 CONFIG_SYS_PROMPT="Colibri VFxx # "
 # CONFIG_CMD_BOOTD is not set
-# CONFIG_CMD_BOOTM is not set
 CONFIG_CMD_BOOTZ=y
 # CONFIG_CMD_ELF is not set
 # CONFIG_CMD_IMI is not set
diff --git a/configs/iot_devkit_defconfig b/configs/iot_devkit_defconfig
index c492005..d02a28a 100644
--- a/configs/iot_devkit_defconfig
+++ b/configs/iot_devkit_defconfig
@@ -14,12 +14,12 @@
 CONFIG_SYS_CLK_FREQ=16000000
 CONFIG_SYS_LOAD_ADDR=0x30000000
 CONFIG_LOCALVERSION="-iotdk-1.0"
+# CONFIG_BOOTM is not set
 # CONFIG_ARCH_FIXUP_FDT_MEMORY is not set
 CONFIG_SYS_CBSIZE=256
 CONFIG_SYS_PBSIZE=280
 CONFIG_SYS_PROMPT="IoTDK# "
 # CONFIG_CMD_BOOTD is not set
-# CONFIG_CMD_BOOTM is not set
 # CONFIG_CMD_ELF is not set
 # CONFIG_CMD_XIMG is not set
 # CONFIG_CMD_LOADB is not set
diff --git a/configs/mx6memcal_defconfig b/configs/mx6memcal_defconfig
index 7f11e6f..6c5481c 100644
--- a/configs/mx6memcal_defconfig
+++ b/configs/mx6memcal_defconfig
@@ -14,6 +14,7 @@
 CONFIG_SPL=y
 CONFIG_SYS_MEMTEST_START=0x10000000
 CONFIG_SYS_MEMTEST_END=0x20000000
+# CONFIG_BOOTM is not set
 CONFIG_SUPPORT_RAW_INITRD=y
 CONFIG_SYS_PBSIZE=528
 CONFIG_SPL_SYS_MALLOC=y
@@ -21,7 +22,6 @@
 CONFIG_HUSH_PARSER=y
 CONFIG_SYS_MAXARGS=32
 # CONFIG_CMD_BOOTD is not set
-# CONFIG_CMD_BOOTM is not set
 # CONFIG_CMD_ELF is not set
 # CONFIG_CMD_IMI is not set
 # CONFIG_CMD_XIMG is not set
diff --git a/configs/tools-only_defconfig b/configs/tools-only_defconfig
index b54d2ce..5de482a 100644
--- a/configs/tools-only_defconfig
+++ b/configs/tools-only_defconfig
@@ -12,10 +12,10 @@
 # CONFIG_BOOTSTD_FULL is not set
 # CONFIG_BOOTMETH_CROS is not set
 # CONFIG_BOOTMETH_VBE is not set
+# CONFIG_BOOTM is not set
 CONFIG_USE_BOOTCOMMAND=y
 CONFIG_BOOTCOMMAND="run distro_bootcmd"
 # CONFIG_CMD_BOOTD is not set
-# CONFIG_CMD_BOOTM is not set
 # CONFIG_CMD_BOOTI is not set
 # CONFIG_CMD_ELF is not set
 # CONFIG_CMD_EXTENSION is not set
diff --git a/configs/xilinx_versal_mini_defconfig b/configs/xilinx_versal_mini_defconfig
index 9d3924c..143d262 100644
--- a/configs/xilinx_versal_mini_defconfig
+++ b/configs/xilinx_versal_mini_defconfig
@@ -18,6 +18,7 @@
 CONFIG_SYS_MEMTEST_END=0x00001000
 # CONFIG_EXPERT is not set
 CONFIG_REMAKE_ELF=y
+# CONFIG_BOOTM is not set
 # CONFIG_LEGACY_IMAGE_FORMAT is not set
 # CONFIG_AUTOBOOT is not set
 CONFIG_SYS_CBSIZE=1024
@@ -33,7 +34,6 @@
 CONFIG_SYS_PROMPT="Versal> "
 # CONFIG_CMD_CONSOLE is not set
 # CONFIG_CMD_BOOTD is not set
-# CONFIG_CMD_BOOTM is not set
 # CONFIG_CMD_BOOTI is not set
 # CONFIG_CMD_ELF is not set
 # CONFIG_CMD_FDT is not set
diff --git a/configs/xilinx_versal_mini_emmc0_defconfig b/configs/xilinx_versal_mini_emmc0_defconfig
index 5c949e3..b0e3462 100644
--- a/configs/xilinx_versal_mini_emmc0_defconfig
+++ b/configs/xilinx_versal_mini_emmc0_defconfig
@@ -15,6 +15,7 @@
 CONFIG_SYS_LOAD_ADDR=0x8000000
 # CONFIG_EXPERT is not set
 CONFIG_REMAKE_ELF=y
+# CONFIG_BOOTM is not set
 # CONFIG_AUTOBOOT is not set
 CONFIG_SYS_CBSIZE=1024
 CONFIG_SYS_PBSIZE=1049
@@ -30,7 +31,6 @@
 # CONFIG_CMD_BDI is not set
 # CONFIG_CMD_CONSOLE is not set
 # CONFIG_CMD_BOOTD is not set
-# CONFIG_CMD_BOOTM is not set
 # CONFIG_CMD_BOOTI is not set
 # CONFIG_CMD_ELF is not set
 # CONFIG_CMD_FDT is not set
diff --git a/configs/xilinx_versal_mini_emmc1_defconfig b/configs/xilinx_versal_mini_emmc1_defconfig
index 04cba5b..559b32c 100644
--- a/configs/xilinx_versal_mini_emmc1_defconfig
+++ b/configs/xilinx_versal_mini_emmc1_defconfig
@@ -15,6 +15,7 @@
 CONFIG_SYS_LOAD_ADDR=0x8000000
 # CONFIG_EXPERT is not set
 CONFIG_REMAKE_ELF=y
+# CONFIG_BOOTM is not set
 # CONFIG_AUTOBOOT is not set
 CONFIG_SYS_CBSIZE=1024
 CONFIG_SYS_PBSIZE=1049
@@ -30,7 +31,6 @@
 # CONFIG_CMD_BDI is not set
 # CONFIG_CMD_CONSOLE is not set
 # CONFIG_CMD_BOOTD is not set
-# CONFIG_CMD_BOOTM is not set
 # CONFIG_CMD_BOOTI is not set
 # CONFIG_CMD_ELF is not set
 # CONFIG_CMD_FDT is not set
diff --git a/configs/xilinx_versal_mini_ospi_defconfig b/configs/xilinx_versal_mini_ospi_defconfig
index 7a11035..c02c6ba 100644
--- a/configs/xilinx_versal_mini_ospi_defconfig
+++ b/configs/xilinx_versal_mini_ospi_defconfig
@@ -19,6 +19,7 @@
 CONFIG_LTO=y
 # CONFIG_EXPERT is not set
 CONFIG_REMAKE_ELF=y
+# CONFIG_BOOTM is not set
 # CONFIG_AUTOBOOT is not set
 CONFIG_SYS_CONSOLE_INFO_QUIET=y
 # CONFIG_DISPLAY_CPUINFO is not set
@@ -31,7 +32,6 @@
 # CONFIG_CMD_BDI is not set
 # CONFIG_CMD_CONSOLE is not set
 # CONFIG_CMD_BOOTD is not set
-# CONFIG_CMD_BOOTM is not set
 # CONFIG_CMD_BOOTI is not set
 # CONFIG_CMD_ELF is not set
 # CONFIG_CMD_FDT is not set
diff --git a/configs/xilinx_versal_mini_qspi_defconfig b/configs/xilinx_versal_mini_qspi_defconfig
index 58945a1..4d4b59a 100644
--- a/configs/xilinx_versal_mini_qspi_defconfig
+++ b/configs/xilinx_versal_mini_qspi_defconfig
@@ -17,6 +17,7 @@
 CONFIG_LTO=y
 # CONFIG_EXPERT is not set
 CONFIG_REMAKE_ELF=y
+# CONFIG_BOOTM is not set
 # CONFIG_AUTOBOOT is not set
 # CONFIG_ARCH_FIXUP_FDT_MEMORY is not set
 CONFIG_LOGLEVEL=0
@@ -32,7 +33,6 @@
 # CONFIG_CMD_BDI is not set
 # CONFIG_CMD_CONSOLE is not set
 # CONFIG_CMD_BOOTD is not set
-# CONFIG_CMD_BOOTM is not set
 # CONFIG_CMD_BOOTI is not set
 # CONFIG_CMD_ELF is not set
 # CONFIG_CMD_FDT is not set
diff --git a/configs/xilinx_versal_net_mini_defconfig b/configs/xilinx_versal_net_mini_defconfig
index 7dac1ec..317fc8e 100644
--- a/configs/xilinx_versal_net_mini_defconfig
+++ b/configs/xilinx_versal_net_mini_defconfig
@@ -20,6 +20,7 @@
 CONFIG_SYS_MEMTEST_END=0x00001000
 # CONFIG_EXPERT is not set
 CONFIG_REMAKE_ELF=y
+# CONFIG_BOOTM is not set
 # CONFIG_LEGACY_IMAGE_FORMAT is not set
 # CONFIG_AUTOBOOT is not set
 # CONFIG_ARCH_FIXUP_FDT_MEMORY is not set
@@ -33,7 +34,6 @@
 CONFIG_SYS_PROMPT="Versal NET> "
 # CONFIG_CMD_CONSOLE is not set
 # CONFIG_CMD_BOOTD is not set
-# CONFIG_CMD_BOOTM is not set
 # CONFIG_CMD_BOOTI is not set
 # CONFIG_CMD_ELF is not set
 # CONFIG_CMD_FDT is not set
diff --git a/configs/xilinx_versal_net_mini_emmc_defconfig b/configs/xilinx_versal_net_mini_emmc_defconfig
index fc88eee..31c4432 100644
--- a/configs/xilinx_versal_net_mini_emmc_defconfig
+++ b/configs/xilinx_versal_net_mini_emmc_defconfig
@@ -25,7 +25,7 @@
 # CONFIG_CMD_BDI is not set
 # CONFIG_CMD_CONSOLE is not set
 # CONFIG_CMD_BOOTD is not set
-# CONFIG_CMD_BOOTM is not set
+# CONFIG_BOOTM is not set
 # CONFIG_CMD_BOOTI is not set
 # CONFIG_CMD_ELF is not set
 # CONFIG_CMD_FDT is not set
diff --git a/configs/xilinx_versal_net_mini_ospi_defconfig b/configs/xilinx_versal_net_mini_ospi_defconfig
index d78c9f8..d0d91f9 100644
--- a/configs/xilinx_versal_net_mini_ospi_defconfig
+++ b/configs/xilinx_versal_net_mini_ospi_defconfig
@@ -30,7 +30,7 @@
 # CONFIG_CMD_BDI is not set
 # CONFIG_CMD_CONSOLE is not set
 # CONFIG_CMD_BOOTD is not set
-# CONFIG_CMD_BOOTM is not set
+# CONFIG_BOOTM is not set
 # CONFIG_CMD_BOOTI is not set
 # CONFIG_CMD_ELF is not set
 # CONFIG_CMD_FDT is not set
diff --git a/configs/xilinx_versal_net_mini_qspi_defconfig b/configs/xilinx_versal_net_mini_qspi_defconfig
index b0567f8..48b6d86 100644
--- a/configs/xilinx_versal_net_mini_qspi_defconfig
+++ b/configs/xilinx_versal_net_mini_qspi_defconfig
@@ -31,7 +31,7 @@
 # CONFIG_CMD_BDI is not set
 # CONFIG_CMD_CONSOLE is not set
 # CONFIG_CMD_BOOTD is not set
-# CONFIG_CMD_BOOTM is not set
+# CONFIG_BOOTM is not set
 # CONFIG_CMD_BOOTI is not set
 # CONFIG_CMD_ELF is not set
 # CONFIG_CMD_FDT is not set
diff --git a/configs/xilinx_zynqmp_mini_defconfig b/configs/xilinx_zynqmp_mini_defconfig
index 7fdd2ee..40d4a4a 100644
--- a/configs/xilinx_zynqmp_mini_defconfig
+++ b/configs/xilinx_zynqmp_mini_defconfig
@@ -13,6 +13,7 @@
 CONFIG_SYS_MEMTEST_START=0x00000000
 CONFIG_SYS_MEMTEST_END=0x00001000
 CONFIG_REMAKE_ELF=y
+# CONFIG_BOOTM is not set
 # CONFIG_LEGACY_IMAGE_FORMAT is not set
 # CONFIG_AUTOBOOT is not set
 CONFIG_SYS_CBSIZE=1024
@@ -26,7 +27,6 @@
 # CONFIG_CMD_BDI is not set
 # CONFIG_CMD_CONSOLE is not set
 # CONFIG_CMD_BOOTD is not set
-# CONFIG_CMD_BOOTM is not set
 # CONFIG_CMD_BOOTI is not set
 # CONFIG_CMD_ELF is not set
 # CONFIG_CMD_FDT is not set
diff --git a/configs/xilinx_zynqmp_mini_emmc0_defconfig b/configs/xilinx_zynqmp_mini_emmc0_defconfig
index bf34832..9cccf5d 100644
--- a/configs/xilinx_zynqmp_mini_emmc0_defconfig
+++ b/configs/xilinx_zynqmp_mini_emmc0_defconfig
@@ -17,6 +17,7 @@
 CONFIG_REMAKE_ELF=y
 # CONFIG_MP is not set
 CONFIG_FIT=y
+# CONFIG_BOOTM is not set
 CONFIG_SUPPORT_RAW_INITRD=y
 # CONFIG_AUTOBOOT is not set
 CONFIG_SYS_CBSIZE=1024
@@ -37,7 +38,6 @@
 # CONFIG_CMD_BDI is not set
 # CONFIG_CMD_CONSOLE is not set
 # CONFIG_CMD_BOOTD is not set
-# CONFIG_CMD_BOOTM is not set
 # CONFIG_CMD_BOOTI is not set
 # CONFIG_CMD_ELF is not set
 # CONFIG_CMD_FDT is not set
diff --git a/configs/xilinx_zynqmp_mini_emmc1_defconfig b/configs/xilinx_zynqmp_mini_emmc1_defconfig
index af70ccf..3919e23 100644
--- a/configs/xilinx_zynqmp_mini_emmc1_defconfig
+++ b/configs/xilinx_zynqmp_mini_emmc1_defconfig
@@ -17,6 +17,7 @@
 CONFIG_REMAKE_ELF=y
 # CONFIG_MP is not set
 CONFIG_FIT=y
+# CONFIG_BOOTM is not set
 CONFIG_SUPPORT_RAW_INITRD=y
 # CONFIG_AUTOBOOT is not set
 CONFIG_SYS_CBSIZE=1024
@@ -37,7 +38,6 @@
 # CONFIG_CMD_BDI is not set
 # CONFIG_CMD_CONSOLE is not set
 # CONFIG_CMD_BOOTD is not set
-# CONFIG_CMD_BOOTM is not set
 # CONFIG_CMD_BOOTI is not set
 # CONFIG_CMD_ELF is not set
 # CONFIG_CMD_FDT is not set
diff --git a/configs/xilinx_zynqmp_mini_nand_defconfig b/configs/xilinx_zynqmp_mini_nand_defconfig
index d2e920f..ae0c3ae 100644
--- a/configs/xilinx_zynqmp_mini_nand_defconfig
+++ b/configs/xilinx_zynqmp_mini_nand_defconfig
@@ -13,6 +13,7 @@
 CONFIG_REMAKE_ELF=y
 # CONFIG_MP is not set
 CONFIG_FIT=y
+# CONFIG_BOOTM is not set
 CONFIG_SUPPORT_RAW_INITRD=y
 # CONFIG_AUTOBOOT is not set
 CONFIG_SYS_CBSIZE=1024
@@ -27,7 +28,6 @@
 # CONFIG_CMD_BDI is not set
 # CONFIG_CMD_CONSOLE is not set
 # CONFIG_CMD_BOOTD is not set
-# CONFIG_CMD_BOOTM is not set
 # CONFIG_CMD_BOOTI is not set
 # CONFIG_CMD_GO is not set
 # CONFIG_CMD_RUN is not set
diff --git a/configs/xilinx_zynqmp_mini_nand_single_defconfig b/configs/xilinx_zynqmp_mini_nand_single_defconfig
index 31f6473..15d471c 100644
--- a/configs/xilinx_zynqmp_mini_nand_single_defconfig
+++ b/configs/xilinx_zynqmp_mini_nand_single_defconfig
@@ -13,6 +13,7 @@
 CONFIG_REMAKE_ELF=y
 # CONFIG_MP is not set
 CONFIG_FIT=y
+# CONFIG_BOOTM is not set
 CONFIG_SUPPORT_RAW_INITRD=y
 # CONFIG_AUTOBOOT is not set
 CONFIG_SYS_CBSIZE=1024
@@ -27,7 +28,6 @@
 # CONFIG_CMD_BDI is not set
 # CONFIG_CMD_CONSOLE is not set
 # CONFIG_CMD_BOOTD is not set
-# CONFIG_CMD_BOOTM is not set
 # CONFIG_CMD_BOOTI is not set
 # CONFIG_CMD_GO is not set
 # CONFIG_CMD_RUN is not set
diff --git a/configs/xilinx_zynqmp_mini_qspi_defconfig b/configs/xilinx_zynqmp_mini_qspi_defconfig
index 096feeb..071784c 100644
--- a/configs/xilinx_zynqmp_mini_qspi_defconfig
+++ b/configs/xilinx_zynqmp_mini_qspi_defconfig
@@ -19,6 +19,7 @@
 CONFIG_SYS_LOAD_ADDR=0x8000000
 # CONFIG_EXPERT is not set
 CONFIG_REMAKE_ELF=y
+# CONFIG_BOOTM is not set
 # CONFIG_LEGACY_IMAGE_FORMAT is not set
 # CONFIG_AUTOBOOT is not set
 # CONFIG_ARCH_FIXUP_FDT_MEMORY is not set
@@ -41,7 +42,6 @@
 # CONFIG_CMD_BDI is not set
 # CONFIG_CMD_CONSOLE is not set
 # CONFIG_CMD_BOOTD is not set
-# CONFIG_CMD_BOOTM is not set
 # CONFIG_CMD_BOOTI is not set
 # CONFIG_CMD_ELF is not set
 # CONFIG_CMD_FDT is not set
diff --git a/configs/zynq_cse_nand_defconfig b/configs/zynq_cse_nand_defconfig
index 0dbc804..982777b 100644
--- a/configs/zynq_cse_nand_defconfig
+++ b/configs/zynq_cse_nand_defconfig
@@ -19,6 +19,7 @@
 CONFIG_REMAKE_ELF=y
 CONFIG_SYS_CUSTOM_LDSCRIPT=y
 CONFIG_SYS_LDSCRIPT="arch/arm/mach-zynq/u-boot.lds"
+# CONFIG_BOOTM is not set
 # CONFIG_AUTOBOOT is not set
 CONFIG_USE_PREBOOT=y
 CONFIG_SYS_CBSIZE=1024
@@ -43,7 +44,6 @@
 # CONFIG_CMD_BDI is not set
 # CONFIG_CMD_CONSOLE is not set
 # CONFIG_CMD_BOOTD is not set
-# CONFIG_CMD_BOOTM is not set
 # CONFIG_CMD_ELF is not set
 # CONFIG_CMD_FDT is not set
 # CONFIG_CMD_GO is not set
diff --git a/configs/zynq_cse_nor_defconfig b/configs/zynq_cse_nor_defconfig
index d95f760..7d70dae 100644
--- a/configs/zynq_cse_nor_defconfig
+++ b/configs/zynq_cse_nor_defconfig
@@ -19,6 +19,7 @@
 CONFIG_REMAKE_ELF=y
 CONFIG_SYS_CUSTOM_LDSCRIPT=y
 CONFIG_SYS_LDSCRIPT="arch/arm/mach-zynq/u-boot.lds"
+# CONFIG_BOOTM is not set
 # CONFIG_AUTOBOOT is not set
 CONFIG_USE_PREBOOT=y
 CONFIG_SYS_CBSIZE=1024
@@ -43,7 +44,6 @@
 # CONFIG_CMD_BDI is not set
 # CONFIG_CMD_CONSOLE is not set
 # CONFIG_CMD_BOOTD is not set
-# CONFIG_CMD_BOOTM is not set
 # CONFIG_CMD_ELF is not set
 # CONFIG_CMD_FDT is not set
 # CONFIG_CMD_GO is not set
diff --git a/configs/zynq_cse_qspi_defconfig b/configs/zynq_cse_qspi_defconfig
index dd7f978..c7477aa 100644
--- a/configs/zynq_cse_qspi_defconfig
+++ b/configs/zynq_cse_qspi_defconfig
@@ -25,6 +25,7 @@
 CONFIG_REMAKE_ELF=y
 CONFIG_SYS_CUSTOM_LDSCRIPT=y
 CONFIG_SYS_LDSCRIPT="arch/arm/mach-zynq/u-boot.lds"
+# CONFIG_BOOTM is not set
 # CONFIG_AUTOBOOT is not set
 # CONFIG_ARCH_FIXUP_FDT_MEMORY is not set
 CONFIG_USE_PREBOOT=y
@@ -52,7 +53,6 @@
 # CONFIG_CMD_BDI is not set
 # CONFIG_CMD_CONSOLE is not set
 # CONFIG_CMD_BOOTD is not set
-# CONFIG_CMD_BOOTM is not set
 # CONFIG_CMD_ELF is not set
 # CONFIG_CMD_FDT is not set
 # CONFIG_CMD_GO is not set
diff --git a/doc/android/fastboot.rst b/doc/android/fastboot.rst
index 05d8f77..9e337ca 100644
--- a/doc/android/fastboot.rst
+++ b/doc/android/fastboot.rst
@@ -128,6 +128,7 @@
 
 When executing the fastboot ``boot`` command, if ``fastboot_bootcmd`` is set
 then that will be executed in place of ``bootm <CONFIG_FASTBOOT_BUF_ADDR>``.
+This is supported if CONFIG_CMDLINE is enabled, which it normally is.
 
 Partition Names
 ---------------
diff --git a/doc/board/emulation/qemu-x86.rst b/doc/board/emulation/qemu-x86.rst
index c604e42..4eeba46 100644
--- a/doc/board/emulation/qemu-x86.rst
+++ b/doc/board/emulation/qemu-x86.rst
@@ -134,7 +134,7 @@
 
    U-Boot SPL 2023.07 (Jul 23 2023 - 08:00:12 -0600)
    Trying to boot from SPI
-   Jumping to 64-bit U-Boot: Note many features are missing
+   Jumping to 64-bit U-Boot
 
 
    U-Boot 2023.07 (Jul 23 2023 - 08:00:12 -0600)
diff --git a/drivers/fastboot/Kconfig b/drivers/fastboot/Kconfig
index 5e5855a..58b0812 100644
--- a/drivers/fastboot/Kconfig
+++ b/drivers/fastboot/Kconfig
@@ -1,5 +1,4 @@
 menu "Fastboot support"
-	depends on CMDLINE
 
 config FASTBOOT
 	bool
diff --git a/drivers/fastboot/fb_command.c b/drivers/fastboot/fb_command.c
index f95f4e4..b8782bf 100644
--- a/drivers/fastboot/fb_command.c
+++ b/drivers/fastboot/fb_command.c
@@ -11,6 +11,7 @@
 #include <fastboot-internal.h>
 #include <fb_mmc.h>
 #include <fb_nand.h>
+#include <mapmem.h>
 #include <part.h>
 #include <stdlib.h>
 #include <linux/printk.h>
@@ -278,6 +279,7 @@
 {
 #define BYTES_PER_DOT	0x20000
 	u32 pre_dot_num, now_dot_num;
+	void *buf;
 
 	if (fastboot_data_len == 0 ||
 	    (fastboot_bytes_received + fastboot_data_len) >
@@ -287,8 +289,10 @@
 		return;
 	}
 	/* Download data to fastboot_buf_addr */
-	memcpy(fastboot_buf_addr + fastboot_bytes_received,
+	buf = map_sysmem(fastboot_buf_addr, 0);
+	memcpy(buf + fastboot_bytes_received,
 	       fastboot_data, fastboot_data_len);
+	unmap_sysmem(buf);
 
 	pre_dot_num = fastboot_bytes_received / BYTES_PER_DOT;
 	fastboot_bytes_received += fastboot_data_len;
@@ -331,13 +335,16 @@
  */
 static void __maybe_unused flash(char *cmd_parameter, char *response)
 {
+	void *buf = map_sysmem(fastboot_buf_addr, 0);
+
 	if (IS_ENABLED(CONFIG_FASTBOOT_FLASH_MMC))
-		fastboot_mmc_flash_write(cmd_parameter, fastboot_buf_addr,
-					 image_size, response);
+		fastboot_mmc_flash_write(cmd_parameter, buf, image_size,
+					 response);
 
 	if (IS_ENABLED(CONFIG_FASTBOOT_FLASH_NAND))
-		fastboot_nand_flash_write(cmd_parameter, fastboot_buf_addr,
-					  image_size, response);
+		fastboot_nand_flash_write(cmd_parameter, buf, image_size,
+					  response);
+	unmap_sysmem(buf);
 }
 
 /**
diff --git a/drivers/fastboot/fb_common.c b/drivers/fastboot/fb_common.c
index 3576b06..5959545 100644
--- a/drivers/fastboot/fb_common.c
+++ b/drivers/fastboot/fb_common.c
@@ -11,6 +11,7 @@
  */
 
 #include <bcb.h>
+#include <bootm.h>
 #include <common.h>
 #include <command.h>
 #include <env.h>
@@ -20,7 +21,7 @@
 /**
  * fastboot_buf_addr - base address of the fastboot download buffer
  */
-void *fastboot_buf_addr;
+ulong fastboot_buf_addr;
 
 /**
  * fastboot_buf_size - size of the fastboot download buffer
@@ -142,22 +143,19 @@
  */
 void fastboot_boot(void)
 {
-	char *s;
+	char *s = NULL;
 
-	s = env_get("fastboot_bootcmd");
-	if (s) {
-		run_command(s, CMD_FLAG_ENV);
-	} else if (IS_ENABLED(CONFIG_CMD_BOOTM)) {
-		static char boot_addr_start[20];
-		static char *const bootm_args[] = {
-			"bootm", boot_addr_start, NULL
-		};
+	if (IS_ENABLED(CONFIG_CMDLINE)) {
+		s = env_get("fastboot_bootcmd");
+		if (s)
+			run_command(s, CMD_FLAG_ENV);
+	}
 
-		snprintf(boot_addr_start, sizeof(boot_addr_start) - 1,
-			 "0x%p", fastboot_buf_addr);
-		printf("Booting kernel at %s...\n\n\n", boot_addr_start);
+	if (!s && IS_ENABLED(CONFIG_BOOTM)) {
+		int ret;
 
-		do_bootm(NULL, 0, 2, bootm_args);
+		printf("Booting kernel at %lx...\n\n\n", fastboot_buf_addr);
+		ret = bootm_boot_start(fastboot_buf_addr, NULL);
 
 		/*
 		 * This only happens if image is somehow faulty so we start
@@ -214,16 +212,9 @@
 	fastboot_progress_callback = progress;
 }
 
-/*
- * fastboot_init() - initialise new fastboot protocol session
- *
- * @buf_addr: Pointer to download buffer, or NULL for default
- * @buf_size: Size of download buffer, or zero for default
- */
-void fastboot_init(void *buf_addr, u32 buf_size)
+void fastboot_init(ulong buf_addr, u32 buf_size)
 {
-	fastboot_buf_addr = buf_addr ? buf_addr :
-				       (void *)CONFIG_FASTBOOT_BUF_ADDR;
+	fastboot_buf_addr = buf_addr ? buf_addr : CONFIG_FASTBOOT_BUF_ADDR;
 	fastboot_buf_size = buf_size ? buf_size : CONFIG_FASTBOOT_BUF_SIZE;
 	fastboot_set_progress_callback(NULL);
 }
diff --git a/include/bootm.h b/include/bootm.h
index 6116070..6983375 100644
--- a/include/bootm.h
+++ b/include/bootm.h
@@ -317,7 +317,7 @@
  * bootm_boot_start() - Boot an image at the given address
  *
  * @addr: Image address
- * @cmdline: Command line to set
+ * @cmdline: Command line to set, NULL for default
  */
 int bootm_boot_start(ulong addr, const char *cmdline);
 
diff --git a/include/fastboot-internal.h b/include/fastboot-internal.h
index 610d4f9..e59c187 100644
--- a/include/fastboot-internal.h
+++ b/include/fastboot-internal.h
@@ -6,7 +6,7 @@
 /**
  * fastboot_buf_addr - base address of the fastboot download buffer
  */
-extern void *fastboot_buf_addr;
+extern ulong fastboot_buf_addr;
 
 /**
  * fastboot_buf_size - size of the fastboot download buffer
diff --git a/include/fastboot.h b/include/fastboot.h
index 1e7920e..c75184c 100644
--- a/include/fastboot.h
+++ b/include/fastboot.h
@@ -114,13 +114,13 @@
  */
 void fastboot_set_progress_callback(void (*progress)(const char *msg));
 
-/*
+/**
  * fastboot_init() - initialise new fastboot protocol session
  *
- * @buf_addr: Pointer to download buffer, or NULL for default
+ * @buf_addr: Address of download buffer, or 0 for default
  * @buf_size: Size of download buffer, or zero for default
  */
-void fastboot_init(void *buf_addr, u32 buf_size);
+void fastboot_init(ulong buf_addr, u32 buf_size);
 
 /**
  * fastboot_boot() - Execute fastboot boot command