
Normally bootm proceeds sequentially through the various states, from 'start' to 'go'. In some cases we want to load the devicetree from one FIT and the kernel and ramdisk from another. This requires two bootm commands. Of course it is possible to just do a second 'bootm start' to load the kernel. But that removes all record of the devicetree from the boot_images information, so it is then not provided to the OS. Add a 'restart' subcommand which allows more images to be loaded, without erasing those already loaded. Signed-off-by: Simon Glass <sjg@chromium.org> --- boot/bootm.c | 13 +++++++++++++ cmd/bootm.c | 5 ++++- doc/usage/cmd/bootm.rst | 12 ++++++++++-- include/bootstage.h | 1 + include/image.h | 2 ++ 5 files changed, 30 insertions(+), 3 deletions(-) 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] [<fit_addr>]#<conf>[#<extra-conf>] - bootm [start] [[<fit_addr>]:<os_subimg>] [[<fit_addr2>]:<rd_subimg2>] [[<fit_addr3>]:<fdt_subimg>] + bootm [start|restart] [<fit_addr>]#<conf>[#<extra-conf>] + bootm [start|restart] [[<fit_addr>]:<os_subimg>] [[<fit_addr2>]:<rd_subimg2>] [[<fit_addr3>]:<fdt_subimg>] bootm <subcmd> bootm <addr1> [[<addr2> [<addr3>]] # 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), }; /* -- 2.43.0