X-Git-Url: https://git.kernelconcepts.de/?a=blobdiff_plain;f=common%2Fcmd_bootm.c;h=a59ee95a698c014abe2a3ce7ce1cf16e98086088;hb=1b6102718bc5514cf974abeecebebe95c6a9ecc6;hp=02a5013c04186ad8b159886f3027b2535e576ef4;hpb=5a34d9bf31a021987f97f20aefa812b97b58584e;p=karo-tx-uboot.git diff --git a/common/cmd_bootm.c b/common/cmd_bootm.c index 02a5013c04..a59ee95a69 100644 --- a/common/cmd_bootm.c +++ b/common/cmd_bootm.c @@ -2,23 +2,7 @@ * (C) Copyright 2000-2009 * Wolfgang Denk, DENX Software Engineering, wd@denx.de. * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA + * SPDX-License-Identifier: GPL-2.0+ */ @@ -39,6 +23,11 @@ #include #include +#if defined(CONFIG_BOOTM_VXWORKS) && \ + (defined(CONFIG_PPC) || defined(CONFIG_ARM)) +#include +#endif + #if defined(CONFIG_CMD_USB) #include #endif @@ -93,6 +82,9 @@ static int do_imls(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]); static void fixup_silent_linux(void); #endif +static int do_bootm_standalone(int flag, int argc, char * const argv[], + bootm_headers_t *images); + static const void *boot_get_kernel(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[], bootm_headers_t *images, ulong *os_data, ulong *os_len); @@ -136,8 +128,11 @@ static boot_os_fn do_bootm_ose; #if defined(CONFIG_BOOTM_PLAN9) static boot_os_fn do_bootm_plan9; #endif -#if defined(CONFIG_CMD_ELF) +#if defined(CONFIG_BOOTM_VXWORKS) && \ + (defined(CONFIG_PPC) || defined(CONFIG_ARM)) static boot_os_fn do_bootm_vxworks; +#endif +#if defined(CONFIG_CMD_ELF) static boot_os_fn do_bootm_qnxelf; int do_bootvx(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]); int do_bootelf(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]); @@ -147,6 +142,7 @@ static boot_os_fn do_bootm_integrity; #endif static boot_os_fn *boot_os[] = { + [IH_OS_U_BOOT] = do_bootm_standalone, #ifdef CONFIG_BOOTM_LINUX [IH_OS_LINUX] = do_bootm_linux, #endif @@ -165,8 +161,11 @@ static boot_os_fn *boot_os[] = { #if defined(CONFIG_BOOTM_PLAN9) [IH_OS_PLAN9] = do_bootm_plan9, #endif -#if defined(CONFIG_CMD_ELF) +#if defined(CONFIG_BOOTM_VXWORKS) && \ + (defined(CONFIG_PPC) || defined(CONFIG_ARM)) [IH_OS_VXWORKS] = do_bootm_vxworks, +#endif +#if defined(CONFIG_CMD_ELF) [IH_OS_QNX] = do_bootm_qnxelf, #endif #ifdef CONFIG_INTEGRITY @@ -309,33 +308,54 @@ static int bootm_find_os(cmd_tbl_t *cmdtp, int flag, int argc, return 0; } -static int bootm_find_other(cmd_tbl_t *cmdtp, int flag, int argc, - char * const argv[]) +static int bootm_find_ramdisk(int flag, int argc, char * const argv[]) +{ + int ret; + + /* find ramdisk */ + ret = boot_get_ramdisk(argc, argv, &images, IH_INITRD_ARCH, + &images.rd_start, &images.rd_end); + if (ret) { + puts("Ramdisk image is corrupt or invalid\n"); + return 1; + } + + return 0; +} + +#if defined(CONFIG_OF_LIBFDT) +static int bootm_find_fdt(int flag, int argc, char * const argv[]) { int ret; + /* 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; + } + + set_working_fdt_addr(images.ft_addr); + + return 0; +} +#endif + +static int bootm_find_other(cmd_tbl_t *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)) { - /* find ramdisk */ - ret = boot_get_ramdisk(argc, argv, &images, IH_INITRD_ARCH, - &images.rd_start, &images.rd_end); - if (ret) { - puts("Ramdisk image is corrupt or invalid\n"); + (images.os.os == IH_OS_LINUX || + images.os.os == IH_OS_VXWORKS)) { + if (bootm_find_ramdisk(flag, argc, argv)) return 1; - } #if defined(CONFIG_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"); + if (bootm_find_fdt(flag, argc, argv)) return 1; - } - - set_working_fdt_addr(images.ft_addr); #endif } @@ -364,7 +384,7 @@ static int bootm_load_os(bootm_headers_t *images, unsigned long *load_end, const char *type_name = genimg_get_type_name(os.type); - load_buf = map_sysmem(load, image_len); + load_buf = map_sysmem(load, unc_len); image_buf = map_sysmem(image_start, image_len); switch (comp) { case IH_COMP_NONE: @@ -376,7 +396,6 @@ static int bootm_load_os(bootm_headers_t *images, unsigned long *load_end, memmove_wd(load_buf, image_buf, image_len, CHUNKSZ); } *load_end = load + image_len; - puts("OK\n"); break; #ifdef CONFIG_GZIP case IH_COMP_GZIP: @@ -433,11 +452,12 @@ static int bootm_load_os(bootm_headers_t *images, unsigned long *load_end, } #endif /* CONFIG_LZMA */ #ifdef CONFIG_LZO - case IH_COMP_LZO: + case IH_COMP_LZO: { + size_t size; + printf(" Uncompressing %s ... ", type_name); - ret = lzop_decompress(image_buf, image_len, load_buf, - &unc_len); + ret = lzop_decompress(image_buf, image_len, load_buf, &size); if (ret != LZO_E_OK) { printf("LZO: uncompress or overwrite error %d " "- must RESET board to recover\n", ret); @@ -446,8 +466,9 @@ static int bootm_load_os(bootm_headers_t *images, unsigned long *load_end, return BOOTM_ERR_RESET; } - *load_end = load + unc_len; + *load_end = load + size; break; + } #endif /* CONFIG_LZO */ default: printf("Unimplemented compression type %d\n", comp); @@ -482,17 +503,18 @@ static int bootm_load_os(bootm_headers_t *images, unsigned long *load_end, return 0; } -static int bootm_start_standalone(int argc, char * const argv[]) +static int do_bootm_standalone(int flag, int argc, char * const argv[], + bootm_headers_t *images) { char *s; int (*appl)(int, char * const []); /* Don't start if "autostart" is set to "no" */ if (((s = getenv("autostart")) != NULL) && (strcmp(s, "no") == 0)) { - setenv_hex("filesize", images.os.image_len); + setenv_hex("filesize", images->os.image_len); return 0; } - appl = (int (*)(int, char * const []))(ulong)ntohl(images.ep); + appl = (int (*)(int, char * const []))(ulong)ntohl(images->ep); (*appl)(argc, argv); return 0; } @@ -518,18 +540,12 @@ static cmd_tbl_t cmd_bootm_sub[] = { static int boot_selected_os(int argc, char * const argv[], int state, bootm_headers_t *images, boot_os_fn *boot_fn) { - if (images->os.type == IH_TYPE_STANDALONE) { - /* This may return when 'autostart' is 'no' */ - bootm_start_standalone(argc, argv); - return 0; - } -#ifdef CONFIG_SILENT_CONSOLE - if (images->os.os == IH_OS_LINUX) - fixup_silent_linux(); -#endif arch_preboot_os(); boot_fn(state, argc, argv, images); - if (state == BOOTM_STATE_OS_FAKE_GO) /* We expect to return */ + + /* Stand-alone may return when 'autostart' is 'no' */ + if (images->os.type == IH_TYPE_STANDALONE || + state == BOOTM_STATE_OS_FAKE_GO) /* We expect to return */ return 0; bootstage_error(BOOTSTAGE_ID_BOOT_OS_RETURNED); #ifdef DEBUG @@ -538,6 +554,43 @@ static int boot_selected_os(int argc, char * const argv[], int state, return BOOTM_ERR_RESET; } +/** + * bootm_disable_interrupts() - Disable interrupts in preparation for load/boot + * + * @return interrupt flag (0 if interrupts were disabled, non-zero if they were + * enabled) + */ +static ulong bootm_disable_interrupts(void) +{ + ulong iflag; + + /* + * We have reached the point of no return: we are going to + * overwrite all exception vector code, so we cannot easily + * recover from any failures any more... + */ + iflag = disable_interrupts(); +#ifdef CONFIG_NETCONSOLE + /* Stop the ethernet stack if NetConsole could have left it up */ + eth_halt(); + eth_unregister(eth_get_dev()); +#endif + +#if defined(CONFIG_CMD_USB) + /* + * turn off USB to prevent the host controller from writing to the + * SDRAM while Linux is booting. This could happen (at least for OHCI + * controller), because the HCCA (Host Controller Communication Area) + * lies within the SDRAM and the host controller writes continously to + * this area (as busmaster!). The HccaFrameNumber is for example + * updated every 1 ms within the HCCA structure in SDRAM! For more + * details see the OpenHCI specification. + */ + usb_stop(); +#endif + return iflag; +} + /** * Execute selected states of the bootm command. * @@ -569,7 +622,7 @@ static int do_bootm_states(cmd_tbl_t *cmdtp, int flag, int argc, { boot_os_fn *boot_fn; ulong iflag = 0; - int ret = 0; + int ret = 0, need_boot_fn; images->state |= states; @@ -588,43 +641,23 @@ static int do_bootm_states(cmd_tbl_t *cmdtp, int flag, int argc, argc = 0; /* consume the args */ } - /* - * We have reached the point of no return: we are going to - * overwrite all exception vector code, so we cannot easily - * recover from any failures any more... - */ - iflag = disable_interrupts(); -#ifdef CONFIG_NETCONSOLE - /* Stop the ethernet stack if NetConsole could have left it up */ - eth_halt(); -#endif - -#if defined(CONFIG_CMD_USB) - /* - * turn off USB to prevent the host controller from writing to the - * SDRAM while Linux is booting. This could happen (at least for OHCI - * controller), because the HCCA (Host Controller Communication Area) - * lies within the SDRAM and the host controller writes continously to - * this area (as busmaster!). The HccaFrameNumber is for example - * updated every 1 ms within the HCCA structure in SDRAM! For more - * details see the OpenHCI specification. - */ - usb_stop(); -#endif - /* Load the OS */ if (!ret && (states & BOOTM_STATE_LOADOS)) { ulong load_end; + iflag = bootm_disable_interrupts(); ret = bootm_load_os(images, &load_end, 0); - if (ret && ret != BOOTM_ERR_OVERLAP) - goto err; - if (ret == 0) lmb_reserve(&images->lmb, images->os.load, (load_end - images->os.load)); + else if (ret && ret != BOOTM_ERR_OVERLAP) + goto err; else if (ret == BOOTM_ERR_OVERLAP) ret = 0; +#if defined(CONFIG_SILENT_CONSOLE) && !defined(CONFIG_SILENT_U_BOOT_ONLY) + if (images->os.os == IH_OS_LINUX) + fixup_silent_linux(); +#endif } /* Relocate the ramdisk */ @@ -652,7 +685,10 @@ static int do_bootm_states(cmd_tbl_t *cmdtp, int flag, int argc, if (ret) return ret; boot_fn = boot_os[images->os.os]; - if (boot_fn == NULL) { + need_boot_fn = states & (BOOTM_STATE_OS_CMDLINE | + BOOTM_STATE_OS_BD_T | BOOTM_STATE_OS_PREP | + BOOTM_STATE_OS_FAKE_GO | BOOTM_STATE_OS_GO); + if (boot_fn == NULL && need_boot_fn) { if (iflag) enable_interrupts(); printf("ERROR: booting os '%s' (%d) is not supported\n", @@ -680,15 +716,17 @@ static int do_bootm_states(cmd_tbl_t *cmdtp, int flag, int argc, ret = run_command_list(cmd_list, -1, flag); } #endif + + /* Check for unsupported subcommand. */ + if (ret) { + puts("subcommand not supported\n"); + return ret; + } + /* Now run the OS! We hope this doesn't return */ - if (!ret && (states & BOOTM_STATE_OS_GO)) { + if (!ret && (states & BOOTM_STATE_OS_GO)) ret = boot_selected_os(argc, argv, BOOTM_STATE_OS_GO, images, boot_fn); - if (ret) - goto err; - } - - return ret; /* Deal with any fallout */ err: @@ -699,8 +737,6 @@ err: bootstage_error(BOOTSTAGE_ID_DECOMP_UNIMPL); else if (ret == BOOTM_ERR_RESET) do_reset(cmdtp, flag, argc, argv); - else - puts("subcommand not supported\n"); return ret; } @@ -779,8 +815,12 @@ int do_bootm(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) return do_bootm_states(cmdtp, flag, argc, argv, BOOTM_STATE_START | BOOTM_STATE_FINDOS | BOOTM_STATE_FINDOTHER | - BOOTM_STATE_LOADOS | BOOTM_STATE_OS_PREP | - BOOTM_STATE_OS_FAKE_GO | BOOTM_STATE_OS_GO, &images, 1); + BOOTM_STATE_LOADOS | +#if defined(CONFIG_PPC) || defined(CONFIG_MIPS) + BOOTM_STATE_OS_CMDLINE | +#endif + BOOTM_STATE_OS_PREP | BOOTM_STATE_OS_FAKE_GO | + BOOTM_STATE_OS_GO, &images, 1); } int bootm_maybe_autostart(cmd_tbl_t *cmdtp, const char *cmd) @@ -949,7 +989,7 @@ static const void *boot_get_kernel(cmd_tbl_t *cmdtp, int flag, int argc, case IMAGE_FORMAT_FIT: os_noffset = fit_image_load(images, FIT_KERNEL_PROP, img_addr, - &fit_uname_kernel, fit_uname_config, + &fit_uname_kernel, &fit_uname_config, IH_ARCH_DEFAULT, IH_TYPE_KERNEL, BOOTSTAGE_ID_FIT_KERNEL_START, FIT_LOAD_IGNORED, os_data, os_len); @@ -958,6 +998,7 @@ static const void *boot_get_kernel(cmd_tbl_t *cmdtp, int flag, int argc, 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 @@ -1365,9 +1406,19 @@ static void fixup_silent_linux(void) char *buf; const char *env_val; char *cmdline = getenv("bootargs"); + int want_silent; - /* Only fix cmdline when requested */ - if (!(gd->flags & GD_FLG_SILENT)) + /* + * Only fix cmdline when requested. The environment variable can be: + * + * no - we never fixup + * yes - we always fixup + * unset - we rely on the console silent flag + */ + want_silent = getenv_yesno("silent_linux"); + if (want_silent == 0) + return; + else if (want_silent == -1 && !(gd->flags & GD_FLG_SILENT)) return; debug("before silent fix-up: %s\n", cmdline); @@ -1433,8 +1484,8 @@ static int do_bootm_netbsd(int flag, int argc, char * const argv[], char *consdev; char *cmdline; - if ((flag != 0) && (flag != BOOTM_STATE_OS_GO)) - return 1; + if (flag != BOOTM_STATE_OS_GO) + return 0; #if defined(CONFIG_FIT) if (!images->legacy_hdr_valid) { @@ -1495,10 +1546,10 @@ static int do_bootm_netbsd(int flag, int argc, char * const argv[], /* * NetBSD Stage-2 Loader Parameters: - * r3: ptr to board info data - * r4: image address - * r5: console device - * r6: boot args string + * arg[0]: pointer to board info data + * arg[1]: image load address + * arg[2]: char pointer to the console device to use + * arg[3]: char pointer to the boot arguments */ (*loader)(gd->bd, os_hdr, consdev, cmdline); @@ -1512,8 +1563,8 @@ static int do_bootm_lynxkdi(int flag, int argc, char * const argv[], { image_header_t *hdr = &images->legacy_hdr_os_copy; - if ((flag != 0) && (flag != BOOTM_STATE_OS_GO)) - return 1; + if (flag != BOOTM_STATE_OS_GO) + return 0; #if defined(CONFIG_FIT) if (!images->legacy_hdr_valid) { @@ -1534,8 +1585,8 @@ static int do_bootm_rtems(int flag, int argc, char * const argv[], { void (*entry_point)(bd_t *); - if ((flag != 0) && (flag != BOOTM_STATE_OS_GO)) - return 1; + if (flag != BOOTM_STATE_OS_GO) + return 0; #if defined(CONFIG_FIT) if (!images->legacy_hdr_valid) { @@ -1567,8 +1618,8 @@ static int do_bootm_ose(int flag, int argc, char * const argv[], { void (*entry_point)(void); - if ((flag != 0) && (flag != BOOTM_STATE_OS_GO)) - return 1; + if (flag != BOOTM_STATE_OS_GO) + return 0; #if defined(CONFIG_FIT) if (!images->legacy_hdr_valid) { @@ -1601,8 +1652,8 @@ static int do_bootm_plan9(int flag, int argc, char * const argv[], void (*entry_point)(void); char *s; - if ((flag != 0) && (flag != BOOTM_STATE_OS_GO)) - return 1; + if (flag != BOOTM_STATE_OS_GO) + return 0; #if defined(CONFIG_FIT) if (!images->legacy_hdr_valid) { @@ -1642,14 +1693,68 @@ static int do_bootm_plan9(int flag, int argc, char * const argv[], } #endif /* CONFIG_BOOTM_PLAN9 */ -#if defined(CONFIG_CMD_ELF) +#if defined(CONFIG_BOOTM_VXWORKS) && \ + (defined(CONFIG_PPC) || defined(CONFIG_ARM)) + +void do_bootvx_fdt(bootm_headers_t *images) +{ +#if defined(CONFIG_OF_LIBFDT) + int ret; + char *bootline; + ulong of_size = images->ft_len; + char **of_flat_tree = &images->ft_addr; + struct lmb *lmb = &images->lmb; + + if (*of_flat_tree) { + boot_fdt_add_mem_rsv_regions(lmb, *of_flat_tree); + + ret = boot_relocate_fdt(lmb, of_flat_tree, &of_size); + if (ret) + return; + + ret = fdt_add_subnode(*of_flat_tree, 0, "chosen"); + if ((ret >= 0 || ret == -FDT_ERR_EXISTS)) { + bootline = getenv("bootargs"); + if (bootline) { + ret = fdt_find_and_setprop(*of_flat_tree, + "/chosen", "bootargs", + bootline, + strlen(bootline) + 1, 1); + if (ret < 0) { + printf("## ERROR: %s : %s\n", __func__, + fdt_strerror(ret)); + return; + } + } + } else { + printf("## ERROR: %s : %s\n", __func__, + fdt_strerror(ret)); + return; + } + } +#endif + + boot_prep_vxworks(images); + + bootstage_mark(BOOTSTAGE_ID_RUN_OS); + +#if defined(CONFIG_OF_LIBFDT) + printf("## Starting vxWorks at 0x%08lx, device tree at 0x%08lx ...\n", + (ulong)images->ep, (ulong)*of_flat_tree); +#else + printf("## Starting vxWorks at 0x%08lx\n", (ulong)images->ep); +#endif + + boot_jump_vxworks(images); + + puts("## vxWorks terminated\n"); +} + static int do_bootm_vxworks(int flag, int argc, char * const argv[], bootm_headers_t *images) { - char str[80]; - - if ((flag != 0) && (flag != BOOTM_STATE_OS_GO)) - return 1; + if (flag != BOOTM_STATE_OS_GO) + return 0; #if defined(CONFIG_FIT) if (!images->legacy_hdr_valid) { @@ -1658,21 +1763,21 @@ static int do_bootm_vxworks(int flag, int argc, char * const argv[], } #endif - sprintf(str, "%lx", images->ep); /* write entry-point into string */ - setenv("loadaddr", str); - do_bootvx(NULL, 0, 0, NULL); + do_bootvx_fdt(images); return 1; } +#endif +#if defined(CONFIG_CMD_ELF) static int do_bootm_qnxelf(int flag, int argc, char * const argv[], bootm_headers_t *images) { char *local_args[2]; char str[16]; - if ((flag != 0) && (flag != BOOTM_STATE_OS_GO)) - return 1; + if (flag != BOOTM_STATE_OS_GO) + return 0; #if defined(CONFIG_FIT) if (!images->legacy_hdr_valid) { @@ -1696,8 +1801,8 @@ static int do_bootm_integrity(int flag, int argc, char * const argv[], { void (*entry_point)(void); - if ((flag != 0) && (flag != BOOTM_STATE_OS_GO)) - return 1; + if (flag != BOOTM_STATE_OS_GO) + return 0; #if defined(CONFIG_FIT) if (!images->legacy_hdr_valid) { @@ -1725,15 +1830,13 @@ static int do_bootm_integrity(int flag, int argc, char * const argv[], #ifdef CONFIG_CMD_BOOTZ -static int __bootz_setup(void *image, void **start, void **end) +int __weak bootz_setup(ulong image, ulong *start, ulong *end) { /* Please define bootz_setup() for your platform */ puts("Your platform's zImage format isn't supported yet!\n"); return -1; } -int bootz_setup(void *image, void **start, void **end) - __attribute__((weak, alias("__bootz_setup"))); /* * zImage booting support @@ -1742,44 +1845,63 @@ static int bootz_start(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[], bootm_headers_t *images) { int ret; - void *zi_start, *zi_end; + ulong zi_start, zi_end; ret = do_bootm_states(cmdtp, flag, argc, argv, BOOTM_STATE_START, images, 1); /* Setup Linux kernel zImage entry point */ - if (argc < 2) { + if (!argc) { images->ep = load_addr; debug("* kernel: default image load address = 0x%08lx\n", load_addr); } else { - images->ep = simple_strtoul(argv[1], NULL, 16); + images->ep = simple_strtoul(argv[0], NULL, 16); debug("* kernel: cmdline image address = 0x%08lx\n", images->ep); } - ret = bootz_setup((void *)images->ep, &zi_start, &zi_end); + ret = bootz_setup(images->ep, &zi_start, &zi_end); if (ret != 0) return 1; lmb_reserve(&images->lmb, images->ep, zi_end - zi_start); - ret = do_bootm_states(cmdtp, flag, argc, argv, BOOTM_STATE_FINDOTHER, - images, 1); + /* + * Handle the BOOTM_STATE_FINDOTHER state ourselves as we do not + * have a header that provide this informaiton. + */ + if (bootm_find_ramdisk(flag, argc, argv)) + return 1; - return ret; +#if defined(CONFIG_OF_LIBFDT) + if (bootm_find_fdt(flag, argc, argv)) + return 1; +#endif + + return 0; } int do_bootz(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { - bootm_headers_t images; int ret; + /* Consume 'bootz' */ + argc--; argv++; + if (bootz_start(cmdtp, flag, argc, argv, &images)) return 1; + /* + * We are doing the BOOTM_STATE_LOADOS state ourselves, so must + * disable interrupts ourselves + */ + bootm_disable_interrupts(); + + images.os.os = IH_OS_LINUX; ret = do_bootm_states(cmdtp, flag, argc, argv, - BOOTM_STATE_OS_FAKE_GO | BOOTM_STATE_OS_GO, + BOOTM_STATE_OS_PREP | BOOTM_STATE_OS_FAKE_GO | + BOOTM_STATE_OS_GO, &images, 1); return ret;