diff --git a/boot/bootm.c b/boot/bootm.c index 3431652e072..46320363270 100644 --- a/boot/bootm.c +++ b/boot/bootm.c @@ -257,6 +257,16 @@ static int bootm_start(void) return 0; } +static int bootm_restart(void) +{ + images.no_os = false; + + bootstage_mark_name(BOOTSTAGE_ID_BOOTM_RESTART, "bootm_restart"); + images.state = BOOTM_STATE_START; + + return 0; +} + static ulong bootm_data_addr(const char *addr_str) { ulong addr; @@ -1059,6 +1069,9 @@ int bootm_run_states(struct bootm_info *bmi, int states) if (states & BOOTM_STATE_START) ret = bootm_start(); + if (states & BOOTM_STATE_RESTART) + ret = bootm_restart(); + if (!ret && (states & BOOTM_STATE_PRE_LOAD)) ret = bootm_pre_load(bmi->addr_img); diff --git a/cmd/bootm.c b/cmd/bootm.c index bee683d0580..23b3d56c101 100644 --- a/cmd/bootm.c +++ b/cmd/bootm.c @@ -41,6 +41,7 @@ static int do_imls(struct cmd_tbl *cmdtp, int flag, int argc, * function pointer */ static struct cmd_tbl cmd_bootm_sub[] = { U_BOOT_CMD_MKENT(start, 0, 1, (void *)BOOTM_STATE_START, "", ""), + U_BOOT_CMD_MKENT(restart, 0, 1, (void *)BOOTM_STATE_RESTART, "", ""), U_BOOT_CMD_MKENT(loados, 0, 1, (void *)BOOTM_STATE_LOADOS, "", ""), #ifdef CONFIG_CMD_BOOTM_PRE_LOAD U_BOOT_CMD_MKENT(preload, 0, 1, (void *)BOOTM_STATE_PRE_LOAD, "", ""), @@ -85,7 +86,9 @@ static int do_bootm_subcommand(struct cmd_tbl *cmdtp, int flag, int argc, if (c) { state = (long)c->cmd; - if (state == BOOTM_STATE_START) + if (state == BOOTM_STATE_RESTART) + images.state = BOOTM_STATE_START; + if (state == BOOTM_STATE_START || state == BOOTM_STATE_RESTART) state |= BOOTM_STATE_PRE_LOAD | BOOTM_STATE_FINDOS | BOOTM_STATE_FINDOTHER; #if defined(CONFIG_CMD_BOOTM_PRE_LOAD) diff --git a/doc/usage/cmd/bootm.rst b/doc/usage/cmd/bootm.rst index 1f59895568e..5af331873ce 100644 --- a/doc/usage/cmd/bootm.rst +++ b/doc/usage/cmd/bootm.rst @@ -11,8 +11,8 @@ Synopsis :: - bootm [start] []#[#] - bootm [start] [[]:] [[]:] [[]:] + bootm [start|restart] []#[#] + bootm [start|restart] [[]:] [[]:] [[]:] bootm bootm [[ []] # Legacy boot @@ -64,6 +64,14 @@ The states are described below: start Start the boot process afresh, recording the image(s) to be booted. +restart + Start the boot process again, but keeping the current state. This allows + multiple FITs to be loaded, for example a first FIT containing just the + devicetree and a second containing the OS and any overlays. In this case, + the first `bootm` command will typically use only `start` (and its implicit + states) and `loados`, with the second using `bootm restart` to select the + second FIT. + preload Deal with any preload step, sometimes used to do a full signature check of the FIT, before looking at any of the data within. diff --git a/include/bootstage.h b/include/bootstage.h index 9471c5d770f..ad98bffedc3 100644 --- a/include/bootstage.h +++ b/include/bootstage.h @@ -189,6 +189,7 @@ enum bootstage_id { BOOTSTAGE_ID_BOOTP_START, BOOTSTAGE_ID_BOOTP_STOP, BOOTSTAGE_ID_BOOTM_START, + BOOTSTAGE_ID_BOOTM_RESTART, BOOTSTAGE_ID_BOOTM_HANDOFF, BOOTSTAGE_ID_MAIN_LOOP, BOOTSTAGE_ID_ENTER_CLI_LOOP, diff --git a/include/image.h b/include/image.h index 46b91888f5b..7576ffa1048 100644 --- a/include/image.h +++ b/include/image.h @@ -349,6 +349,7 @@ struct image_info { * enum bootm_state - States which the bootm machine goes through (in order) * * @BOOTM_STATE_START: Set up the state structure (struct bootm_headers) + * @BOOTM_STATE_RESTART: Restart the boot, keeping the existing state * @BOOTM_STATE_PRE_LOAD: Do any neceessary processing before images are read. * For now this just implements a whole-image signature, if enabled. See * CONFIG_IMAGE_PRE_LOAD_SIG @@ -398,6 +399,7 @@ enum bootm_state { BOOTM_STATE_OS_PREP = BIT(10), BOOTM_STATE_OS_FAKE_GO = BIT(11), BOOTM_STATE_OS_GO = BIT(12), + BOOTM_STATE_RESTART = BIT(13), }; /*