diff --git a/arch/arm/mach-stm32mp/cmd_stm32prog/cmd_stm32prog.c b/arch/arm/mach-stm32mp/cmd_stm32prog/cmd_stm32prog.c index 3627b4c35c..cb13a14d82 100644 --- a/arch/arm/mach-stm32mp/cmd_stm32prog/cmd_stm32prog.c +++ b/arch/arm/mach-stm32mp/cmd_stm32prog/cmd_stm32prog.c @@ -154,7 +154,7 @@ static int do_stm32prog(struct cmd_tbl *cmdtp, int flag, int argc, do_bootz(cmdtp, 0, 4, bootm_argv); } if (data->script) - image_source_script(data->script, NULL); + image_source_script(data->script, NULL, NULL); if (reset) { puts("Reset...\n"); diff --git a/boot/bootmeth_script.c b/boot/bootmeth_script.c index d1c3f94003..6c84721d1c 100644 --- a/boot/bootmeth_script.c +++ b/boot/bootmeth_script.c @@ -101,7 +101,7 @@ static int script_boot(struct udevice *dev, struct bootflow *bflow) log_debug("mmc_bootdev: %s\n", env_get("mmc_bootdev")); addr = map_to_sysmem(bflow->buf); - ret = image_source_script(addr, NULL); + ret = image_source_script(addr, NULL, NULL); if (ret) return log_msg_ret("boot", ret); diff --git a/cmd/source.c b/cmd/source.c index 5973824601..94da5d8d6a 100644 --- a/cmd/source.c +++ b/cmd/source.c @@ -42,7 +42,7 @@ static const char *get_default_image(const void *fit) } #endif -int image_source_script(ulong addr, const char *fit_uname) +int image_source_script(ulong addr, const char *fit_uname, const char *confname) { ulong len; #if defined(CONFIG_LEGACY_IMAGE_FORMAT) @@ -112,19 +112,47 @@ int image_source_script(ulong addr, const char *fit_uname) return 1; } - if (!fit_uname) - fit_uname = get_default_image(fit_hdr); - if (!fit_uname) { - puts("No FIT subimage unit name\n"); - return 1; - } + /* If confname is empty, use the default */ + if (confname && *confname) + noffset = fit_conf_get_node(fit_hdr, confname); + else + noffset = fit_conf_get_node(fit_hdr, NULL); + if (noffset < 0) { + if (!confname) + goto fallback; + printf("Could not find config %s\n", confname); + return 1; + } - /* get script component image node offset */ - noffset = fit_image_get_node (fit_hdr, fit_uname); - if (noffset < 0) { - printf ("Can't find '%s' FIT subimage\n", fit_uname); - return 1; + if (verify && fit_config_verify(fit_hdr, noffset)) + return 1; + + noffset = fit_conf_get_prop_node(fit_hdr, noffset, + FIT_SCRIPT_PROP, + IH_PHASE_NONE); + if (noffset < 0) { + if (!confname) + goto fallback; + printf("Could not find script in %s\n", confname); + return 1; + } + } else { +fallback: + if (!fit_uname || !*fit_uname) + fit_uname = get_default_image(fit_hdr); + if (!fit_uname) { + puts("No FIT subimage unit name\n"); + return 1; + } + + /* get script component image node offset */ + noffset = fit_image_get_node(fit_hdr, fit_uname); + if (noffset < 0) { + printf("Can't find '%s' FIT subimage\n", + fit_uname); + return 1; + } } if (!fit_image_check_type (fit_hdr, noffset, IH_TYPE_SCRIPT)) { @@ -164,7 +192,7 @@ static int do_source(struct cmd_tbl *cmdtp, int flag, int argc, { ulong addr; int rcode; - const char *fit_uname = NULL; + const char *fit_uname = NULL, *confname = NULL; /* Find script image */ if (argc < 2) { @@ -175,6 +203,9 @@ static int do_source(struct cmd_tbl *cmdtp, int flag, int argc, &fit_uname)) { debug("* source: subimage '%s' from FIT image at 0x%08lx\n", fit_uname, addr); + } else if (fit_parse_conf(argv[1], image_load_addr, &addr, &confname)) { + debug("* source: config '%s' from FIT image at 0x%08lx\n", + confname, addr); #endif } else { addr = hextoul(argv[1], NULL); @@ -182,21 +213,22 @@ static int do_source(struct cmd_tbl *cmdtp, int flag, int argc, } printf ("## Executing script at %08lx\n", addr); - rcode = image_source_script(addr, fit_uname); + rcode = image_source_script(addr, fit_uname, confname); return rcode; } #ifdef CONFIG_SYS_LONGHELP static char source_help_text[] = - "[addr]\n" - "\t- run script starting at addr\n" - "\t- A valid image header must be present" #if defined(CONFIG_FIT) - "\n" - "For FIT format uImage addr must include subimage\n" - "unit name in the form of addr:" + "[][:[]|#[]]\n" + "\t- Run script starting at addr\n" + "\t- A FIT config name or subimage name may be specified with : or #\n" + "\t (like bootm). If the image or config name is omitted, the\n" + "\t default is used."; +#else + "[]\n" + "\t- Run script starting at addr"; #endif - ""; #endif U_BOOT_CMD( diff --git a/doc/uImage.FIT/source_file_format.txt b/doc/uImage.FIT/source_file_format.txt index 4640e38e3c..269e1fa0b5 100644 --- a/doc/uImage.FIT/source_file_format.txt +++ b/doc/uImage.FIT/source_file_format.txt @@ -247,6 +247,7 @@ o config-1 |- kernel = "kernel sub-node unit name" |- fdt = "fdt sub-node unit-name" [, "fdt overlay sub-node unit-name", ...] |- loadables = "loadables sub-node unit-name" + |- script = " |- compatible = "vendor,board-style device tree compatible string" @@ -268,6 +269,8 @@ o config-1 of strings. U-Boot will load each binary at its given start-address and may optionally invoke additional post-processing steps on this binary based on its component image node type. + - script : The image to use when loading a U-Boot script (for use with the + source command). - compatible : The root compatible string of the U-Boot device tree that this configuration shall automatically match when CONFIG_FIT_BEST_MATCH is enabled. If this property is not provided, the compatible string will be diff --git a/drivers/usb/gadget/f_sdp.c b/drivers/usb/gadget/f_sdp.c index 1643d28947..5ae5b62741 100644 --- a/drivers/usb/gadget/f_sdp.c +++ b/drivers/usb/gadget/f_sdp.c @@ -868,7 +868,7 @@ static int sdp_handle_in_ep(struct spl_image_info *spl_image, jump_to_image_no_args(&spl_image); #else /* In U-Boot, allow jumps to scripts */ - image_source_script(sdp_func->jmp_address, NULL); + image_source_script(sdp_func->jmp_address, NULL, NULL); #endif } diff --git a/include/image.h b/include/image.h index 6f9c5a486b..bed75ce1b3 100644 --- a/include/image.h +++ b/include/image.h @@ -711,15 +711,23 @@ int fit_image_load(struct bootm_headers *images, ulong addr, /** * image_source_script() - Execute a script + * @addr: Address of script + * @fit_uname: FIT subimage name + * @confname: FIT config name. The subimage is chosen based on FIT_SCRIPT_PROP. * * Executes a U-Boot script at a particular address in memory. The script should * have a header (FIT or legacy) with the script type (IH_TYPE_SCRIPT). * - * @addr: Address of script - * @fit_uname: FIT subimage name + * If @fit_uname is the empty string, then the default image is used. If + * @confname is the empty string, the default config is used. If @confname and + * @fit_uname are both non-%NULL, then @confname is ignored. If @confname and + * @fit_uname are both %NULL, then first the default config is tried, and then + * the default image. + * * Return: result code (enum command_ret_t) */ -int image_source_script(ulong addr, const char *fit_uname); +int image_source_script(ulong addr, const char *fit_uname, + const char *confname); /** * fit_get_node_from_config() - Look up an image a FIT by type @@ -1032,6 +1040,7 @@ int booti_setup(ulong image, ulong *relocated_addr, ulong *size, #define FIT_FPGA_PROP "fpga" #define FIT_FIRMWARE_PROP "firmware" #define FIT_STANDALONE_PROP "standalone" +#define FIT_SCRIPT_PROP "script" #define FIT_PHASE_PROP "phase" #define FIT_MAX_HASH_LEN HASH_MAX_DIGEST_SIZE diff --git a/test/py/tests/test_source.py b/test/py/tests/test_source.py index e5ffdfe3fc..bbc311df6d 100644 --- a/test/py/tests/test_source.py +++ b/test/py/tests/test_source.py @@ -18,11 +18,20 @@ def test_source(u_boot_console): util.run_and_log(cons, (mkimage, '-f', its, fit)) cons.run_command(f'host load hostfs - $loadaddr {fit}') - assert '1' in cons.run_command('source') + assert '2' in cons.run_command('source') + assert '1' in cons.run_command('source :') assert '1' in cons.run_command('source :script-1') assert '2' in cons.run_command('source :script-2') assert 'Fail' in cons.run_command('source :not-a-script || echo Fail') + assert '2' in cons.run_command('source \\#') + assert '1' in cons.run_command('source \\#conf-1') + assert '2' in cons.run_command('source \\#conf-2') cons.run_command('fdt addr $loadaddr') + cons.run_command('fdt rm /configurations default') + assert '1' in cons.run_command('source') + assert 'Fail' in cons.run_command('source \\# || echo Fail') + cons.run_command('fdt rm /images default') assert 'Fail' in cons.run_command('source || echo Fail') + assert 'Fail' in cons.run_command('source \\# || echo Fail')