diff --git a/README b/README index 00d422737fb..ab4cda54d2b 100644 --- a/README +++ b/README @@ -1544,16 +1544,26 @@ Low Level (hardware related) configuration options: globally (CONFIG_CMD_MEMORY). - CONFIG_SPL_BUILD - Set when the currently-running compilation is for an artifact - that will end up in the SPL (as opposed to the TPL or U-Boot - proper). Code that needs stage-specific behavior should check - this. + Set when the currently running compilation is for an artifact + that will end up in one of the 'xPL' builds, i.e. SPL, TPL or + VPL. Code that needs phase-specific behaviour can check this, + or (where possible) use spl_phase() instead. + + Note that CONFIG_SPL_BUILD *is* always defined when either + of CONFIG_TPL_BUILD / CONFIG_VPL_BUILD is defined. This can be + counter-intuitive and should perhaps be changed. - CONFIG_TPL_BUILD - Set when the currently-running compilation is for an artifact - that will end up in the TPL (as opposed to the SPL or U-Boot - proper). Code that needs stage-specific behavior should check - this. + Set when the currently running compilation is for an artifact + that will end up in the TPL build (as opposed to SPL, VPL or + U-Boot proper). Code that needs phase-specific behaviour can + check this, or (where possible) use spl_phase() instead. + +- CONFIG_VPL_BUILD + Set when the currently running compilation is for an artifact + that will end up in the VPL build (as opposed to the SPL, TPL + or U-Boot proper). Code that needs phase-specific behaviour can + check this, or (where possible) use spl_phase() instead. - CONFIG_ARCH_MAP_SYSMEM Generally U-Boot (and in particular the md command) uses diff --git a/arch/arm/cpu/u-boot.lds b/arch/arm/cpu/u-boot.lds index fc4f63d8348..7724c9332c3 100644 --- a/arch/arm/cpu/u-boot.lds +++ b/arch/arm/cpu/u-boot.lds @@ -14,9 +14,6 @@ OUTPUT_ARCH(arm) ENTRY(_start) SECTIONS { -#ifndef CONFIG_CMDLINE - /DISCARD/ : { *(__u_boot_list_2_cmd_*) } -#endif #if defined(CONFIG_ARMV7_SECURE_BASE) && defined(CONFIG_ARMV7_NONSEC) /* * If CONFIG_ARMV7_SECURE_BASE is true, secure code will not diff --git a/arch/x86/cpu/u-boot-64.lds b/arch/x86/cpu/u-boot-64.lds index d0398ff00d7..00a6d869121 100644 --- a/arch/x86/cpu/u-boot-64.lds +++ b/arch/x86/cpu/u-boot-64.lds @@ -11,10 +11,6 @@ ENTRY(_start) SECTIONS { -#ifndef CONFIG_CMDLINE - /DISCARD/ : { *(__u_boot_list_2_cmd_*) } -#endif - #ifdef CONFIG_TEXT_BASE . = CONFIG_TEXT_BASE; /* Location of bootcode in flash */ #endif diff --git a/arch/x86/cpu/u-boot-spl.lds b/arch/x86/cpu/u-boot-spl.lds index a0a2a06a18c..50b4b160855 100644 --- a/arch/x86/cpu/u-boot-spl.lds +++ b/arch/x86/cpu/u-boot-spl.lds @@ -11,10 +11,6 @@ ENTRY(_start) SECTIONS { -#ifndef CONFIG_CMDLINE - /DISCARD/ : { *(__u_boot_list_2_cmd_*) } -#endif - . = IMAGE_TEXT_BASE; /* Location of bootcode in flash */ __text_start = .; .text : { diff --git a/arch/x86/cpu/u-boot.lds b/arch/x86/cpu/u-boot.lds index a31f4220a00..c418ff44aa0 100644 --- a/arch/x86/cpu/u-boot.lds +++ b/arch/x86/cpu/u-boot.lds @@ -11,10 +11,6 @@ ENTRY(_start) SECTIONS { -#ifndef CONFIG_CMDLINE - /DISCARD/ : { *(__u_boot_list_2_cmd_*) } -#endif - . = CONFIG_TEXT_BASE; /* Location of bootcode in flash */ __text_start = .; diff --git a/board/freescale/common/vid.c b/board/freescale/common/vid.c index 5ec3f2a76b1..fc5d400cfe1 100644 --- a/board/freescale/common/vid.c +++ b/board/freescale/common/vid.c @@ -793,4 +793,4 @@ U_BOOT_CMD( vdd_read, 1, 0, do_vdd_read, "read VDD", " - Read the voltage specified in mV" -) +); diff --git a/board/xilinx/common/fru.c b/board/xilinx/common/fru.c index c916c3d6b4c..12b21317496 100644 --- a/board/xilinx/common/fru.c +++ b/board/xilinx/common/fru.c @@ -85,4 +85,4 @@ U_BOOT_CMD( fru, 8, 1, do_fru, "FRU table info", fru_help_text -) +); diff --git a/board/xilinx/versal/cmds.c b/board/xilinx/versal/cmds.c index 9cc2cdcebf1..2a74e49aede 100644 --- a/board/xilinx/versal/cmds.c +++ b/board/xilinx/versal/cmds.c @@ -98,4 +98,4 @@ U_BOOT_LONGHELP(versal, U_BOOT_CMD(versal, 4, 1, do_versal, "versal sub-system", versal_help_text -) +); diff --git a/board/xilinx/zynqmp/cmds.c b/board/xilinx/zynqmp/cmds.c index f1f3eff501e..9524688f27d 100644 --- a/board/xilinx/zynqmp/cmds.c +++ b/board/xilinx/zynqmp/cmds.c @@ -427,4 +427,4 @@ U_BOOT_CMD( zynqmp, 9, 1, do_zynqmp, "ZynqMP sub-system", zynqmp_help_text -) +); 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/bootm.c b/boot/bootm.c index cb61485c226..a0d17be7742 100644 --- a/boot/bootm.c +++ b/boot/bootm.c @@ -44,14 +44,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 +255,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 +268,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 +304,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 +322,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; } @@ -266,30 +469,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 + * check_overlap() - Check if an image overlaps the OS * - * 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 + * @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 +528,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 +562,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 +572,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; } @@ -783,16 +1002,21 @@ 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(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); + if (!ret && (states & BOOTM_STATE_FINDOTHER)) { + ulong img_addr; + + img_addr = argc ? hextoul(argv[0], NULL) : image_load_addr; + ret = bootm_find_other(img_addr, cmd_arg1(argc, argv), + cmd_arg2(argc, argv)); + } if (IS_ENABLED(CONFIG_MEASURED_BOOT) && !ret && (states & BOOTM_STATE_MEASURE)) @@ -934,193 +1158,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 * diff --git a/boot/bootm_os.c b/boot/bootm_os.c index 30296eb27d7..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); } @@ -486,18 +476,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) { diff --git a/boot/image-board.c b/boot/image-board.c index d500da1b4b9..bb0ca9d7f22 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); diff --git a/boot/image-fdt.c b/boot/image-fdt.c index f10200f6474..08fca08b710 100644 --- a/boot/image-fdt.c +++ b/boot/image-fdt.c @@ -447,45 +447,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; 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/cmd/booti.c b/cmd/booti.c index a6c7db272c5..2db8f4a16ff 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, cmd_arg1(argc, argv), + cmd_arg2(argc, argv), relocated_addr, + image_size)) return 1; return 0; diff --git a/cmd/bootz.c b/cmd/bootz.c index dd6fe4904b0..a652879ea5e 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, cmd_arg1(argc, argv), + cmd_arg2(argc, argv), images->ep, + zi_end - zi_start)) return 1; return 0; diff --git a/cmd/btrfs.c b/cmd/btrfs.c index 98daea99e9e..2843835d08b 100644 --- a/cmd/btrfs.c +++ b/cmd/btrfs.c @@ -24,4 +24,4 @@ U_BOOT_CMD(btrsubvol, 3, 1, do_btrsubvol, "list subvolumes of a BTRFS filesystem", " \n" " - List subvolumes of a BTRFS filesystem." -) +); 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/eeprom.c b/cmd/eeprom.c index 0b6ca8c505f..322765ad02a 100644 --- a/cmd/eeprom.c +++ b/cmd/eeprom.c @@ -435,4 +435,4 @@ U_BOOT_CMD( "The values which can be provided with the -l option are:\n" CONFIG_EEPROM_LAYOUT_HELP_STRING"\n" #endif -) +); diff --git a/cmd/ext2.c b/cmd/ext2.c index 57a99516a6a..a0ce0cf5796 100644 --- a/cmd/ext2.c +++ b/cmd/ext2.c @@ -42,7 +42,7 @@ U_BOOT_CMD( "list files in a directory (default /)", " [directory]\n" " - list files from 'dev' on 'interface' in a 'directory'" -) +); U_BOOT_CMD( ext2load, 6, 0, do_ext2load, @@ -50,4 +50,4 @@ U_BOOT_CMD( " [ [addr [filename [bytes [pos]]]]]\n" " - load binary file 'filename' from 'dev' on 'interface'\n" " to address 'addr' from ext2 filesystem." -) +); diff --git a/cmd/fs.c b/cmd/fs.c index 6044f73af5b..46cb43dcdb5 100644 --- a/cmd/fs.c +++ b/cmd/fs.c @@ -39,7 +39,7 @@ U_BOOT_CMD( " If 'bytes' is 0 or omitted, the file is read until the end.\n" " 'pos' gives the file byte position to start reading from.\n" " If 'pos' is 0 or omitted, the file is read from the start." -) +); static int do_save_wrapper(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) @@ -56,7 +56,7 @@ U_BOOT_CMD( " 'bytes' gives the size to save in bytes and is mandatory.\n" " 'pos' gives the file byte position to start writing to.\n" " If 'pos' is 0 or omitted, the file is written from the start." -) +); static int do_ls_wrapper(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) @@ -70,7 +70,7 @@ U_BOOT_CMD( " [ [directory]]\n" " - List files in directory 'directory' of partition 'part' on\n" " device type 'interface' instance 'dev'." -) +); static int do_ln_wrapper(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) @@ -84,7 +84,7 @@ U_BOOT_CMD( " target linkname\n" " - create a symbolic link to 'target' with the name 'linkname' on\n" " device type 'interface' instance 'dev'." -) +); static int do_fstype_wrapper(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) 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/cmd/pinmux.c b/cmd/pinmux.c index f17cf4110d9..105f01eaaff 100644 --- a/cmd/pinmux.c +++ b/cmd/pinmux.c @@ -178,4 +178,4 @@ U_BOOT_CMD(pinmux, CONFIG_SYS_MAXARGS, 1, do_pinmux, "list - list UCLASS_PINCTRL devices\n" "pinmux dev [pincontroller-name] - select pin-controller device\n" "pinmux status [-a | pin-name] - print pin-controller muxing [for all | for pin-name]\n" -) +); diff --git a/cmd/qfw.c b/cmd/qfw.c index d6ecfa60d5a..1b8c775ebf5 100644 --- a/cmd/qfw.c +++ b/cmd/qfw.c @@ -121,4 +121,4 @@ U_BOOT_CMD( " - list : print firmware(s) currently loaded\n" " - cpus : print online cpu number\n" " - load : load kernel and initrd (if any), and setup for zboot\n" -) +); 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/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/env/mmc.c b/env/mmc.c index cb14bbb58f1..da84cddd74f 100644 --- a/env/mmc.c +++ b/env/mmc.c @@ -495,7 +495,7 @@ U_BOOT_ENV_LOCATION(mmc) = { .location = ENVL_MMC, ENV_NAME("MMC") .load = env_mmc_load, -#ifndef CONFIG_SPL_BUILD +#if defined(CONFIG_CMD_SAVEENV) && !defined(CONFIG_SPL_BUILD) .save = env_save_ptr(env_mmc_save), .erase = ENV_ERASE_PTR(env_mmc_erase) #endif 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/bootdev.h b/include/bootdev.h index 35fa25aff1d..2cee8832d26 100644 --- a/include/bootdev.h +++ b/include/bootdev.h @@ -7,6 +7,7 @@ #ifndef __bootdev_h #define __bootdev_h +#include #include struct bootflow; 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 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, 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 diff --git a/include/command.h b/include/command.h index 6262365e128..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[]); @@ -390,7 +423,7 @@ int cmd_source_script(ulong addr, const char *fit_uname, const char *confname); #define U_BOOT_CMD_COMPLETE(_name, _maxargs, _rep, _cmd, _usage, _help, _comp) \ ll_entry_declare(struct cmd_tbl, _name, cmd) = \ U_BOOT_CMD_MKENT_COMPLETE(_name, _maxargs, _rep, _cmd, \ - _usage, _help, _comp); + _usage, _help, _comp) #define U_BOOT_CMDREP_COMPLETE(_name, _maxargs, _cmd_rep, _usage, \ _help, _comp) \ diff --git a/include/fdt_support.h b/include/fdt_support.h index 2cd83668982..feda0d99740 100644 --- a/include/fdt_support.h +++ b/include/fdt_support.h @@ -7,8 +7,7 @@ #ifndef __FDT_SUPPORT_H #define __FDT_SUPPORT_H -#if (defined(CONFIG_OF_LIBFDT) || defined(CONFIG_OF_CONTROL)) && \ - !defined(USE_HOSTCC) +#if !defined(USE_HOSTCC) #include #include @@ -418,7 +417,7 @@ int fdt_valid(struct fdt_header **blobp); */ int fdt_get_cells_len(const void *blob, char *nr_cells_name); -#endif /* ifdef CONFIG_OF_LIBFDT */ +#endif /* !USE_HOSTCC */ #ifdef USE_HOSTCC int fdtdec_get_int(const void *blob, int node, const char *prop_name, diff --git a/include/image.h b/include/image.h index 2e3cf839ee3..b89912a50f9 100644 --- a/include/image.h +++ b/include/image.h @@ -612,41 +612,86 @@ 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); -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_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_loadable - routine to load a list of binaries to memory - * @argc: Ignored Argument - * @argv: Ignored Argument + * 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 architecture for the image - * @ld_start: Ignored Argument - * @ld_len: Ignored Argument + * @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_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: + * 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() - load a list of binaries to memory + * + * @images: pointer to the bootm images structure + * + * 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); @@ -705,7 +750,13 @@ int boot_get_fdt_fit(struct bootm_headers *images, ulong addr, * @param load_op Decribes what to do with the load address * @param datap Returns address of loaded image * @param lenp Returns length of loaded image - * Return: node offset of image, or -ve error code on error + * Return: node offset of image, or -ve error code on error: + * -ENOEXEC - unsupported architecture + * -ENOENT - could not find image / subimage + * -EACCES - hash, signature or decryptions failure + * -EBADF - invalid OS or image type, or cannot get image load-address + * -EXDEV - memory overwritten / overlap + * -NOEXEC - image decompression error, or invalid FDT */ int fit_image_load(struct bootm_headers *images, ulong addr, const char **fit_unamep, const char **fit_uname_configp, @@ -756,9 +807,33 @@ 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 + * @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 + * @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, const char *select, 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); 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;