From a50e886a7f3e42d712fb86423d0ad52546224f44 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 18 Nov 2023 14:04:54 -0700 Subject: bootm: Drop arguments from bootm_start() This function does not use its arguments. Drop them. Signed-off-by: Simon Glass Reviewed-by: Tom Rini Reviewed-by: Ilias Apalodimas --- boot/bootm.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'boot') diff --git a/boot/bootm.c b/boot/bootm.c index cb61485c226..fda97706fc2 100644 --- a/boot/bootm.c +++ b/boot/bootm.c @@ -69,8 +69,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"); @@ -783,7 +782,7 @@ 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); -- cgit v1.2.3 From 921070bcdc7e21c14d3924c6042048b6beadcba9 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 18 Nov 2023 14:04:55 -0700 Subject: bootm: Simplify arguments for bootm_pre_load() Move the argument decoding to the caller, to avoid needing to pass the command-line arguments. Add a function comment while we are here. Signed-off-by: Simon Glass Reviewed-by: Tom Rini --- boot/bootm.c | 23 ++++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-) (limited to 'boot') diff --git a/boot/bootm.c b/boot/bootm.c index fda97706fc2..1482a2cc783 100644 --- a/boot/bootm.c +++ b/boot/bootm.c @@ -82,22 +82,31 @@ static int bootm_start(void) 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)) @@ -785,7 +794,7 @@ int do_bootm_states(struct cmd_tbl *cmdtp, int flag, int argc, ret = bootm_start(); if (!ret && (states & BOOTM_STATE_PRE_LOAD)) - ret = bootm_pre_load(cmdtp, flag, argc, argv); + ret = bootm_pre_load(argv[0]); if (!ret && (states & BOOTM_STATE_FINDOS)) ret = bootm_find_os(cmdtp, flag, argc, argv); -- cgit v1.2.3 From 7f3b1ee3b2633ce83626cf3aa95ef8d71bca563e Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 18 Nov 2023 14:04:56 -0700 Subject: bootm: Move boot_get_kernel() higher in the file Move this code and image_get_kernel() higher in the file to avoid the need for a forward declaration. No attempt is made to remove #ifdefs or adjust the code in any other way. Signed-off-by: Simon Glass Reviewed-by: Tom Rini --- boot/bootm.c | 376 +++++++++++++++++++++++++++++------------------------------ 1 file changed, 186 insertions(+), 190 deletions(-) (limited to 'boot') diff --git a/boot/bootm.c b/boot/bootm.c index 1482a2cc783..598f880d86d 100644 --- a/boot/bootm.c +++ b/boot/bootm.c @@ -44,12 +44,195 @@ DECLARE_GLOBAL_DATA_PTR; struct bootm_headers images; /* pointers to os/initrd/fdt images */ +__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 + * @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); - -__weak void board_quiesce_devices(void) + ulong *os_data, ulong *os_len) { +#if CONFIG_IS_ENABLED(LEGACY_IMAGE_FORMAT) + struct legacy_img_hdr *hdr; +#endif + ulong img_addr; + const void *buf; + const char *fit_uname_config = NULL; + const char *fit_uname_kernel = NULL; +#if CONFIG_IS_ENABLED(FIT) + int os_noffset; +#endif + +#ifdef CONFIG_ANDROID_BOOT_IMAGE + const void *boot_img; + const void *vendor_boot_img; +#endif + img_addr = genimg_get_kernel_addr_fit(argc < 1 ? NULL : argv[0], + &fit_uname_config, + &fit_uname_kernel); + + if (IS_ENABLED(CONFIG_CMD_BOOTM_PRE_LOAD)) + img_addr += image_load_offset; + + bootstage_mark(BOOTSTAGE_ID_CHECK_MAGIC); + + /* check image type, for FIT images get FIT kernel node */ + *os_data = *os_len = 0; + buf = map_sysmem(img_addr, 0); + switch (genimg_get_format(buf)) { +#if CONFIG_IS_ENABLED(LEGACY_IMAGE_FORMAT) + case IMAGE_FORMAT_LEGACY: + printf("## Booting kernel from Legacy Image at %08lx ...\n", + img_addr); + hdr = image_get_kernel(img_addr, images->verify); + if (!hdr) + return NULL; + bootstage_mark(BOOTSTAGE_ID_CHECK_IMAGETYPE); + + /* get os_data and os_len */ + switch (image_get_type(hdr)) { + case IH_TYPE_KERNEL: + case IH_TYPE_KERNEL_NOLOAD: + *os_data = image_get_data(hdr); + *os_len = image_get_data_size(hdr); + break; + case IH_TYPE_MULTI: + image_multi_getimg(hdr, 0, os_data, os_len); + break; + case IH_TYPE_STANDALONE: + *os_data = image_get_data(hdr); + *os_len = image_get_data_size(hdr); + break; + default: + printf("Wrong Image Type for %s command\n", + cmdtp->name); + bootstage_error(BOOTSTAGE_ID_CHECK_IMAGETYPE); + return NULL; + } + + /* + * copy image header to allow for image overwrites during + * kernel decompression. + */ + memmove(&images->legacy_hdr_os_copy, hdr, + sizeof(struct legacy_img_hdr)); + + /* save pointer to image header */ + images->legacy_hdr_os = hdr; + + images->legacy_hdr_valid = 1; + bootstage_mark(BOOTSTAGE_ID_DECOMP_IMAGE); + break; +#endif +#if CONFIG_IS_ENABLED(FIT) + case IMAGE_FORMAT_FIT: + os_noffset = fit_image_load(images, img_addr, + &fit_uname_kernel, &fit_uname_config, + IH_ARCH_DEFAULT, IH_TYPE_KERNEL, + BOOTSTAGE_ID_FIT_KERNEL_START, + FIT_LOAD_IGNORED, os_data, os_len); + if (os_noffset < 0) + return NULL; + + images->fit_hdr_os = map_sysmem(img_addr, 0); + images->fit_uname_os = fit_uname_kernel; + images->fit_uname_cfg = fit_uname_config; + images->fit_noffset_os = os_noffset; + break; +#endif +#ifdef CONFIG_ANDROID_BOOT_IMAGE + case IMAGE_FORMAT_ANDROID: + boot_img = buf; + vendor_boot_img = NULL; + if (IS_ENABLED(CONFIG_CMD_ABOOTIMG)) { + boot_img = map_sysmem(get_abootimg_addr(), 0); + vendor_boot_img = map_sysmem(get_avendor_bootimg_addr(), 0); + } + printf("## Booting Android Image at 0x%08lx ...\n", img_addr); + if (android_image_get_kernel(boot_img, vendor_boot_img, images->verify, + os_data, os_len)) + return NULL; + if (IS_ENABLED(CONFIG_CMD_ABOOTIMG)) { + unmap_sysmem(vendor_boot_img); + unmap_sysmem(boot_img); + } + break; +#endif + default: + printf("Wrong Image Format for %s command\n", cmdtp->name); + bootstage_error(BOOTSTAGE_ID_FIT_KERNEL_INFO); + return NULL; + } + + debug(" kernel data at 0x%08lx, len = 0x%08lx (%ld)\n", + *os_data, *os_len, *os_len); + + return buf; } #ifdef CONFIG_LMB @@ -942,193 +1125,6 @@ int bootm_boot_start(ulong addr, const char *cmdline) 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) -{ -#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; -} - /** * switch_to_non_secure_mode() - switch to non-secure mode * -- cgit v1.2.3 From 530cc4797faebbab2284fd3bddf37f975a3f40f7 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 18 Nov 2023 14:04:57 -0700 Subject: image: Tidy up genimg_get_kernel_addr_fit() This function does not modify its first argument, so mark it const. Also move the comments to the header file and expand them to provide more useful information. Signed-off-by: Simon Glass Reviewed-by: Tom Rini --- boot/bootm.c | 3 +-- boot/image-board.c | 17 +---------------- include/image.h | 29 ++++++++++++++++++++++++++--- 3 files changed, 28 insertions(+), 21 deletions(-) (limited to 'boot') diff --git a/boot/bootm.c b/boot/bootm.c index 598f880d86d..e323c8b758e 100644 --- a/boot/bootm.c +++ b/boot/bootm.c @@ -122,8 +122,7 @@ static const void *boot_get_kernel(struct cmd_tbl *cmdtp, int flag, int argc, #endif ulong img_addr; const void *buf; - const char *fit_uname_config = NULL; - const char *fit_uname_kernel = NULL; + const char *fit_uname_config = NULL, *fit_uname_kernel = NULL; #if CONFIG_IS_ENABLED(FIT) int os_noffset; #endif diff --git a/boot/image-board.c b/boot/image-board.c index d500da1b4b9..062c76badec 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) { diff --git a/include/image.h b/include/image.h index 2e3cf839ee3..798c5f9c16e 100644 --- a/include/image.h +++ b/include/image.h @@ -612,9 +612,32 @@ int boot_get_setup(struct bootm_headers *images, uint8_t arch, ulong *setup_star #define IMAGE_FORMAT_FIT 0x02 /* new, libfdt based format */ #define IMAGE_FORMAT_ANDROID 0x03 /* Android boot image */ -ulong genimg_get_kernel_addr_fit(char * const img_addr, - const char **fit_uname_config, - const char **fit_uname_kernel); +/** + * genimg_get_kernel_addr_fit() - Parse FIT specifier + * + * Get the real kernel start address from a string which is normally the first + * argv of bootm/bootz + * + * These cases are dealt with, based on the value of @img_addr: + * NULL: Returns image_load_addr, does not set last two args + * "": Returns address + * + * For FIT: + * "[]#": Returns address (or image_load_addr), + * sets fit_uname_config to config name + * "[]:": Returns address (or image_load_addr) and sets + * fit_uname_kernel to the subimage name + * + * @img_addr: a string might contain real image address (or NULL) + * @fit_uname_config: Returns configuration unit name + * @fit_uname_kernel: Returns subimage name + * + * Returns: kernel start address + */ +ulong genimg_get_kernel_addr_fit(const char *const img_addr, + const char **fit_uname_config, + const char **fit_uname_kernel); + ulong genimg_get_kernel_addr(char * const img_addr); int genimg_get_format(const void *img_addr); int genimg_has_config(struct bootm_headers *images); -- cgit v1.2.3 From 820110c4532ae45133a338c3c0b103494acba4c4 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 18 Nov 2023 14:04:58 -0700 Subject: bootm: Reduce arguments to boot_get_kernel() This function only uses one argument and just needs to know the name of the command which called it. Adjust the function to use only what it needs. This will make it easier to call from a non-command context. Tidy up the function comment while we are here. Signed-off-by: Simon Glass Reviewed-by: Tom Rini --- boot/bootm.c | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) (limited to 'boot') diff --git a/boot/bootm.c b/boot/bootm.c index e323c8b758e..ea1575bd07e 100644 --- a/boot/bootm.c +++ b/boot/bootm.c @@ -102,9 +102,14 @@ static struct legacy_img_hdr *image_get_kernel(ulong img_addr, int verify) #endif /** - * boot_get_kernel - find kernel image + * boot_get_kernel() - find kernel image + * + * @cmd_name: Name of the command calling this function, e.g. "bootm" + * @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 * * boot_get_kernel() tries to find a kernel image, verifies its integrity * and locates kernel data. @@ -113,8 +118,8 @@ static struct legacy_img_hdr *image_get_kernel(ulong img_addr, int verify) * 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, +static const void *boot_get_kernel(const char *cmd_name, const char *addr_fit, + struct bootm_headers *images, ulong *os_data, ulong *os_len) { #if CONFIG_IS_ENABLED(LEGACY_IMAGE_FORMAT) @@ -131,8 +136,7 @@ static const void *boot_get_kernel(struct cmd_tbl *cmdtp, int flag, int argc, 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, + img_addr = genimg_get_kernel_addr_fit(addr_fit, &fit_uname_config, &fit_uname_kernel); if (IS_ENABLED(CONFIG_CMD_BOOTM_PRE_LOAD)) @@ -169,7 +173,7 @@ static const void *boot_get_kernel(struct cmd_tbl *cmdtp, int flag, int argc, break; default: printf("Wrong Image Type for %s command\n", - cmdtp->name); + cmd_name); bootstage_error(BOOTSTAGE_ID_CHECK_IMAGETYPE); return NULL; } @@ -223,7 +227,7 @@ static const void *boot_get_kernel(struct cmd_tbl *cmdtp, int flag, int argc, break; #endif default: - printf("Wrong Image Format for %s command\n", cmdtp->name); + printf("Wrong Image Format for %s command\n", cmd_name); bootstage_error(BOOTSTAGE_ID_FIT_KERNEL_INFO); return NULL; } @@ -312,8 +316,8 @@ 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); + os_hdr = boot_get_kernel(cmdtp->name, argv[0], &images, + &images.os.image_start, &images.os.image_len); if (images.os.image_len == 0) { puts("ERROR: can't get kernel image!\n"); return 1; -- cgit v1.2.3 From 7721e71f031894da02a8f7a1f419891582b1747c Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 18 Nov 2023 14:05:00 -0700 Subject: bootm: Adjust boot_get_kernel() to return an error This function obtains lots of error codes and then throws them away. Update it to return the error, moving the image pointer to an argument. Signed-off-by: Simon Glass Reviewed-by: Tom Rini --- boot/bootm.c | 35 +++++++++++++++++++++-------------- 1 file changed, 21 insertions(+), 14 deletions(-) (limited to 'boot') diff --git a/boot/bootm.c b/boot/bootm.c index ea1575bd07e..1f3a01994cb 100644 --- a/boot/bootm.c +++ b/boot/bootm.c @@ -110,6 +110,7 @@ static struct legacy_img_hdr *image_get_kernel(ulong img_addr, int verify) * @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. @@ -118,9 +119,9 @@ static struct legacy_img_hdr *image_get_kernel(ulong img_addr, int verify) * pointer to image header if valid image was found, plus kernel start * address and length, otherwise NULL */ -static const void *boot_get_kernel(const char *cmd_name, const char *addr_fit, - struct bootm_headers *images, - ulong *os_data, ulong *os_len) +static int boot_get_kernel(const char *cmd_name, 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; @@ -154,7 +155,7 @@ static const void *boot_get_kernel(const char *cmd_name, const char *addr_fit, img_addr); hdr = image_get_kernel(img_addr, images->verify); if (!hdr) - return NULL; + return -EINVAL; bootstage_mark(BOOTSTAGE_ID_CHECK_IMAGETYPE); /* get os_data and os_len */ @@ -175,7 +176,7 @@ static const void *boot_get_kernel(const char *cmd_name, const char *addr_fit, printf("Wrong Image Type for %s command\n", cmd_name); bootstage_error(BOOTSTAGE_ID_CHECK_IMAGETYPE); - return NULL; + return -EPROTOTYPE; } /* @@ -200,7 +201,7 @@ static const void *boot_get_kernel(const char *cmd_name, const char *addr_fit, BOOTSTAGE_ID_FIT_KERNEL_START, FIT_LOAD_IGNORED, os_data, os_len); if (os_noffset < 0) - return NULL; + return -ENOENT; images->fit_hdr_os = map_sysmem(img_addr, 0); images->fit_uname_os = fit_uname_kernel; @@ -209,7 +210,9 @@ static const void *boot_get_kernel(const char *cmd_name, const char *addr_fit, break; #endif #ifdef CONFIG_ANDROID_BOOT_IMAGE - case IMAGE_FORMAT_ANDROID: + case IMAGE_FORMAT_ANDROID: { + int ret; + boot_img = buf; vendor_boot_img = NULL; if (IS_ENABLED(CONFIG_CMD_ABOOTIMG)) { @@ -217,25 +220,28 @@ static const void *boot_get_kernel(const char *cmd_name, const char *addr_fit, 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; + ret = android_image_get_kernel(boot_img, vendor_boot_img, + images->verify, os_data, os_len); + if (ret) + return ret; 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", cmd_name); bootstage_error(BOOTSTAGE_ID_FIT_KERNEL_INFO); - return NULL; + return -EBADF; } debug(" kernel data at 0x%08lx, len = 0x%08lx (%ld)\n", *os_data, *os_len, *os_len); + *kernp = buf; - return buf; + return 0; } #ifdef CONFIG_LMB @@ -316,8 +322,9 @@ 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->name, argv[0], &images, - &images.os.image_start, &images.os.image_len); + ret = boot_get_kernel(cmdtp->name, argv[0], &images, + &images.os.image_start, &images.os.image_len, + &os_hdr); if (images.os.image_len == 0) { puts("ERROR: can't get kernel image!\n"); return 1; -- cgit v1.2.3 From 4f77169c942b10f9b6dc45a3bc4be65a3d086607 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 18 Nov 2023 14:05:01 -0700 Subject: bootm: Adjust position of unmap_sysmem() in boot_get_kernel() These unmaps should happen regardless of the return value. Move them before the 'return' statement. Signed-off-by: Simon Glass Reviewed-by: Tom Rini --- boot/bootm.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'boot') diff --git a/boot/bootm.c b/boot/bootm.c index 1f3a01994cb..6ed60bf0508 100644 --- a/boot/bootm.c +++ b/boot/bootm.c @@ -222,12 +222,12 @@ static int boot_get_kernel(const char *cmd_name, const char *addr_fit, 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 (ret) - return ret; if (IS_ENABLED(CONFIG_CMD_ABOOTIMG)) { unmap_sysmem(vendor_boot_img); unmap_sysmem(boot_img); } + if (ret) + return ret; break; } #endif -- cgit v1.2.3 From 4c76f5e49a499219cde94de5d0b0e007d3d70f79 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 18 Nov 2023 14:05:02 -0700 Subject: bootm: Use the error return from boot_get_kernel() Rather than looking for a zero-sized image, use the error code returned to determine if things are OK. Signed-off-by: Simon Glass Reviewed-by: Tom Rini --- boot/bootm.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'boot') diff --git a/boot/bootm.c b/boot/bootm.c index 6ed60bf0508..a23c791a9e1 100644 --- a/boot/bootm.c +++ b/boot/bootm.c @@ -324,9 +324,9 @@ static int bootm_find_os(struct cmd_tbl *cmdtp, int flag, int argc, /* get kernel image header, start address and length */ ret = boot_get_kernel(cmdtp->name, argv[0], &images, &images.os.image_start, &images.os.image_len, - &os_hdr); - if (images.os.image_len == 0) { - puts("ERROR: can't get kernel image!\n"); + &os_hdr); + if (ret) { + printf("ERROR %dE: can't get kernel image!\n", ret); return 1; } -- cgit v1.2.3 From bdfa1b67850f5fc775ca00a78993ae1a8178ff1d Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 18 Nov 2023 14:05:03 -0700 Subject: bootstage: Drop BOOTSTAGE_ID_FIT_KERNEL_INFO This is a misnomer since we don't necessarily know that the image is a FIT. Use the existing BOOTSTAGE_ID_CHECK_IMAGETYPE instead. Signed-off-by: Simon Glass Reviewed-by: Tom Rini --- boot/bootm.c | 2 +- include/bootstage.h | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) (limited to 'boot') diff --git a/boot/bootm.c b/boot/bootm.c index a23c791a9e1..9bd93f5dee7 100644 --- a/boot/bootm.c +++ b/boot/bootm.c @@ -233,7 +233,7 @@ static int boot_get_kernel(const char *cmd_name, const char *addr_fit, #endif default: printf("Wrong Image Format for %s command\n", cmd_name); - bootstage_error(BOOTSTAGE_ID_FIT_KERNEL_INFO); + bootstage_error(BOOTSTAGE_ID_CHECK_IMAGETYPE); return -EBADF; } diff --git a/include/bootstage.h b/include/bootstage.h index affb0e5c6a6..59a76d0f0c4 100644 --- a/include/bootstage.h +++ b/include/bootstage.h @@ -147,7 +147,6 @@ enum bootstage_id { BOOTSTAGE_ID_FIT_CONFIG = 110, BOOTSTAGE_ID_FIT_TYPE, - BOOTSTAGE_ID_FIT_KERNEL_INFO, BOOTSTAGE_ID_FIT_COMPRESSION, BOOTSTAGE_ID_FIT_OS, -- cgit v1.2.3 From b13e94886c088271c4fc87a821f4eee5dc4b2112 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 18 Nov 2023 14:05:04 -0700 Subject: bootm: Move error printing out of boot_get_kernel() The same error message is printed in two places. Move it out to the caller so we can avoid passing in the command name. Leave the bootstage handling where it is. Signed-off-by: Simon Glass Reviewed-by: Tom Rini --- boot/bootm.c | 25 +++++++++++-------------- 1 file changed, 11 insertions(+), 14 deletions(-) (limited to 'boot') diff --git a/boot/bootm.c b/boot/bootm.c index 9bd93f5dee7..7aca2bf8146 100644 --- a/boot/bootm.c +++ b/boot/bootm.c @@ -104,7 +104,6 @@ static struct legacy_img_hdr *image_get_kernel(ulong img_addr, int verify) /** * boot_get_kernel() - find kernel image * - * @cmd_name: Name of the command calling this function, e.g. "bootm" * @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 @@ -115,13 +114,11 @@ static struct legacy_img_hdr *image_get_kernel(ulong img_addr, int verify) * 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 + * 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 *cmd_name, const char *addr_fit, - struct bootm_headers *images, ulong *os_data, - ulong *os_len, const void **kernp) +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; @@ -173,8 +170,6 @@ static int boot_get_kernel(const char *cmd_name, const char *addr_fit, *os_len = image_get_data_size(hdr); break; default: - printf("Wrong Image Type for %s command\n", - cmd_name); bootstage_error(BOOTSTAGE_ID_CHECK_IMAGETYPE); return -EPROTOTYPE; } @@ -232,9 +227,8 @@ static int boot_get_kernel(const char *cmd_name, const char *addr_fit, } #endif default: - printf("Wrong Image Format for %s command\n", cmd_name); bootstage_error(BOOTSTAGE_ID_CHECK_IMAGETYPE); - return -EBADF; + return -EPROTOTYPE; } debug(" kernel data at 0x%08lx, len = 0x%08lx (%ld)\n", @@ -322,10 +316,13 @@ static int bootm_find_os(struct cmd_tbl *cmdtp, int flag, int argc, int ret; /* get kernel image header, start address and length */ - ret = boot_get_kernel(cmdtp->name, argv[0], &images, - &images.os.image_start, &images.os.image_len, - &os_hdr); + ret = boot_get_kernel(argv[0], &images, &images.os.image_start, + &images.os.image_len, &os_hdr); if (ret) { + if (ret == -EPROTOTYPE) + printf("Wrong Image Type for %s command\n", + cmdtp->name); + printf("ERROR %dE: can't get kernel image!\n", ret); return 1; } -- cgit v1.2.3 From 3e3bd5bda7e505dde45585e6c7c1e07cddcb641e Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 18 Nov 2023 14:05:05 -0700 Subject: bootm: Reduce arguments to bootm_find_os() This function only uses one argument so pass it in directly. Signed-off-by: Simon Glass Reviewed-by: Tom Rini --- boot/bootm.c | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) (limited to 'boot') diff --git a/boot/bootm.c b/boot/bootm.c index 7aca2bf8146..922989b9cfc 100644 --- a/boot/bootm.c +++ b/boot/bootm.c @@ -304,8 +304,14 @@ static int bootm_pre_load(const char *addr_str) 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 @@ -316,12 +322,11 @@ static int bootm_find_os(struct cmd_tbl *cmdtp, int flag, int argc, int ret; /* get kernel image header, start address and length */ - ret = boot_get_kernel(argv[0], &images, &images.os.image_start, + 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", - cmdtp->name); + printf("Wrong Image Type for %s command\n", cmd_name); printf("ERROR %dE: can't get kernel image!\n", ret); return 1; @@ -987,7 +992,7 @@ int do_bootm_states(struct cmd_tbl *cmdtp, int flag, int argc, ret = bootm_pre_load(argv[0]); if (!ret && (states & BOOTM_STATE_FINDOS)) - ret = bootm_find_os(cmdtp, flag, argc, argv); + ret = bootm_find_os(cmdtp->name, argv[0]); if (!ret && (states & BOOTM_STATE_FINDOTHER)) ret = bootm_find_other(cmdtp, flag, argc, argv); -- cgit v1.2.3 From 8eda15bc6a374a963ddf899d99088e40484d5276 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 18 Nov 2023 14:05:06 -0700 Subject: bootm: Reduce arguments to boot_get_ramdisk() This function normally only uses one argument so pass it in directly. Move comments to the header file so could one day include these functions in API docs. Fix up the u8 argument while here, since it avoids the compiler having to mask the value on some machines. The Android case here is bit strange, since it can use argv[0], so deal with that in the caller. Signed-off-by: Simon Glass Reviewed-by: Tom Rini --- boot/bootm.c | 15 ++++++++++++++- boot/image-board.c | 39 ++------------------------------------- include/image.h | 27 +++++++++++++++++++++++++-- 3 files changed, 41 insertions(+), 40 deletions(-) (limited to 'boot') diff --git a/boot/bootm.c b/boot/bootm.c index 922989b9cfc..d5893e82d12 100644 --- a/boot/bootm.c +++ b/boot/bootm.c @@ -489,10 +489,23 @@ static int bootm_find_os(const char *cmd_name, const char *addr_fit) int bootm_find_images(int flag, int argc, char *const argv[], ulong start, ulong size) { + const char *select = NULL; int ret; + 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 ? argv[0] : env_get("loadaddr"); + } + + if (argc >= 2) + select = argv[1]; + /* 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"); diff --git a/boot/image-board.c b/boot/image-board.c index 062c76badec..60e514fc150 100644 --- a/boot/image-board.c +++ b/boot/image-board.c @@ -456,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 diff --git a/include/image.h b/include/image.h index d37e4472167..3e48ad5b303 100644 --- a/include/image.h +++ b/include/image.h @@ -644,8 +644,31 @@ int genimg_has_config(struct bootm_headers *images); int boot_get_fpga(int argc, char *const argv[], struct bootm_headers *images, uint8_t arch, const ulong *ld_start, ulong * const ld_len); -int boot_get_ramdisk(int argc, char *const argv[], struct bootm_headers *images, - uint8_t arch, ulong *rd_start, ulong *rd_end); + +/** + * boot_get_ramdisk() - Locate the ramdisk + * + * @select: address or name of ramdisk to use, or NULL for default + * @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(char const *select, struct bootm_headers *images, + uint arch, ulong *rd_start, ulong *rd_end); /** * boot_get_loadable - routine to load a list of binaries to memory -- cgit v1.2.3 From 972d524893e4635ff1ac4286a870cda2dd3fc301 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 18 Nov 2023 14:05:08 -0700 Subject: bootm: Drop #ifdef in bootm_find_images() The OF_LIBFDT #ifdef makes it harder to use a local variable for that code block. Convert it to if() instead. Signed-off-by: Simon Glass --- boot/bootm.c | 42 +++++++++++++++++++++--------------------- 1 file changed, 21 insertions(+), 21 deletions(-) (limited to 'boot') diff --git a/boot/bootm.c b/boot/bootm.c index d5893e82d12..d9c62d730f7 100644 --- a/boot/bootm.c +++ b/boot/bootm.c @@ -524,29 +524,29 @@ int bootm_find_images(int flag, int argc, char *const argv[], ulong start, 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)) { + /* 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; + } - /* 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; - } + /* 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; + } - if (IS_ENABLED(CONFIG_CMD_FDT)) - set_working_fdt_addr(map_to_sysmem(images.ft_addr)); -#endif + 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)) { -- cgit v1.2.3 From ba5e3f7f7825169d95a17cc4929143f522e82868 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 18 Nov 2023 14:05:09 -0700 Subject: bootm: Pass image buffer to boot_get_fdt() Rather than having boot_get_fdt() calculate this, move the calculation into the caller. This removes the access to argv[0] in this function, so we can later refactor it to just accept argv[2] instead of the whole argv[]. Move the function comment to the header file and fix the u8 argument, while we are here. Signed-off-by: Simon Glass Reviewed-by: Tom Rini --- boot/bootm.c | 11 +++++++---- boot/image-fdt.c | 32 +++----------------------------- include/image.h | 31 ++++++++++++++++++++++++++++--- 3 files changed, 38 insertions(+), 36 deletions(-) (limited to 'boot') diff --git a/boot/bootm.c b/boot/bootm.c index d9c62d730f7..cd11994e21c 100644 --- a/boot/bootm.c +++ b/boot/bootm.c @@ -490,11 +490,11 @@ int bootm_find_images(int flag, int argc, char *const argv[], ulong start, ulong size) { const char *select = NULL; + ulong img_addr; + void *buf; int ret; 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) @@ -525,9 +525,12 @@ int bootm_find_images(int flag, int argc, char *const argv[], ulong start, } if (CONFIG_IS_ENABLED(OF_LIBFDT)) { + img_addr = argc ? hextoul(argv[0], NULL) : image_load_addr; + buf = map_sysmem(img_addr, 0); + /* find flattened device tree */ - ret = boot_get_fdt(flag, argc, argv, IH_ARCH_DEFAULT, &images, - &images.ft_addr, &images.ft_len); + ret = boot_get_fdt(buf, 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; diff --git a/boot/image-fdt.c b/boot/image-fdt.c index f10200f6474..6ff2d52d6c7 100644 --- a/boot/image-fdt.c +++ b/boot/image-fdt.c @@ -447,43 +447,17 @@ 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, int flag, int argc, char *const argv[], 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; *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)) { diff --git a/include/image.h b/include/image.h index 3e48ad5b303..a4555f25fb5 100644 --- a/include/image.h +++ b/include/image.h @@ -808,9 +808,34 @@ int image_locate_script(void *buf, int size, const char *fit_uname, int fit_get_node_from_config(struct bootm_headers *images, const char *prop_name, ulong addr); -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); +/** + * boot_get_fdt() - locate FDT devicetree to use for booting + * + * @buf: Pointer to image + * @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 FDT sources: + * - multicomponent kernel/ramdisk/FDT image, + * - commandline provided address of decicated FDT image. + * + * Return: + * 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(void *buf, int flag, int argc, char *const argv[], uint arch, + struct bootm_headers *images, char **of_flat_tree, + ulong *of_size); + void boot_fdt_add_mem_rsv_regions(struct lmb *lmb, void *fdt_blob); int boot_relocate_fdt(struct lmb *lmb, char **of_flat_tree, ulong *of_size); -- cgit v1.2.3 From 0aa923aba53ecf6a9baf36dc6e81cd25c41cd718 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 18 Nov 2023 14:05:10 -0700 Subject: bootm: Reduce arguments to boot_get_fdt() This function only uses one argument from bootm (argv[2]) so pass it in directly. Signed-off-by: Simon Glass Reviewed-by: Tom Rini --- boot/bootm.c | 5 +++-- boot/image-fdt.c | 9 +++------ include/image.h | 5 ++--- 3 files changed, 8 insertions(+), 11 deletions(-) (limited to 'boot') diff --git a/boot/bootm.c b/boot/bootm.c index cd11994e21c..5dc9cdeb244 100644 --- a/boot/bootm.c +++ b/boot/bootm.c @@ -529,8 +529,9 @@ int bootm_find_images(int flag, int argc, char *const argv[], ulong start, buf = map_sysmem(img_addr, 0); /* find flattened device tree */ - ret = boot_get_fdt(buf, flag, argc, argv, IH_ARCH_DEFAULT, - &images, &images.ft_addr, &images.ft_len); + ret = boot_get_fdt(buf, argc > 2 ? argv[2] : NULL, + IH_ARCH_DEFAULT, &images, &images.ft_addr, + &images.ft_len); if (ret) { puts("Could not find a valid device tree\n"); return 1; diff --git a/boot/image-fdt.c b/boot/image-fdt.c index 6ff2d52d6c7..08fca08b710 100644 --- a/boot/image-fdt.c +++ b/boot/image-fdt.c @@ -447,19 +447,16 @@ static int select_fdt(struct bootm_headers *images, const char *select, u8 arch, return 0; } -int boot_get_fdt(void *buf, int flag, int argc, char *const argv[], uint arch, +int boot_get_fdt(void *buf, const char *select, uint arch, struct bootm_headers *images, char **of_flat_tree, ulong *of_size) { - ulong fdt_addr; - char *fdt_blob = NULL; - const char *select = NULL; + char *fdt_blob = NULL; + ulong fdt_addr; *of_flat_tree = NULL; *of_size = 0; - if (argc > 2) - select = argv[2]; if (select || genimg_has_config(images)) { int ret; diff --git a/include/image.h b/include/image.h index a4555f25fb5..04f35de9d08 100644 --- a/include/image.h +++ b/include/image.h @@ -812,8 +812,7 @@ int fit_get_node_from_config(struct bootm_headers *images, * boot_get_fdt() - locate FDT devicetree to use for booting * * @buf: Pointer to image - * @argc: command argument count - * @argv: command argument list + * @select: FDT to select (this is normally argv[2] of the bootm command) * @arch: architecture (IH_ARCH_...) * @images: pointer to the bootm images structure * @of_flat_tree: pointer to a char* variable, will hold fdt start address @@ -832,7 +831,7 @@ int fit_get_node_from_config(struct bootm_headers *images, * 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(void *buf, int flag, int argc, char *const argv[], uint arch, +int boot_get_fdt(void *buf, const char *select, uint arch, struct bootm_headers *images, char **of_flat_tree, ulong *of_size); -- cgit v1.2.3 From 745367b218c024dfcde72c37d15da88918e37e18 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 18 Nov 2023 14:05:11 -0700 Subject: bootm: Reduce arguments to boot_get_fpga() This function only uses two arguments. The 'arch' always has a constant value, so drop it. This simplifies the function call. Signed-off-by: Simon Glass Reviewed-by: Tom Rini --- boot/bootm.c | 3 +-- boot/image-board.c | 5 ++--- include/image.h | 9 +++++++-- 3 files changed, 10 insertions(+), 7 deletions(-) (limited to 'boot') diff --git a/boot/bootm.c b/boot/bootm.c index 5dc9cdeb244..ae3fceb392d 100644 --- a/boot/bootm.c +++ b/boot/bootm.c @@ -555,8 +555,7 @@ int bootm_find_images(int flag, int argc, char *const argv[], ulong start, #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; diff --git a/boot/image-board.c b/boot/image-board.c index 60e514fc150..b926275ec91 100644 --- a/boot/image-board.c +++ b/boot/image-board.c @@ -616,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; @@ -659,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, diff --git a/include/image.h b/include/image.h index 04f35de9d08..63f2bd3b371 100644 --- a/include/image.h +++ b/include/image.h @@ -642,8 +642,13 @@ ulong genimg_get_kernel_addr(char * const img_addr); int genimg_get_format(const void *img_addr); int genimg_has_config(struct bootm_headers *images); -int boot_get_fpga(int argc, char *const argv[], struct bootm_headers *images, - uint8_t arch, const ulong *ld_start, ulong * const ld_len); +/** + * boot_get_fpga() - Locate the FPGA image + * + * @images: Information about images being loaded + * Return 0 if OK, non-zero on failure + */ +int boot_get_fpga(struct bootm_headers *images); /** * boot_get_ramdisk() - Locate the ramdisk -- cgit v1.2.3 From 96456285c28138999c095dd64a259bdc6c98ec8b Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 18 Nov 2023 14:05:12 -0700 Subject: bootm: Reduce arguments to boot_get_loadables() This function only uses two arguments. The 'arch' always has a constant value, so drop it. This simplifies the function call. Tidy up the function comment while we are here. Signed-off-by: Simon Glass Reviewed-by: Tom Rini --- boot/bootm.c | 3 +-- boot/image-board.c | 6 +++--- include/image.h | 24 +++++++++--------------- 3 files changed, 13 insertions(+), 20 deletions(-) (limited to 'boot') diff --git a/boot/bootm.c b/boot/bootm.c index ae3fceb392d..aae097df0c7 100644 --- a/boot/bootm.c +++ b/boot/bootm.c @@ -563,8 +563,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; diff --git a/boot/image-board.c b/boot/image-board.c index b926275ec91..bb0ca9d7f22 100644 --- a/boot/image-board.c +++ b/boot/image-board.c @@ -718,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 @@ -765,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); diff --git a/include/image.h b/include/image.h index 63f2bd3b371..b89912a50f9 100644 --- a/include/image.h +++ b/include/image.h @@ -676,28 +676,22 @@ int boot_get_ramdisk(char const *select, struct bootm_headers *images, uint arch, ulong *rd_start, ulong *rd_end); /** - * boot_get_loadable - routine to load a list of binaries to memory - * @argc: Ignored Argument - * @argv: Ignored Argument + * boot_get_loadable() - load a list of binaries to memory + * * @images: pointer to the bootm images structure - * @arch: expected architecture for the image - * @ld_start: Ignored Argument - * @ld_len: Ignored Argument * - * boot_get_loadable() will take the given FIT configuration, and look - * for a field named "loadables". Loadables, is a list of elements in - * the FIT given as strings. exe: + * Takes the given FIT configuration, then looks for a field named + * "loadables", a list of elements in the FIT given as strings, e.g.: * loadables = "linux_kernel", "fdt-2"; - * this function will attempt to parse each string, and load the - * corresponding element from the FIT into memory. Once placed, - * no aditional actions are taken. * - * @return: + * Each string is parsed, loading the corresponding element from the FIT into + * memory. Once placed, no additional actions are taken. + * + * Return: * 0, if only valid images or no images are found * error code, if an error occurs during fit_image_load */ -int boot_get_loadable(int argc, char *const argv[], struct bootm_headers *images, - uint8_t arch, const ulong *ld_start, ulong *const ld_len); +int boot_get_loadable(struct bootm_headers *images); int boot_get_setup_fit(struct bootm_headers *images, uint8_t arch, ulong *setup_start, ulong *setup_len); -- cgit v1.2.3 From 46aee252aff82e05f9d8adfd8565c453ed013bff Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 18 Nov 2023 14:05:13 -0700 Subject: bootm: Simplify Android ramdisk addr in bootm_find_images() The Android mechanism uses the loadaddr envrionment-variable to get the load address, if none is provided. This is equivalent to image_load_addr so use that instead, converting it to a string as needed. This change will permit passing img_addr to this function, in a future change. Signed-off-by: Simon Glass Reviewed-by: Tom Rini --- boot/bootm.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) (limited to 'boot') diff --git a/boot/bootm.c b/boot/bootm.c index aae097df0c7..db1466cecf2 100644 --- a/boot/bootm.c +++ b/boot/bootm.c @@ -490,15 +490,20 @@ int bootm_find_images(int flag, int argc, char *const argv[], ulong start, ulong size) { const char *select = NULL; + char addr_str[17]; ulong img_addr; void *buf; int ret; + img_addr = argc ? hextoul(argv[0], NULL) : image_load_addr; + 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) - select = argc ? argv[0] : env_get("loadaddr"); + if (buf && genimg_get_format(buf) == IMAGE_FORMAT_ANDROID) { + strcpy(addr_str, simple_xtoa(img_addr)); + select = addr_str; + } } if (argc >= 2) @@ -525,7 +530,6 @@ int bootm_find_images(int flag, int argc, char *const argv[], ulong start, } if (CONFIG_IS_ENABLED(OF_LIBFDT)) { - img_addr = argc ? hextoul(argv[0], NULL) : image_load_addr; buf = map_sysmem(img_addr, 0); /* find flattened device tree */ -- cgit v1.2.3 From e2fc90e5ad469b10c0d7abe54f5689957c88a518 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 18 Nov 2023 14:05:14 -0700 Subject: bootm: efi: Drop special call to bootm_find_other() The normal bootm flow calls bootm_find_other() can call the BOOTM_STATE_FINDOTHER state as part of its processing. Fix the condition there so that this hack can be removed. Signed-off-by: Simon Glass --- boot/bootm.c | 10 +++++----- boot/bootm_os.c | 6 ------ 2 files changed, 5 insertions(+), 11 deletions(-) (limited to 'boot') diff --git a/boot/bootm.c b/boot/bootm.c index db1466cecf2..dc64de952c2 100644 --- a/boot/bootm.c +++ b/boot/bootm.c @@ -580,11 +580,11 @@ int bootm_find_images(int flag, int argc, char *const argv[], ulong start, static int bootm_find_other(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) { - 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)) + 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)) return bootm_find_images(flag, argc, argv, 0, 0); return 0; diff --git a/boot/bootm_os.c b/boot/bootm_os.c index 30296eb27d7..af25c9e7c81 100644 --- a/boot/bootm_os.c +++ b/boot/bootm_os.c @@ -486,18 +486,12 @@ static int do_bootm_tee(int flag, int argc, char *const argv[], static int do_bootm_efi(int flag, int argc, char *const argv[], struct bootm_headers *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) { -- cgit v1.2.3 From b020254d71ed0873baddb9b9bc6ec5bf1e82b26c Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 18 Nov 2023 14:05:15 -0700 Subject: bootm: optee: Drop special call to bootm_find_other() The normal bootm flow calls bootm_find_other() can call the BOOTM_STATE_FINDOTHER state as part of its processing. Fix the condition there so that this hack can be removed. Also drop the confusing check for the OS type, since do_bootm_tee() is only called if the condition is met - see bootm_os_get_boot_func() Signed-off-by: Simon Glass --- boot/bootm.c | 2 +- boot/bootm_os.c | 10 ---------- 2 files changed, 1 insertion(+), 11 deletions(-) (limited to 'boot') diff --git a/boot/bootm.c b/boot/bootm.c index dc64de952c2..45491e3f30a 100644 --- a/boot/bootm.c +++ b/boot/bootm.c @@ -584,7 +584,7 @@ static int bootm_find_other(struct cmd_tbl *cmdtp, int flag, int argc, 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_EFI || images.os.os == IH_OS_TEE)) return bootm_find_images(flag, argc, argv, 0, 0); return 0; diff --git a/boot/bootm_os.c b/boot/bootm_os.c index af25c9e7c81..b92422171a8 100644 --- a/boot/bootm_os.c +++ b/boot/bootm_os.c @@ -460,11 +460,6 @@ static int do_bootm_tee(int flag, int argc, char *const argv[], { 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,11 +467,6 @@ 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); } -- cgit v1.2.3 From 3ac85bdc6a6cc5bc8a93ad91b330015ad8355cb2 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 18 Nov 2023 14:05:16 -0700 Subject: bootm: Adjust the parameters of bootm_find_images() Rather than passing it all the command-line args, pass in the pieces that it needs. These are the image address, the ramdisk address/name and the FDT address/name. Ultimately this will allow usage of this function without being called from the command line. Move the function comment to the header file and tidy it a little. Signed-off-by: Simon Glass --- boot/bootm.c | 45 ++++++++++++++------------------------------- cmd/booti.c | 4 +++- cmd/bootz.c | 4 +++- include/bootm.h | 26 +++++++++++++++++++++++--- 4 files changed, 43 insertions(+), 36 deletions(-) (limited to 'boot') diff --git a/boot/bootm.c b/boot/bootm.c index 45491e3f30a..fe6e84601f5 100644 --- a/boot/bootm.c +++ b/boot/bootm.c @@ -468,35 +468,14 @@ static int bootm_find_os(const char *cmd_name, const char *addr_fit) return 0; } -/** - * bootm_find_images - wrapper to find and locate various images - * @flag: Ignored Argument - * @argc: command argument count - * @argv: command argument list - * @start: OS image start address - * @size: OS image size - * - * boot_find_images() will attempt to load an available ramdisk, - * flattened device tree, as well as specifically marked - * "loadable" images (loadables are FIT only) - * - * Note: bootm_find_images will skip an image if it is not found - * - * @return: - * 0, if all existing images were loaded correctly - * 1, if an image is found but corrupted, or invalid - */ -int bootm_find_images(int flag, int argc, char *const argv[], ulong start, - ulong size) +int bootm_find_images(ulong img_addr, const char *conf_ramdisk, + const char *conf_fdt, ulong start, ulong size) { - const char *select = NULL; + const char *select = conf_ramdisk; char addr_str[17]; - ulong img_addr; void *buf; int ret; - img_addr = argc ? hextoul(argv[0], NULL) : image_load_addr; - if (IS_ENABLED(CONFIG_ANDROID_BOOT_IMAGE)) { /* Look for an Android boot image */ buf = map_sysmem(images.os.start, 0); @@ -506,8 +485,8 @@ int bootm_find_images(int flag, int argc, char *const argv[], ulong start, } } - if (argc >= 2) - select = argv[1]; + if (conf_ramdisk) + select = conf_ramdisk; /* find ramdisk */ ret = boot_get_ramdisk(select, &images, IH_INITRD_ARCH, @@ -533,9 +512,8 @@ int bootm_find_images(int flag, int argc, char *const argv[], ulong start, buf = map_sysmem(img_addr, 0); /* find flattened device tree */ - ret = boot_get_fdt(buf, argc > 2 ? argv[2] : NULL, - IH_ARCH_DEFAULT, &images, &images.ft_addr, - &images.ft_len); + 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; @@ -584,8 +562,13 @@ static int bootm_find_other(struct cmd_tbl *cmdtp, int flag, int argc, 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(flag, argc, argv, 0, 0); + images.os.os == IH_OS_EFI || images.os.os == IH_OS_TEE)) { + ulong img_addr; + + img_addr = argc ? hextoul(argv[0], NULL) : image_load_addr; + return bootm_find_images(img_addr, argc > 1 ? argv[1] : NULL, + argc > 2 ? argv[2] : NULL, 0, 0); + } return 0; } diff --git a/cmd/booti.c b/cmd/booti.c index a6c7db272c5..dc73c83f0db 100644 --- a/cmd/booti.c +++ b/cmd/booti.c @@ -95,7 +95,9 @@ static int booti_start(struct cmd_tbl *cmdtp, int flag, int argc, * Handle the BOOTM_STATE_FINDOTHER state ourselves as we do not * have a header that provide this informaiton. */ - if (bootm_find_images(flag, argc, argv, relocated_addr, image_size)) + if (bootm_find_images(image_load_addr, argc > 1 ? argv[1] : NULL, + argc > 2 ? argv[2] : NULL, relocated_addr, + image_size)) return 1; return 0; diff --git a/cmd/bootz.c b/cmd/bootz.c index dd6fe4904b0..bcf232b4f30 100644 --- a/cmd/bootz.c +++ b/cmd/bootz.c @@ -54,7 +54,9 @@ static int bootz_start(struct cmd_tbl *cmdtp, int flag, int argc, * Handle the BOOTM_STATE_FINDOTHER state ourselves as we do not * have a header that provide this informaiton. */ - if (bootm_find_images(flag, argc, argv, images->ep, zi_end - zi_start)) + if (bootm_find_images(image_load_addr, argc > 1 ? argv[1] : NULL, + argc > 2 ? argv[2] : NULL, images->ep, + zi_end - zi_start)) return 1; return 0; diff --git a/include/bootm.h b/include/bootm.h index 10a1bd65a75..f5229ea90b3 100644 --- a/include/bootm.h +++ b/include/bootm.h @@ -52,9 +52,29 @@ int boot_selected_os(int argc, char *const argv[], int state, ulong bootm_disable_interrupts(void); -/* This is a special function used by booti/bootz */ -int bootm_find_images(int flag, int argc, char *const argv[], ulong start, - ulong size); +/** + * bootm_find_images() - find and locate various images + * + * @img_addr: Address of image being loaded + * @conf_ramdisk: Indicates the ramdisk to use (typically second arg of bootm) + * @conf_fdt: Indicates the FDT to use (typically third arg of bootm) + * @start: OS image start address + * @size: OS image size + * + * boot_find_images() will attempt to load an available ramdisk, + * flattened device tree, as well as specifically marked + * "loadable" images (loadables are FIT only) + * + * Note: bootm_find_images will skip an image if it is not found + * + * This is a special function used by booti/bootz + * + * Return: + * 0, if all existing images were loaded correctly + * 1, if an image is found but corrupted, or invalid + */ +int bootm_find_images(ulong img_addr, const char *conf_ramdisk, + const char *conf_fdt, ulong start, ulong size); /* * Measure the boot images. Measurement is the process of hashing some binary -- cgit v1.2.3 From 65f0bfe28acc5183d4bef9ebe9b31bdac0e89e6a Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 18 Nov 2023 14:05:17 -0700 Subject: bootm: Add a function to check overlap Move this code into a function to reduce code size and make it easier to understand. Drop the unnecessary 0x to help a little with code size. Use this in bootm_find_images() Signed-off-by: Simon Glass Reviewed-by: Tom Rini --- boot/bootm.c | 51 ++++++++++++++++++++++++++++++++++----------------- 1 file changed, 34 insertions(+), 17 deletions(-) (limited to 'boot') diff --git a/boot/bootm.c b/boot/bootm.c index fe6e84601f5..371f404a02a 100644 --- a/boot/bootm.c +++ b/boot/bootm.c @@ -468,6 +468,37 @@ static int bootm_find_os(const char *cmd_name, const char *addr_fit) return 0; } +/** + * check_overlap() - Check if an image overlaps the OS + * + * @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 + */ +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) { @@ -497,16 +528,8 @@ int bootm_find_images(ulong img_addr, const char *conf_ramdisk, } /* 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)) { buf = map_sysmem(img_addr, 0); @@ -520,15 +543,9 @@ int bootm_find_images(ulong img_addr, const char *conf_ramdisk, } /* 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); + 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)); -- cgit v1.2.3 From 984e6fedb54ee45002b8b7e2de916346a1aca26c Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 18 Nov 2023 14:05:18 -0700 Subject: bootm: Reduce arguments to bootm_find_other() Rather than passing the full list of command arguments, pass only those which are needed. Signed-off-by: Simon Glass Reviewed-by: Tom Rini --- boot/bootm.c | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) (limited to 'boot') diff --git a/boot/bootm.c b/boot/bootm.c index 371f404a02a..07aae26af01 100644 --- a/boot/bootm.c +++ b/boot/bootm.c @@ -572,19 +572,16 @@ int bootm_find_images(ulong img_addr, const char *conf_ramdisk, 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 || images.os.os == IH_OS_EFI || images.os.os == IH_OS_TEE)) { - ulong img_addr; - - img_addr = argc ? hextoul(argv[0], NULL) : image_load_addr; - return bootm_find_images(img_addr, argc > 1 ? argv[1] : NULL, - argc > 2 ? argv[2] : NULL, 0, 0); + return bootm_find_images(img_addr, conf_ramdisk, conf_fdt, 0, + 0); } return 0; @@ -1013,8 +1010,13 @@ int do_bootm_states(struct cmd_tbl *cmdtp, int flag, int argc, if (!ret && (states & BOOTM_STATE_FINDOS)) ret = bootm_find_os(cmdtp->name, argv[0]); - if (!ret && (states & BOOTM_STATE_FINDOTHER)) - ret = bootm_find_other(cmdtp, flag, argc, argv); + if (!ret && (states & BOOTM_STATE_FINDOTHER)) { + ulong img_addr; + + img_addr = argc ? hextoul(argv[0], NULL) : image_load_addr; + ret = bootm_find_other(img_addr, argc > 1 ? argv[1] : NULL, + argc > 2 ? argv[2] : NULL); + } if (IS_ENABLED(CONFIG_MEASURED_BOOT) && !ret && (states & BOOTM_STATE_MEASURE)) -- cgit v1.2.3 From 1047b5340c1203f825c0a68b33997b787be0123e Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 18 Nov 2023 14:05:19 -0700 Subject: bootstd: Introduce programmatic boot At present bootstd requires CONFIG_CMDLINE to operate. Add a new 'programmatic' boot which can be used when no command line is available. For now it does almost nothing, since most bootmeths require the command line. Signed-off-by: Simon Glass --- boot/Kconfig | 12 ++++++++++++ boot/Makefile | 2 ++ boot/prog_boot.c | 51 +++++++++++++++++++++++++++++++++++++++++++++++++++ common/main.c | 11 +++++++++++ include/bootstd.h | 9 +++++++++ 5 files changed, 85 insertions(+) create mode 100644 boot/prog_boot.c (limited to 'boot') diff --git a/boot/Kconfig b/boot/Kconfig index ef71883a502..b438002059c 100644 --- a/boot/Kconfig +++ b/boot/Kconfig @@ -459,6 +459,18 @@ config BOOTSTD_BOOTCOMMAND standard boot does not support all of the features of distro boot yet. +config BOOTSTD_PROG + bool "Use programmatic boot" + depends on !CMDLINE + default y + help + Enable this to provide a board_run_command() function which can boot + a systen without using commands. If the boot fails, then U-Boot will + panic. + + Note: This currently has many limitations and is not a useful booting + solution. Future work will eventually make this a viable option. + config BOOTMETH_GLOBAL bool help diff --git a/boot/Makefile b/boot/Makefile index 3fd048bb41a..de0eafed14b 100644 --- a/boot/Makefile +++ b/boot/Makefile @@ -25,6 +25,8 @@ 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 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 + */ + +#define LOG_CATEGORY UCLASS_BOOTSTD + +#include +#include +#include +#include + +/* + * 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/common/main.c b/common/main.c index 7c70de2e59a..6dba6cba144 100644 --- a/common/main.c +++ b/common/main.c @@ -9,6 +9,7 @@ #include #include #include +#include #include #include #include @@ -67,6 +68,16 @@ void main_loop(void) autoboot_command(s); + /* if standard boot if enabled, assume that it will be able to boot */ + if (IS_ENABLED(CONFIG_BOOTSTD_PROG)) { + int ret; + + ret = bootstd_prog_boot(); + printf("Standard boot failed (err=%dE)\n", ret); + panic("Failed to boot"); + } + cli_loop(); + panic("No CLI available"); } diff --git a/include/bootstd.h b/include/bootstd.h index 7802564bcc6..99ce7b64e7c 100644 --- a/include/bootstd.h +++ b/include/bootstd.h @@ -94,4 +94,13 @@ int bootstd_get_priv(struct bootstd_priv **stdp); */ void bootstd_clear_glob(void); +/** + * bootstd_prog_boot() - Run standard boot in a fully programmatic mode + * + * Attempts to boot without making any use of U-Boot commands + * + * Returns: -ve error value (does not return except on failure to boot) + */ +int bootstd_prog_boot(void); + #endif -- cgit v1.2.3 From 8632b36b96d38a85f2e71603a6f90ec9e4e5e37e Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 18 Nov 2023 14:05:20 -0700 Subject: command: Introduce functions to obtain command arguments Add some functions which provide an argument to a command, or NULL if the argument does not exist. Use the same numbering as argv[] since it seems less confusing than the previous idea. Signed-off-by: Simon Glass Suggested-by: Tom Rini --- boot/bootm.c | 4 ++-- cmd/booti.c | 4 ++-- cmd/bootz.c | 4 ++-- cmd/disk.c | 4 ++-- cmd/fuse.c | 2 +- cmd/mmc.c | 2 +- drivers/misc/gsc.c | 6 +++--- fs/fs.c | 4 ++-- include/command.h | 33 +++++++++++++++++++++++++++++++++ test/cmd_ut.c | 2 +- 10 files changed, 49 insertions(+), 16 deletions(-) (limited to 'boot') diff --git a/boot/bootm.c b/boot/bootm.c index 07aae26af01..a0d17be7742 100644 --- a/boot/bootm.c +++ b/boot/bootm.c @@ -1014,8 +1014,8 @@ int do_bootm_states(struct cmd_tbl *cmdtp, int flag, int argc, ulong img_addr; img_addr = argc ? hextoul(argv[0], NULL) : image_load_addr; - ret = bootm_find_other(img_addr, argc > 1 ? argv[1] : NULL, - argc > 2 ? argv[2] : NULL); + ret = bootm_find_other(img_addr, cmd_arg1(argc, argv), + cmd_arg2(argc, argv)); } if (IS_ENABLED(CONFIG_MEASURED_BOOT) && !ret && diff --git a/cmd/booti.c b/cmd/booti.c index dc73c83f0db..2db8f4a16ff 100644 --- a/cmd/booti.c +++ b/cmd/booti.c @@ -95,8 +95,8 @@ static int booti_start(struct cmd_tbl *cmdtp, int flag, int argc, * Handle the BOOTM_STATE_FINDOTHER state ourselves as we do not * have a header that provide this informaiton. */ - if (bootm_find_images(image_load_addr, argc > 1 ? argv[1] : NULL, - argc > 2 ? argv[2] : NULL, relocated_addr, + if (bootm_find_images(image_load_addr, cmd_arg1(argc, argv), + cmd_arg2(argc, argv), relocated_addr, image_size)) return 1; diff --git a/cmd/bootz.c b/cmd/bootz.c index bcf232b4f30..a652879ea5e 100644 --- a/cmd/bootz.c +++ b/cmd/bootz.c @@ -54,8 +54,8 @@ static int bootz_start(struct cmd_tbl *cmdtp, int flag, int argc, * Handle the BOOTM_STATE_FINDOTHER state ourselves as we do not * have a header that provide this informaiton. */ - if (bootm_find_images(image_load_addr, argc > 1 ? argv[1] : NULL, - argc > 2 ? argv[2] : NULL, images->ep, + if (bootm_find_images(image_load_addr, cmd_arg1(argc, argv), + cmd_arg2(argc, argv), images->ep, zi_end - zi_start)) return 1; diff --git a/cmd/disk.c b/cmd/disk.c index 3d7bc2f6018..92eaa02f4a1 100644 --- a/cmd/disk.c +++ b/cmd/disk.c @@ -40,8 +40,8 @@ int common_diskboot(struct cmd_tbl *cmdtp, const char *intf, int argc, bootstage_mark(BOOTSTAGE_ID_IDE_BOOT_DEVICE); - part = blk_get_device_part_str(intf, (argc == 3) ? argv[2] : NULL, - &dev_desc, &info, 1); + part = blk_get_device_part_str(intf, cmd_arg2(argc, argv), + &dev_desc, &info, 1); if (part < 0) { bootstage_error(BOOTSTAGE_ID_IDE_TYPE); return 1; diff --git a/cmd/fuse.c b/cmd/fuse.c index 0676bb7a812..f884c894fb0 100644 --- a/cmd/fuse.c +++ b/cmd/fuse.c @@ -44,7 +44,7 @@ static int confirm_prog(void) static int do_fuse(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) { - const char *op = argc >= 2 ? argv[1] : NULL; + const char *op = cmd_arg1(argc, argv); int confirmed = argc >= 3 && !strcmp(argv[2], "-y"); u32 bank, word, cnt, val, cmp; ulong addr; diff --git a/cmd/mmc.c b/cmd/mmc.c index 96befb27eec..2d5430a5307 100644 --- a/cmd/mmc.c +++ b/cmd/mmc.c @@ -946,7 +946,7 @@ static int do_mmc_partconf(struct cmd_tbl *cmdtp, int flag, } if (argc == 2 || argc == 3) - return mmc_partconf_print(mmc, argc == 3 ? argv[2] : NULL); + return mmc_partconf_print(mmc, cmd_arg2(argc, argv)); ack = dectoul(argv[2], NULL); part_num = dectoul(argv[3], NULL); diff --git a/drivers/misc/gsc.c b/drivers/misc/gsc.c index 65c9c2c6ce3..feb02f97065 100644 --- a/drivers/misc/gsc.c +++ b/drivers/misc/gsc.c @@ -531,10 +531,10 @@ static int do_gsc(struct cmd_tbl *cmdtp, int flag, int argc, char * const argv[] if (!gsc_wd_disable(dev)) return CMD_RET_SUCCESS; } else if (strcasecmp(argv[1], "thermal") == 0) { - char *cmd, *val; + const char *cmd, *val; - cmd = (argc > 2) ? argv[2] : NULL; - val = (argc > 3) ? argv[3] : NULL; + cmd = cmd_arg2(argc, argv); + val = cmd_arg3(argc, argv); if (!gsc_thermal(dev, cmd, val)) return CMD_RET_SUCCESS; } diff --git a/fs/fs.c b/fs/fs.c index 4cb4310c9cc..f33b85f92b6 100644 --- a/fs/fs.c +++ b/fs/fs.c @@ -749,7 +749,7 @@ int do_load(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[], if (argc > 7) return CMD_RET_USAGE; - if (fs_set_blk_dev(argv[1], (argc >= 3) ? argv[2] : NULL, fstype)) { + if (fs_set_blk_dev(argv[1], cmd_arg2(argc, argv), fstype)) { log_err("Can't set block device\n"); return 1; } @@ -818,7 +818,7 @@ int do_ls(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[], if (argc > 4) return CMD_RET_USAGE; - if (fs_set_blk_dev(argv[1], (argc >= 3) ? argv[2] : NULL, fstype)) + if (fs_set_blk_dev(argv[1], cmd_arg2(argc, argv), fstype)) return 1; if (fs_ls(argc >= 4 ? argv[3] : "/")) diff --git a/include/command.h b/include/command.h index 5bd3ecbe8f9..4cec6345453 100644 --- a/include/command.h +++ b/include/command.h @@ -60,6 +60,39 @@ struct cmd_tbl { #endif }; +/** + * cmd_arg_get() - Get a particular argument + * + * @argc: Number of arguments + * @argv: Argument vector of length @argc + * @argnum: Argument to get (0=first) + * Return: Pointer to argument @argnum if it exists, else NULL + */ +static inline const char *cmd_arg_get(int argc, char *const argv[], int argnum) +{ + return argc > argnum ? argv[argnum] : NULL; +} + +static inline const char *cmd_arg0(int argc, char *const argv[]) +{ + return cmd_arg_get(argc, argv, 0); +} + +static inline const char *cmd_arg1(int argc, char *const argv[]) +{ + return cmd_arg_get(argc, argv, 1); +} + +static inline const char *cmd_arg2(int argc, char *const argv[]) +{ + return cmd_arg_get(argc, argv, 2); +} + +static inline const char *cmd_arg3(int argc, char *const argv[]) +{ + return cmd_arg_get(argc, argv, 3); +} + #if defined(CONFIG_CMD_RUN) int do_run(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]); diff --git a/test/cmd_ut.c b/test/cmd_ut.c index 2d5b80f992e..2ead1c68e0e 100644 --- a/test/cmd_ut.c +++ b/test/cmd_ut.c @@ -45,7 +45,7 @@ int cmd_ut_category(const char *name, const char *prefix, } ret = ut_run_list(name, prefix, tests, n_ents, - argc > 1 ? argv[1] : NULL, runs_per_text, force_run, + cmd_arg1(argc, argv), runs_per_text, force_run, test_insert); return ret ? CMD_RET_FAILURE : 0; -- cgit v1.2.3