diff options
Diffstat (limited to 'boot')
| -rw-r--r-- | boot/Kconfig | 28 | ||||
| -rw-r--r-- | boot/Makefile | 6 | ||||
| -rw-r--r-- | boot/android_ab.c | 18 | ||||
| -rw-r--r-- | boot/bootdev-uclass.c | 14 | ||||
| -rw-r--r-- | boot/bootflow.c | 6 | ||||
| -rw-r--r-- | boot/bootflow_menu.c | 1 | ||||
| -rw-r--r-- | boot/bootm.c | 750 | ||||
| -rw-r--r-- | boot/bootm_os.c | 124 | ||||
| -rw-r--r-- | boot/bootmeth_efi.c | 46 | ||||
| -rw-r--r-- | boot/bootmeth_efi_mgr.c | 4 | ||||
| -rw-r--r-- | boot/bootmeth_extlinux.c | 2 | ||||
| -rw-r--r-- | boot/fdt_support.c | 1 | ||||
| -rw-r--r-- | boot/image-board.c | 69 | ||||
| -rw-r--r-- | boot/image-fdt.c | 84 | ||||
| -rw-r--r-- | boot/image-fit.c | 2 | ||||
| -rw-r--r-- | boot/image.c | 15 | ||||
| -rw-r--r-- | boot/prog_boot.c | 51 | ||||
| -rw-r--r-- | boot/pxe_utils.c | 5 | 
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) | 
