Commit b639640371ed38c76602387af865b814967473ba

Authored by Simon Glass
Committed by Tom Rini
1 parent 12df2abe3e

bootm: Split out code from cmd_bootm.c

This file has code in three different categories:
- Command processing
- OS-specific boot code
- Locating images and setting up to boot

Only the first category really belongs in a file called cmd_bootm.c.

Leave the command processing code where it is. Split out the OS-specific
boot code into bootm_os.c. Split out the other code into bootm.c

Header files and extern declarations are tidied but otherwise no code
changes are made, to make it easier to review.

Signed-off-by: Simon Glass <sjg@chromium.org>

Showing 5 changed files with 1356 additions and 1338 deletions Side-by-side Diff

... ... @@ -40,7 +40,7 @@
40 40  
41 41 # core command
42 42 obj-y += cmd_boot.o
43   -obj-$(CONFIG_CMD_BOOTM) += cmd_bootm.o
  43 +obj-$(CONFIG_CMD_BOOTM) += cmd_bootm.o bootm.o bootm_os.o
44 44 obj-y += cmd_help.o
45 45 obj-y += cmd_version.o
46 46  
  1 +/*
  2 + * (C) Copyright 2000-2009
  3 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
  4 + *
  5 + * SPDX-License-Identifier: GPL-2.0+
  6 + */
  7 +
  8 +#include <common.h>
  9 +#include <bootm.h>
  10 +#include <bzlib.h>
  11 +#include <image.h>
  12 +#include <fdt_support.h>
  13 +#include <lmb.h>
  14 +#include <malloc.h>
  15 +#include <asm/io.h>
  16 +#include <linux/lzo.h>
  17 +#include <lzma/LzmaTypes.h>
  18 +#include <lzma/LzmaDec.h>
  19 +#include <lzma/LzmaTools.h>
  20 +
  21 +#if defined(CONFIG_CMD_USB)
  22 +#include <usb.h>
  23 +#endif
  24 +
  25 +DECLARE_GLOBAL_DATA_PTR;
  26 +
  27 +#ifndef CONFIG_SYS_BOOTM_LEN
  28 +/* use 8MByte as default max gunzip size */
  29 +#define CONFIG_SYS_BOOTM_LEN 0x800000
  30 +#endif
  31 +
  32 +#define IH_INITRD_ARCH IH_ARCH_DEFAULT
  33 +
  34 +static const void *boot_get_kernel(cmd_tbl_t *cmdtp, int flag, int argc,
  35 + char * const argv[], bootm_headers_t *images,
  36 + ulong *os_data, ulong *os_len);
  37 +
  38 +#ifdef CONFIG_LMB
  39 +static void boot_start_lmb(bootm_headers_t *images)
  40 +{
  41 + ulong mem_start;
  42 + phys_size_t mem_size;
  43 +
  44 + lmb_init(&images->lmb);
  45 +
  46 + mem_start = getenv_bootm_low();
  47 + mem_size = getenv_bootm_size();
  48 +
  49 + lmb_add(&images->lmb, (phys_addr_t)mem_start, mem_size);
  50 +
  51 + arch_lmb_reserve(&images->lmb);
  52 + board_lmb_reserve(&images->lmb);
  53 +}
  54 +#else
  55 +#define lmb_reserve(lmb, base, size)
  56 +static inline void boot_start_lmb(bootm_headers_t *images) { }
  57 +#endif
  58 +
  59 +static int bootm_start(cmd_tbl_t *cmdtp, int flag, int argc,
  60 + char * const argv[])
  61 +{
  62 + memset((void *)&images, 0, sizeof(images));
  63 + images.verify = getenv_yesno("verify");
  64 +
  65 + boot_start_lmb(&images);
  66 +
  67 + bootstage_mark_name(BOOTSTAGE_ID_BOOTM_START, "bootm_start");
  68 + images.state = BOOTM_STATE_START;
  69 +
  70 + return 0;
  71 +}
  72 +
  73 +static int bootm_find_os(cmd_tbl_t *cmdtp, int flag, int argc,
  74 + char * const argv[])
  75 +{
  76 + const void *os_hdr;
  77 + bool ep_found = false;
  78 +
  79 + /* get kernel image header, start address and length */
  80 + os_hdr = boot_get_kernel(cmdtp, flag, argc, argv,
  81 + &images, &images.os.image_start, &images.os.image_len);
  82 + if (images.os.image_len == 0) {
  83 + puts("ERROR: can't get kernel image!\n");
  84 + return 1;
  85 + }
  86 +
  87 + /* get image parameters */
  88 + switch (genimg_get_format(os_hdr)) {
  89 +#if defined(CONFIG_IMAGE_FORMAT_LEGACY)
  90 + case IMAGE_FORMAT_LEGACY:
  91 + images.os.type = image_get_type(os_hdr);
  92 + images.os.comp = image_get_comp(os_hdr);
  93 + images.os.os = image_get_os(os_hdr);
  94 +
  95 + images.os.end = image_get_image_end(os_hdr);
  96 + images.os.load = image_get_load(os_hdr);
  97 + break;
  98 +#endif
  99 +#if defined(CONFIG_FIT)
  100 + case IMAGE_FORMAT_FIT:
  101 + if (fit_image_get_type(images.fit_hdr_os,
  102 + images.fit_noffset_os,
  103 + &images.os.type)) {
  104 + puts("Can't get image type!\n");
  105 + bootstage_error(BOOTSTAGE_ID_FIT_TYPE);
  106 + return 1;
  107 + }
  108 +
  109 + if (fit_image_get_comp(images.fit_hdr_os,
  110 + images.fit_noffset_os,
  111 + &images.os.comp)) {
  112 + puts("Can't get image compression!\n");
  113 + bootstage_error(BOOTSTAGE_ID_FIT_COMPRESSION);
  114 + return 1;
  115 + }
  116 +
  117 + if (fit_image_get_os(images.fit_hdr_os, images.fit_noffset_os,
  118 + &images.os.os)) {
  119 + puts("Can't get image OS!\n");
  120 + bootstage_error(BOOTSTAGE_ID_FIT_OS);
  121 + return 1;
  122 + }
  123 +
  124 + images.os.end = fit_get_end(images.fit_hdr_os);
  125 +
  126 + if (fit_image_get_load(images.fit_hdr_os, images.fit_noffset_os,
  127 + &images.os.load)) {
  128 + puts("Can't get image load address!\n");
  129 + bootstage_error(BOOTSTAGE_ID_FIT_LOADADDR);
  130 + return 1;
  131 + }
  132 + break;
  133 +#endif
  134 +#ifdef CONFIG_ANDROID_BOOT_IMAGE
  135 + case IMAGE_FORMAT_ANDROID:
  136 + images.os.type = IH_TYPE_KERNEL;
  137 + images.os.comp = IH_COMP_NONE;
  138 + images.os.os = IH_OS_LINUX;
  139 + images.ep = images.os.load;
  140 + ep_found = true;
  141 +
  142 + images.os.end = android_image_get_end(os_hdr);
  143 + images.os.load = android_image_get_kload(os_hdr);
  144 + break;
  145 +#endif
  146 + default:
  147 + puts("ERROR: unknown image format type!\n");
  148 + return 1;
  149 + }
  150 +
  151 + /* find kernel entry point */
  152 + if (images.legacy_hdr_valid) {
  153 + images.ep = image_get_ep(&images.legacy_hdr_os_copy);
  154 +#if defined(CONFIG_FIT)
  155 + } else if (images.fit_uname_os) {
  156 + int ret;
  157 +
  158 + ret = fit_image_get_entry(images.fit_hdr_os,
  159 + images.fit_noffset_os, &images.ep);
  160 + if (ret) {
  161 + puts("Can't get entry point property!\n");
  162 + return 1;
  163 + }
  164 +#endif
  165 + } else if (!ep_found) {
  166 + puts("Could not find kernel entry point!\n");
  167 + return 1;
  168 + }
  169 +
  170 + if (images.os.type == IH_TYPE_KERNEL_NOLOAD) {
  171 + images.os.load = images.os.image_start;
  172 + images.ep += images.os.load;
  173 + }
  174 +
  175 + images.os.start = (ulong)os_hdr;
  176 +
  177 + return 0;
  178 +}
  179 +
  180 +static int bootm_find_ramdisk(int flag, int argc, char * const argv[])
  181 +{
  182 + int ret;
  183 +
  184 + /* find ramdisk */
  185 + ret = boot_get_ramdisk(argc, argv, &images, IH_INITRD_ARCH,
  186 + &images.rd_start, &images.rd_end);
  187 + if (ret) {
  188 + puts("Ramdisk image is corrupt or invalid\n");
  189 + return 1;
  190 + }
  191 +
  192 + return 0;
  193 +}
  194 +
  195 +#if defined(CONFIG_OF_LIBFDT)
  196 +static int bootm_find_fdt(int flag, int argc, char * const argv[])
  197 +{
  198 + int ret;
  199 +
  200 + /* find flattened device tree */
  201 + ret = boot_get_fdt(flag, argc, argv, IH_ARCH_DEFAULT, &images,
  202 + &images.ft_addr, &images.ft_len);
  203 + if (ret) {
  204 + puts("Could not find a valid device tree\n");
  205 + return 1;
  206 + }
  207 +
  208 + set_working_fdt_addr(images.ft_addr);
  209 +
  210 + return 0;
  211 +}
  212 +#endif
  213 +
  214 +int bootm_find_ramdisk_fdt(int flag, int argc, char * const argv[])
  215 +{
  216 + if (bootm_find_ramdisk(flag, argc, argv))
  217 + return 1;
  218 +
  219 +#if defined(CONFIG_OF_LIBFDT)
  220 + if (bootm_find_fdt(flag, argc, argv))
  221 + return 1;
  222 +#endif
  223 +
  224 + return 0;
  225 +}
  226 +
  227 +static int bootm_find_other(cmd_tbl_t *cmdtp, int flag, int argc,
  228 + char * const argv[])
  229 +{
  230 + if (((images.os.type == IH_TYPE_KERNEL) ||
  231 + (images.os.type == IH_TYPE_KERNEL_NOLOAD) ||
  232 + (images.os.type == IH_TYPE_MULTI)) &&
  233 + (images.os.os == IH_OS_LINUX ||
  234 + images.os.os == IH_OS_VXWORKS))
  235 + return bootm_find_ramdisk_fdt(flag, argc, argv);
  236 +
  237 + return 0;
  238 +}
  239 +
  240 +static int bootm_load_os(bootm_headers_t *images, unsigned long *load_end,
  241 + int boot_progress)
  242 +{
  243 + image_info_t os = images->os;
  244 + uint8_t comp = os.comp;
  245 + ulong load = os.load;
  246 + ulong blob_start = os.start;
  247 + ulong blob_end = os.end;
  248 + ulong image_start = os.image_start;
  249 + ulong image_len = os.image_len;
  250 + __maybe_unused uint unc_len = CONFIG_SYS_BOOTM_LEN;
  251 + int no_overlap = 0;
  252 + void *load_buf, *image_buf;
  253 +#if defined(CONFIG_LZMA) || defined(CONFIG_LZO)
  254 + int ret;
  255 +#endif /* defined(CONFIG_LZMA) || defined(CONFIG_LZO) */
  256 +
  257 + const char *type_name = genimg_get_type_name(os.type);
  258 +
  259 + load_buf = map_sysmem(load, unc_len);
  260 + image_buf = map_sysmem(image_start, image_len);
  261 + switch (comp) {
  262 + case IH_COMP_NONE:
  263 + if (load == image_start) {
  264 + printf(" XIP %s ... ", type_name);
  265 + no_overlap = 1;
  266 + } else {
  267 + printf(" Loading %s ... ", type_name);
  268 + memmove_wd(load_buf, image_buf, image_len, CHUNKSZ);
  269 + }
  270 + *load_end = load + image_len;
  271 + break;
  272 +#ifdef CONFIG_GZIP
  273 + case IH_COMP_GZIP:
  274 + printf(" Uncompressing %s ... ", type_name);
  275 + if (gunzip(load_buf, unc_len, image_buf, &image_len) != 0) {
  276 + puts("GUNZIP: uncompress, out-of-mem or overwrite error - must RESET board to recover\n");
  277 + if (boot_progress)
  278 + bootstage_error(BOOTSTAGE_ID_DECOMP_IMAGE);
  279 + return BOOTM_ERR_RESET;
  280 + }
  281 +
  282 + *load_end = load + image_len;
  283 + break;
  284 +#endif /* CONFIG_GZIP */
  285 +#ifdef CONFIG_BZIP2
  286 + case IH_COMP_BZIP2:
  287 + printf(" Uncompressing %s ... ", type_name);
  288 + /*
  289 + * If we've got less than 4 MB of malloc() space,
  290 + * use slower decompression algorithm which requires
  291 + * at most 2300 KB of memory.
  292 + */
  293 + int i = BZ2_bzBuffToBuffDecompress(load_buf, &unc_len,
  294 + image_buf, image_len,
  295 + CONFIG_SYS_MALLOC_LEN < (4096 * 1024), 0);
  296 + if (i != BZ_OK) {
  297 + printf("BUNZIP2: uncompress or overwrite error %d - must RESET board to recover\n",
  298 + i);
  299 + if (boot_progress)
  300 + bootstage_error(BOOTSTAGE_ID_DECOMP_IMAGE);
  301 + return BOOTM_ERR_RESET;
  302 + }
  303 +
  304 + *load_end = load + unc_len;
  305 + break;
  306 +#endif /* CONFIG_BZIP2 */
  307 +#ifdef CONFIG_LZMA
  308 + case IH_COMP_LZMA: {
  309 + SizeT lzma_len = unc_len;
  310 + printf(" Uncompressing %s ... ", type_name);
  311 +
  312 + ret = lzmaBuffToBuffDecompress(load_buf, &lzma_len,
  313 + image_buf, image_len);
  314 + unc_len = lzma_len;
  315 + if (ret != SZ_OK) {
  316 + printf("LZMA: uncompress or overwrite error %d - must RESET board to recover\n",
  317 + ret);
  318 + bootstage_error(BOOTSTAGE_ID_DECOMP_IMAGE);
  319 + return BOOTM_ERR_RESET;
  320 + }
  321 + *load_end = load + unc_len;
  322 + break;
  323 + }
  324 +#endif /* CONFIG_LZMA */
  325 +#ifdef CONFIG_LZO
  326 + case IH_COMP_LZO: {
  327 + size_t size = unc_len;
  328 +
  329 + printf(" Uncompressing %s ... ", type_name);
  330 +
  331 + ret = lzop_decompress(image_buf, image_len, load_buf, &size);
  332 + if (ret != LZO_E_OK) {
  333 + printf("LZO: uncompress or overwrite error %d - must RESET board to recover\n",
  334 + ret);
  335 + if (boot_progress)
  336 + bootstage_error(BOOTSTAGE_ID_DECOMP_IMAGE);
  337 + return BOOTM_ERR_RESET;
  338 + }
  339 +
  340 + *load_end = load + size;
  341 + break;
  342 + }
  343 +#endif /* CONFIG_LZO */
  344 + default:
  345 + printf("Unimplemented compression type %d\n", comp);
  346 + return BOOTM_ERR_UNIMPLEMENTED;
  347 + }
  348 +
  349 + flush_cache(load, (*load_end - load) * sizeof(ulong));
  350 +
  351 + puts("OK\n");
  352 + debug(" kernel loaded at 0x%08lx, end = 0x%08lx\n", load, *load_end);
  353 + bootstage_mark(BOOTSTAGE_ID_KERNEL_LOADED);
  354 +
  355 + if (!no_overlap && (load < blob_end) && (*load_end > blob_start)) {
  356 + debug("images.os.start = 0x%lX, images.os.end = 0x%lx\n",
  357 + blob_start, blob_end);
  358 + debug("images.os.load = 0x%lx, load_end = 0x%lx\n", load,
  359 + *load_end);
  360 +
  361 + /* Check what type of image this is. */
  362 + if (images->legacy_hdr_valid) {
  363 + if (image_get_type(&images->legacy_hdr_os_copy)
  364 + == IH_TYPE_MULTI)
  365 + puts("WARNING: legacy format multi component image overwritten\n");
  366 + return BOOTM_ERR_OVERLAP;
  367 + } else {
  368 + puts("ERROR: new format image overwritten - must RESET the board to recover\n");
  369 + bootstage_error(BOOTSTAGE_ID_OVERWRITTEN);
  370 + return BOOTM_ERR_RESET;
  371 + }
  372 + }
  373 +
  374 + return 0;
  375 +}
  376 +
  377 +/**
  378 + * bootm_disable_interrupts() - Disable interrupts in preparation for load/boot
  379 + *
  380 + * @return interrupt flag (0 if interrupts were disabled, non-zero if they were
  381 + * enabled)
  382 + */
  383 +ulong bootm_disable_interrupts(void)
  384 +{
  385 + ulong iflag;
  386 +
  387 + /*
  388 + * We have reached the point of no return: we are going to
  389 + * overwrite all exception vector code, so we cannot easily
  390 + * recover from any failures any more...
  391 + */
  392 + iflag = disable_interrupts();
  393 +#ifdef CONFIG_NETCONSOLE
  394 + /* Stop the ethernet stack if NetConsole could have left it up */
  395 + eth_halt();
  396 + eth_unregister(eth_get_dev());
  397 +#endif
  398 +
  399 +#if defined(CONFIG_CMD_USB)
  400 + /*
  401 + * turn off USB to prevent the host controller from writing to the
  402 + * SDRAM while Linux is booting. This could happen (at least for OHCI
  403 + * controller), because the HCCA (Host Controller Communication Area)
  404 + * lies within the SDRAM and the host controller writes continously to
  405 + * this area (as busmaster!). The HccaFrameNumber is for example
  406 + * updated every 1 ms within the HCCA structure in SDRAM! For more
  407 + * details see the OpenHCI specification.
  408 + */
  409 + usb_stop();
  410 +#endif
  411 + return iflag;
  412 +}
  413 +
  414 +#if defined(CONFIG_SILENT_CONSOLE) && !defined(CONFIG_SILENT_U_BOOT_ONLY)
  415 +
  416 +#define CONSOLE_ARG "console="
  417 +#define CONSOLE_ARG_LEN (sizeof(CONSOLE_ARG) - 1)
  418 +
  419 +static void fixup_silent_linux(void)
  420 +{
  421 + char *buf;
  422 + const char *env_val;
  423 + char *cmdline = getenv("bootargs");
  424 + int want_silent;
  425 +
  426 + /*
  427 + * Only fix cmdline when requested. The environment variable can be:
  428 + *
  429 + * no - we never fixup
  430 + * yes - we always fixup
  431 + * unset - we rely on the console silent flag
  432 + */
  433 + want_silent = getenv_yesno("silent_linux");
  434 + if (want_silent == 0)
  435 + return;
  436 + else if (want_silent == -1 && !(gd->flags & GD_FLG_SILENT))
  437 + return;
  438 +
  439 + debug("before silent fix-up: %s\n", cmdline);
  440 + if (cmdline && (cmdline[0] != '\0')) {
  441 + char *start = strstr(cmdline, CONSOLE_ARG);
  442 +
  443 + /* Allocate space for maximum possible new command line */
  444 + buf = malloc(strlen(cmdline) + 1 + CONSOLE_ARG_LEN + 1);
  445 + if (!buf) {
  446 + debug("%s: out of memory\n", __func__);
  447 + return;
  448 + }
  449 +
  450 + if (start) {
  451 + char *end = strchr(start, ' ');
  452 + int num_start_bytes = start - cmdline + CONSOLE_ARG_LEN;
  453 +
  454 + strncpy(buf, cmdline, num_start_bytes);
  455 + if (end)
  456 + strcpy(buf + num_start_bytes, end);
  457 + else
  458 + buf[num_start_bytes] = '\0';
  459 + } else {
  460 + sprintf(buf, "%s %s", cmdline, CONSOLE_ARG);
  461 + }
  462 + env_val = buf;
  463 + } else {
  464 + buf = NULL;
  465 + env_val = CONSOLE_ARG;
  466 + }
  467 +
  468 + setenv("bootargs", env_val);
  469 + debug("after silent fix-up: %s\n", env_val);
  470 + free(buf);
  471 +}
  472 +#endif /* CONFIG_SILENT_CONSOLE */
  473 +
  474 +/**
  475 + * Execute selected states of the bootm command.
  476 + *
  477 + * Note the arguments to this state must be the first argument, Any 'bootm'
  478 + * or sub-command arguments must have already been taken.
  479 + *
  480 + * Note that if states contains more than one flag it MUST contain
  481 + * BOOTM_STATE_START, since this handles and consumes the command line args.
  482 + *
  483 + * Also note that aside from boot_os_fn functions and bootm_load_os no other
  484 + * functions we store the return value of in 'ret' may use a negative return
  485 + * value, without special handling.
  486 + *
  487 + * @param cmdtp Pointer to bootm command table entry
  488 + * @param flag Command flags (CMD_FLAG_...)
  489 + * @param argc Number of subcommand arguments (0 = no arguments)
  490 + * @param argv Arguments
  491 + * @param states Mask containing states to run (BOOTM_STATE_...)
  492 + * @param images Image header information
  493 + * @param boot_progress 1 to show boot progress, 0 to not do this
  494 + * @return 0 if ok, something else on error. Some errors will cause this
  495 + * function to perform a reboot! If states contains BOOTM_STATE_OS_GO
  496 + * then the intent is to boot an OS, so this function will not return
  497 + * unless the image type is standalone.
  498 + */
  499 +int do_bootm_states(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[],
  500 + int states, bootm_headers_t *images, int boot_progress)
  501 +{
  502 + boot_os_fn *boot_fn;
  503 + ulong iflag = 0;
  504 + int ret = 0, need_boot_fn;
  505 +
  506 + images->state |= states;
  507 +
  508 + /*
  509 + * Work through the states and see how far we get. We stop on
  510 + * any error.
  511 + */
  512 + if (states & BOOTM_STATE_START)
  513 + ret = bootm_start(cmdtp, flag, argc, argv);
  514 +
  515 + if (!ret && (states & BOOTM_STATE_FINDOS))
  516 + ret = bootm_find_os(cmdtp, flag, argc, argv);
  517 +
  518 + if (!ret && (states & BOOTM_STATE_FINDOTHER)) {
  519 + ret = bootm_find_other(cmdtp, flag, argc, argv);
  520 + argc = 0; /* consume the args */
  521 + }
  522 +
  523 + /* Load the OS */
  524 + if (!ret && (states & BOOTM_STATE_LOADOS)) {
  525 + ulong load_end;
  526 +
  527 + iflag = bootm_disable_interrupts();
  528 + ret = bootm_load_os(images, &load_end, 0);
  529 + if (ret == 0)
  530 + lmb_reserve(&images->lmb, images->os.load,
  531 + (load_end - images->os.load));
  532 + else if (ret && ret != BOOTM_ERR_OVERLAP)
  533 + goto err;
  534 + else if (ret == BOOTM_ERR_OVERLAP)
  535 + ret = 0;
  536 +#if defined(CONFIG_SILENT_CONSOLE) && !defined(CONFIG_SILENT_U_BOOT_ONLY)
  537 + if (images->os.os == IH_OS_LINUX)
  538 + fixup_silent_linux();
  539 +#endif
  540 + }
  541 +
  542 + /* Relocate the ramdisk */
  543 +#ifdef CONFIG_SYS_BOOT_RAMDISK_HIGH
  544 + if (!ret && (states & BOOTM_STATE_RAMDISK)) {
  545 + ulong rd_len = images->rd_end - images->rd_start;
  546 +
  547 + ret = boot_ramdisk_high(&images->lmb, images->rd_start,
  548 + rd_len, &images->initrd_start, &images->initrd_end);
  549 + if (!ret) {
  550 + setenv_hex("initrd_start", images->initrd_start);
  551 + setenv_hex("initrd_end", images->initrd_end);
  552 + }
  553 + }
  554 +#endif
  555 +#if defined(CONFIG_OF_LIBFDT) && defined(CONFIG_LMB)
  556 + if (!ret && (states & BOOTM_STATE_FDT)) {
  557 + boot_fdt_add_mem_rsv_regions(&images->lmb, images->ft_addr);
  558 + ret = boot_relocate_fdt(&images->lmb, &images->ft_addr,
  559 + &images->ft_len);
  560 + }
  561 +#endif
  562 +
  563 + /* From now on, we need the OS boot function */
  564 + if (ret)
  565 + return ret;
  566 + boot_fn = bootm_os_get_boot_func(images->os.os);
  567 + need_boot_fn = states & (BOOTM_STATE_OS_CMDLINE |
  568 + BOOTM_STATE_OS_BD_T | BOOTM_STATE_OS_PREP |
  569 + BOOTM_STATE_OS_FAKE_GO | BOOTM_STATE_OS_GO);
  570 + if (boot_fn == NULL && need_boot_fn) {
  571 + if (iflag)
  572 + enable_interrupts();
  573 + printf("ERROR: booting os '%s' (%d) is not supported\n",
  574 + genimg_get_os_name(images->os.os), images->os.os);
  575 + bootstage_error(BOOTSTAGE_ID_CHECK_BOOT_OS);
  576 + return 1;
  577 + }
  578 +
  579 + /* Call various other states that are not generally used */
  580 + if (!ret && (states & BOOTM_STATE_OS_CMDLINE))
  581 + ret = boot_fn(BOOTM_STATE_OS_CMDLINE, argc, argv, images);
  582 + if (!ret && (states & BOOTM_STATE_OS_BD_T))
  583 + ret = boot_fn(BOOTM_STATE_OS_BD_T, argc, argv, images);
  584 + if (!ret && (states & BOOTM_STATE_OS_PREP))
  585 + ret = boot_fn(BOOTM_STATE_OS_PREP, argc, argv, images);
  586 +
  587 +#ifdef CONFIG_TRACE
  588 + /* Pretend to run the OS, then run a user command */
  589 + if (!ret && (states & BOOTM_STATE_OS_FAKE_GO)) {
  590 + char *cmd_list = getenv("fakegocmd");
  591 +
  592 + ret = boot_selected_os(argc, argv, BOOTM_STATE_OS_FAKE_GO,
  593 + images, boot_fn);
  594 + if (!ret && cmd_list)
  595 + ret = run_command_list(cmd_list, -1, flag);
  596 + }
  597 +#endif
  598 +
  599 + /* Check for unsupported subcommand. */
  600 + if (ret) {
  601 + puts("subcommand not supported\n");
  602 + return ret;
  603 + }
  604 +
  605 + /* Now run the OS! We hope this doesn't return */
  606 + if (!ret && (states & BOOTM_STATE_OS_GO))
  607 + ret = boot_selected_os(argc, argv, BOOTM_STATE_OS_GO,
  608 + images, boot_fn);
  609 +
  610 + /* Deal with any fallout */
  611 +err:
  612 + if (iflag)
  613 + enable_interrupts();
  614 +
  615 + if (ret == BOOTM_ERR_UNIMPLEMENTED)
  616 + bootstage_error(BOOTSTAGE_ID_DECOMP_UNIMPL);
  617 + else if (ret == BOOTM_ERR_RESET)
  618 + do_reset(cmdtp, flag, argc, argv);
  619 +
  620 + return ret;
  621 +}
  622 +
  623 +#if defined(CONFIG_IMAGE_FORMAT_LEGACY)
  624 +/**
  625 + * image_get_kernel - verify legacy format kernel image
  626 + * @img_addr: in RAM address of the legacy format image to be verified
  627 + * @verify: data CRC verification flag
  628 + *
  629 + * image_get_kernel() verifies legacy image integrity and returns pointer to
  630 + * legacy image header if image verification was completed successfully.
  631 + *
  632 + * returns:
  633 + * pointer to a legacy image header if valid image was found
  634 + * otherwise return NULL
  635 + */
  636 +static image_header_t *image_get_kernel(ulong img_addr, int verify)
  637 +{
  638 + image_header_t *hdr = (image_header_t *)img_addr;
  639 +
  640 + if (!image_check_magic(hdr)) {
  641 + puts("Bad Magic Number\n");
  642 + bootstage_error(BOOTSTAGE_ID_CHECK_MAGIC);
  643 + return NULL;
  644 + }
  645 + bootstage_mark(BOOTSTAGE_ID_CHECK_HEADER);
  646 +
  647 + if (!image_check_hcrc(hdr)) {
  648 + puts("Bad Header Checksum\n");
  649 + bootstage_error(BOOTSTAGE_ID_CHECK_HEADER);
  650 + return NULL;
  651 + }
  652 +
  653 + bootstage_mark(BOOTSTAGE_ID_CHECK_CHECKSUM);
  654 + image_print_contents(hdr);
  655 +
  656 + if (verify) {
  657 + puts(" Verifying Checksum ... ");
  658 + if (!image_check_dcrc(hdr)) {
  659 + printf("Bad Data CRC\n");
  660 + bootstage_error(BOOTSTAGE_ID_CHECK_CHECKSUM);
  661 + return NULL;
  662 + }
  663 + puts("OK\n");
  664 + }
  665 + bootstage_mark(BOOTSTAGE_ID_CHECK_ARCH);
  666 +
  667 + if (!image_check_target_arch(hdr)) {
  668 + printf("Unsupported Architecture 0x%x\n", image_get_arch(hdr));
  669 + bootstage_error(BOOTSTAGE_ID_CHECK_ARCH);
  670 + return NULL;
  671 + }
  672 + return hdr;
  673 +}
  674 +#endif
  675 +
  676 +/**
  677 + * boot_get_kernel - find kernel image
  678 + * @os_data: pointer to a ulong variable, will hold os data start address
  679 + * @os_len: pointer to a ulong variable, will hold os data length
  680 + *
  681 + * boot_get_kernel() tries to find a kernel image, verifies its integrity
  682 + * and locates kernel data.
  683 + *
  684 + * returns:
  685 + * pointer to image header if valid image was found, plus kernel start
  686 + * address and length, otherwise NULL
  687 + */
  688 +static const void *boot_get_kernel(cmd_tbl_t *cmdtp, int flag, int argc,
  689 + char * const argv[], bootm_headers_t *images,
  690 + ulong *os_data, ulong *os_len)
  691 +{
  692 +#if defined(CONFIG_IMAGE_FORMAT_LEGACY)
  693 + image_header_t *hdr;
  694 +#endif
  695 + ulong img_addr;
  696 + const void *buf;
  697 +#if defined(CONFIG_FIT)
  698 + const char *fit_uname_config = NULL;
  699 + const char *fit_uname_kernel = NULL;
  700 + int os_noffset;
  701 +#endif
  702 +
  703 + /* find out kernel image address */
  704 + if (argc < 1) {
  705 + img_addr = load_addr;
  706 + debug("* kernel: default image load address = 0x%08lx\n",
  707 + load_addr);
  708 +#if defined(CONFIG_FIT)
  709 + } else if (fit_parse_conf(argv[0], load_addr, &img_addr,
  710 + &fit_uname_config)) {
  711 + debug("* kernel: config '%s' from image at 0x%08lx\n",
  712 + fit_uname_config, img_addr);
  713 + } else if (fit_parse_subimage(argv[0], load_addr, &img_addr,
  714 + &fit_uname_kernel)) {
  715 + debug("* kernel: subimage '%s' from image at 0x%08lx\n",
  716 + fit_uname_kernel, img_addr);
  717 +#endif
  718 + } else {
  719 + img_addr = simple_strtoul(argv[0], NULL, 16);
  720 + debug("* kernel: cmdline image address = 0x%08lx\n",
  721 + img_addr);
  722 + }
  723 +
  724 + bootstage_mark(BOOTSTAGE_ID_CHECK_MAGIC);
  725 +
  726 + /* copy from dataflash if needed */
  727 + img_addr = genimg_get_image(img_addr);
  728 +
  729 + /* check image type, for FIT images get FIT kernel node */
  730 + *os_data = *os_len = 0;
  731 + buf = map_sysmem(img_addr, 0);
  732 + switch (genimg_get_format(buf)) {
  733 +#if defined(CONFIG_IMAGE_FORMAT_LEGACY)
  734 + case IMAGE_FORMAT_LEGACY:
  735 + printf("## Booting kernel from Legacy Image at %08lx ...\n",
  736 + img_addr);
  737 + hdr = image_get_kernel(img_addr, images->verify);
  738 + if (!hdr)
  739 + return NULL;
  740 + bootstage_mark(BOOTSTAGE_ID_CHECK_IMAGETYPE);
  741 +
  742 + /* get os_data and os_len */
  743 + switch (image_get_type(hdr)) {
  744 + case IH_TYPE_KERNEL:
  745 + case IH_TYPE_KERNEL_NOLOAD:
  746 + *os_data = image_get_data(hdr);
  747 + *os_len = image_get_data_size(hdr);
  748 + break;
  749 + case IH_TYPE_MULTI:
  750 + image_multi_getimg(hdr, 0, os_data, os_len);
  751 + break;
  752 + case IH_TYPE_STANDALONE:
  753 + *os_data = image_get_data(hdr);
  754 + *os_len = image_get_data_size(hdr);
  755 + break;
  756 + default:
  757 + printf("Wrong Image Type for %s command\n",
  758 + cmdtp->name);
  759 + bootstage_error(BOOTSTAGE_ID_CHECK_IMAGETYPE);
  760 + return NULL;
  761 + }
  762 +
  763 + /*
  764 + * copy image header to allow for image overwrites during
  765 + * kernel decompression.
  766 + */
  767 + memmove(&images->legacy_hdr_os_copy, hdr,
  768 + sizeof(image_header_t));
  769 +
  770 + /* save pointer to image header */
  771 + images->legacy_hdr_os = hdr;
  772 +
  773 + images->legacy_hdr_valid = 1;
  774 + bootstage_mark(BOOTSTAGE_ID_DECOMP_IMAGE);
  775 + break;
  776 +#endif
  777 +#if defined(CONFIG_FIT)
  778 + case IMAGE_FORMAT_FIT:
  779 + os_noffset = fit_image_load(images, FIT_KERNEL_PROP,
  780 + img_addr,
  781 + &fit_uname_kernel, &fit_uname_config,
  782 + IH_ARCH_DEFAULT, IH_TYPE_KERNEL,
  783 + BOOTSTAGE_ID_FIT_KERNEL_START,
  784 + FIT_LOAD_IGNORED, os_data, os_len);
  785 + if (os_noffset < 0)
  786 + return NULL;
  787 +
  788 + images->fit_hdr_os = map_sysmem(img_addr, 0);
  789 + images->fit_uname_os = fit_uname_kernel;
  790 + images->fit_uname_cfg = fit_uname_config;
  791 + images->fit_noffset_os = os_noffset;
  792 + break;
  793 +#endif
  794 +#ifdef CONFIG_ANDROID_BOOT_IMAGE
  795 + case IMAGE_FORMAT_ANDROID:
  796 + printf("## Booting Android Image at 0x%08lx ...\n", img_addr);
  797 + if (android_image_get_kernel((void *)img_addr, images->verify,
  798 + os_data, os_len))
  799 + return NULL;
  800 + break;
  801 +#endif
  802 + default:
  803 + printf("Wrong Image Format for %s command\n", cmdtp->name);
  804 + bootstage_error(BOOTSTAGE_ID_FIT_KERNEL_INFO);
  805 + return NULL;
  806 + }
  807 +
  808 + debug(" kernel data at 0x%08lx, len = 0x%08lx (%ld)\n",
  809 + *os_data, *os_len, *os_len);
  810 +
  811 + return buf;
  812 +}
  1 +/*
  2 + * (C) Copyright 2000-2009
  3 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
  4 + *
  5 + * SPDX-License-Identifier: GPL-2.0+
  6 + */
  7 +
  8 +#include <common.h>
  9 +#include <bootm.h>
  10 +#include <fdt_support.h>
  11 +#include <libfdt.h>
  12 +#include <malloc.h>
  13 +#include <vxworks.h>
  14 +
  15 +DECLARE_GLOBAL_DATA_PTR;
  16 +
  17 +static int do_bootm_standalone(int flag, int argc, char * const argv[],
  18 + bootm_headers_t *images)
  19 +{
  20 + char *s;
  21 + int (*appl)(int, char *const[]);
  22 +
  23 + /* Don't start if "autostart" is set to "no" */
  24 + s = getenv("autostart");
  25 + if ((s != NULL) && !strcmp(s, "no")) {
  26 + setenv_hex("filesize", images->os.image_len);
  27 + return 0;
  28 + }
  29 + appl = (int (*)(int, char * const []))images->ep;
  30 + appl(argc, argv);
  31 + return 0;
  32 +}
  33 +
  34 +/*******************************************************************/
  35 +/* OS booting routines */
  36 +/*******************************************************************/
  37 +
  38 +#if defined(CONFIG_BOOTM_NETBSD) || defined(CONFIG_BOOTM_PLAN9)
  39 +static void copy_args(char *dest, int argc, char * const argv[], char delim)
  40 +{
  41 + int i;
  42 +
  43 + for (i = 0; i < argc; i++) {
  44 + if (i > 0)
  45 + *dest++ = delim;
  46 + strcpy(dest, argv[i]);
  47 + dest += strlen(argv[i]);
  48 + }
  49 +}
  50 +#endif
  51 +
  52 +#ifdef CONFIG_BOOTM_NETBSD
  53 +static int do_bootm_netbsd(int flag, int argc, char * const argv[],
  54 + bootm_headers_t *images)
  55 +{
  56 + void (*loader)(bd_t *, image_header_t *, char *, char *);
  57 + image_header_t *os_hdr, *hdr;
  58 + ulong kernel_data, kernel_len;
  59 + char *consdev;
  60 + char *cmdline;
  61 +
  62 + if (flag != BOOTM_STATE_OS_GO)
  63 + return 0;
  64 +
  65 +#if defined(CONFIG_FIT)
  66 + if (!images->legacy_hdr_valid) {
  67 + fit_unsupported_reset("NetBSD");
  68 + return 1;
  69 + }
  70 +#endif
  71 + hdr = images->legacy_hdr_os;
  72 +
  73 + /*
  74 + * Booting a (NetBSD) kernel image
  75 + *
  76 + * This process is pretty similar to a standalone application:
  77 + * The (first part of an multi-) image must be a stage-2 loader,
  78 + * which in turn is responsible for loading & invoking the actual
  79 + * kernel. The only differences are the parameters being passed:
  80 + * besides the board info strucure, the loader expects a command
  81 + * line, the name of the console device, and (optionally) the
  82 + * address of the original image header.
  83 + */
  84 + os_hdr = NULL;
  85 + if (image_check_type(&images->legacy_hdr_os_copy, IH_TYPE_MULTI)) {
  86 + image_multi_getimg(hdr, 1, &kernel_data, &kernel_len);
  87 + if (kernel_len)
  88 + os_hdr = hdr;
  89 + }
  90 +
  91 + consdev = "";
  92 +#if defined(CONFIG_8xx_CONS_SMC1)
  93 + consdev = "smc1";
  94 +#elif defined(CONFIG_8xx_CONS_SMC2)
  95 + consdev = "smc2";
  96 +#elif defined(CONFIG_8xx_CONS_SCC2)
  97 + consdev = "scc2";
  98 +#elif defined(CONFIG_8xx_CONS_SCC3)
  99 + consdev = "scc3";
  100 +#endif
  101 +
  102 + if (argc > 0) {
  103 + ulong len;
  104 + int i;
  105 +
  106 + for (i = 0, len = 0; i < argc; i += 1)
  107 + len += strlen(argv[i]) + 1;
  108 + cmdline = malloc(len);
  109 + copy_args(cmdline, argc, argv, ' ');
  110 + } else {
  111 + cmdline = getenv("bootargs");
  112 + if (cmdline == NULL)
  113 + cmdline = "";
  114 + }
  115 +
  116 + loader = (void (*)(bd_t *, image_header_t *, char *, char *))images->ep;
  117 +
  118 + printf("## Transferring control to NetBSD stage-2 loader (at address %08lx) ...\n",
  119 + (ulong)loader);
  120 +
  121 + bootstage_mark(BOOTSTAGE_ID_RUN_OS);
  122 +
  123 + /*
  124 + * NetBSD Stage-2 Loader Parameters:
  125 + * arg[0]: pointer to board info data
  126 + * arg[1]: image load address
  127 + * arg[2]: char pointer to the console device to use
  128 + * arg[3]: char pointer to the boot arguments
  129 + */
  130 + (*loader)(gd->bd, os_hdr, consdev, cmdline);
  131 +
  132 + return 1;
  133 +}
  134 +#endif /* CONFIG_BOOTM_NETBSD*/
  135 +
  136 +#ifdef CONFIG_LYNXKDI
  137 +static int do_bootm_lynxkdi(int flag, int argc, char * const argv[],
  138 + bootm_headers_t *images)
  139 +{
  140 + image_header_t *hdr = &images->legacy_hdr_os_copy;
  141 +
  142 + if (flag != BOOTM_STATE_OS_GO)
  143 + return 0;
  144 +
  145 +#if defined(CONFIG_FIT)
  146 + if (!images->legacy_hdr_valid) {
  147 + fit_unsupported_reset("Lynx");
  148 + return 1;
  149 + }
  150 +#endif
  151 +
  152 + lynxkdi_boot((image_header_t *)hdr);
  153 +
  154 + return 1;
  155 +}
  156 +#endif /* CONFIG_LYNXKDI */
  157 +
  158 +#ifdef CONFIG_BOOTM_RTEMS
  159 +static int do_bootm_rtems(int flag, int argc, char * const argv[],
  160 + bootm_headers_t *images)
  161 +{
  162 + void (*entry_point)(bd_t *);
  163 +
  164 + if (flag != BOOTM_STATE_OS_GO)
  165 + return 0;
  166 +
  167 +#if defined(CONFIG_FIT)
  168 + if (!images->legacy_hdr_valid) {
  169 + fit_unsupported_reset("RTEMS");
  170 + return 1;
  171 + }
  172 +#endif
  173 +
  174 + entry_point = (void (*)(bd_t *))images->ep;
  175 +
  176 + printf("## Transferring control to RTEMS (at address %08lx) ...\n",
  177 + (ulong)entry_point);
  178 +
  179 + bootstage_mark(BOOTSTAGE_ID_RUN_OS);
  180 +
  181 + /*
  182 + * RTEMS Parameters:
  183 + * r3: ptr to board info data
  184 + */
  185 + (*entry_point)(gd->bd);
  186 +
  187 + return 1;
  188 +}
  189 +#endif /* CONFIG_BOOTM_RTEMS */
  190 +
  191 +#if defined(CONFIG_BOOTM_OSE)
  192 +static int do_bootm_ose(int flag, int argc, char * const argv[],
  193 + bootm_headers_t *images)
  194 +{
  195 + void (*entry_point)(void);
  196 +
  197 + if (flag != BOOTM_STATE_OS_GO)
  198 + return 0;
  199 +
  200 +#if defined(CONFIG_FIT)
  201 + if (!images->legacy_hdr_valid) {
  202 + fit_unsupported_reset("OSE");
  203 + return 1;
  204 + }
  205 +#endif
  206 +
  207 + entry_point = (void (*)(void))images->ep;
  208 +
  209 + printf("## Transferring control to OSE (at address %08lx) ...\n",
  210 + (ulong)entry_point);
  211 +
  212 + bootstage_mark(BOOTSTAGE_ID_RUN_OS);
  213 +
  214 + /*
  215 + * OSE Parameters:
  216 + * None
  217 + */
  218 + (*entry_point)();
  219 +
  220 + return 1;
  221 +}
  222 +#endif /* CONFIG_BOOTM_OSE */
  223 +
  224 +#if defined(CONFIG_BOOTM_PLAN9)
  225 +static int do_bootm_plan9(int flag, int argc, char * const argv[],
  226 + bootm_headers_t *images)
  227 +{
  228 + void (*entry_point)(void);
  229 + char *s;
  230 +
  231 + if (flag != BOOTM_STATE_OS_GO)
  232 + return 0;
  233 +
  234 +#if defined(CONFIG_FIT)
  235 + if (!images->legacy_hdr_valid) {
  236 + fit_unsupported_reset("Plan 9");
  237 + return 1;
  238 + }
  239 +#endif
  240 +
  241 + /* See README.plan9 */
  242 + s = getenv("confaddr");
  243 + if (s != NULL) {
  244 + char *confaddr = (char *)simple_strtoul(s, NULL, 16);
  245 +
  246 + if (argc > 0) {
  247 + copy_args(confaddr, argc, argv, '\n');
  248 + } else {
  249 + s = getenv("bootargs");
  250 + if (s != NULL)
  251 + strcpy(confaddr, s);
  252 + }
  253 + }
  254 +
  255 + entry_point = (void (*)(void))images->ep;
  256 +
  257 + printf("## Transferring control to Plan 9 (at address %08lx) ...\n",
  258 + (ulong)entry_point);
  259 +
  260 + bootstage_mark(BOOTSTAGE_ID_RUN_OS);
  261 +
  262 + /*
  263 + * Plan 9 Parameters:
  264 + * None
  265 + */
  266 + (*entry_point)();
  267 +
  268 + return 1;
  269 +}
  270 +#endif /* CONFIG_BOOTM_PLAN9 */
  271 +
  272 +#if defined(CONFIG_BOOTM_VXWORKS) && \
  273 + (defined(CONFIG_PPC) || defined(CONFIG_ARM))
  274 +
  275 +void do_bootvx_fdt(bootm_headers_t *images)
  276 +{
  277 +#if defined(CONFIG_OF_LIBFDT)
  278 + int ret;
  279 + char *bootline;
  280 + ulong of_size = images->ft_len;
  281 + char **of_flat_tree = &images->ft_addr;
  282 + struct lmb *lmb = &images->lmb;
  283 +
  284 + if (*of_flat_tree) {
  285 + boot_fdt_add_mem_rsv_regions(lmb, *of_flat_tree);
  286 +
  287 + ret = boot_relocate_fdt(lmb, of_flat_tree, &of_size);
  288 + if (ret)
  289 + return;
  290 +
  291 + ret = fdt_add_subnode(*of_flat_tree, 0, "chosen");
  292 + if ((ret >= 0 || ret == -FDT_ERR_EXISTS)) {
  293 + bootline = getenv("bootargs");
  294 + if (bootline) {
  295 + ret = fdt_find_and_setprop(*of_flat_tree,
  296 + "/chosen", "bootargs",
  297 + bootline,
  298 + strlen(bootline) + 1, 1);
  299 + if (ret < 0) {
  300 + printf("## ERROR: %s : %s\n", __func__,
  301 + fdt_strerror(ret));
  302 + return;
  303 + }
  304 + }
  305 + } else {
  306 + printf("## ERROR: %s : %s\n", __func__,
  307 + fdt_strerror(ret));
  308 + return;
  309 + }
  310 + }
  311 +#endif
  312 +
  313 + boot_prep_vxworks(images);
  314 +
  315 + bootstage_mark(BOOTSTAGE_ID_RUN_OS);
  316 +
  317 +#if defined(CONFIG_OF_LIBFDT)
  318 + printf("## Starting vxWorks at 0x%08lx, device tree at 0x%08lx ...\n",
  319 + (ulong)images->ep, (ulong)*of_flat_tree);
  320 +#else
  321 + printf("## Starting vxWorks at 0x%08lx\n", (ulong)images->ep);
  322 +#endif
  323 +
  324 + boot_jump_vxworks(images);
  325 +
  326 + puts("## vxWorks terminated\n");
  327 +}
  328 +
  329 +static int do_bootm_vxworks(int flag, int argc, char * const argv[],
  330 + bootm_headers_t *images)
  331 +{
  332 + if (flag != BOOTM_STATE_OS_GO)
  333 + return 0;
  334 +
  335 +#if defined(CONFIG_FIT)
  336 + if (!images->legacy_hdr_valid) {
  337 + fit_unsupported_reset("VxWorks");
  338 + return 1;
  339 + }
  340 +#endif
  341 +
  342 + do_bootvx_fdt(images);
  343 +
  344 + return 1;
  345 +}
  346 +#endif
  347 +
  348 +#if defined(CONFIG_CMD_ELF)
  349 +static int do_bootm_qnxelf(int flag, int argc, char * const argv[],
  350 + bootm_headers_t *images)
  351 +{
  352 + char *local_args[2];
  353 + char str[16];
  354 +
  355 + if (flag != BOOTM_STATE_OS_GO)
  356 + return 0;
  357 +
  358 +#if defined(CONFIG_FIT)
  359 + if (!images->legacy_hdr_valid) {
  360 + fit_unsupported_reset("QNX");
  361 + return 1;
  362 + }
  363 +#endif
  364 +
  365 + sprintf(str, "%lx", images->ep); /* write entry-point into string */
  366 + local_args[0] = argv[0];
  367 + local_args[1] = str; /* and provide it via the arguments */
  368 + do_bootelf(NULL, 0, 2, local_args);
  369 +
  370 + return 1;
  371 +}
  372 +#endif
  373 +
  374 +#ifdef CONFIG_INTEGRITY
  375 +static int do_bootm_integrity(int flag, int argc, char * const argv[],
  376 + bootm_headers_t *images)
  377 +{
  378 + void (*entry_point)(void);
  379 +
  380 + if (flag != BOOTM_STATE_OS_GO)
  381 + return 0;
  382 +
  383 +#if defined(CONFIG_FIT)
  384 + if (!images->legacy_hdr_valid) {
  385 + fit_unsupported_reset("INTEGRITY");
  386 + return 1;
  387 + }
  388 +#endif
  389 +
  390 + entry_point = (void (*)(void))images->ep;
  391 +
  392 + printf("## Transferring control to INTEGRITY (at address %08lx) ...\n",
  393 + (ulong)entry_point);
  394 +
  395 + bootstage_mark(BOOTSTAGE_ID_RUN_OS);
  396 +
  397 + /*
  398 + * INTEGRITY Parameters:
  399 + * None
  400 + */
  401 + (*entry_point)();
  402 +
  403 + return 1;
  404 +}
  405 +#endif
  406 +
  407 +static boot_os_fn *boot_os[] = {
  408 + [IH_OS_U_BOOT] = do_bootm_standalone,
  409 +#ifdef CONFIG_BOOTM_LINUX
  410 + [IH_OS_LINUX] = do_bootm_linux,
  411 +#endif
  412 +#ifdef CONFIG_BOOTM_NETBSD
  413 + [IH_OS_NETBSD] = do_bootm_netbsd,
  414 +#endif
  415 +#ifdef CONFIG_LYNXKDI
  416 + [IH_OS_LYNXOS] = do_bootm_lynxkdi,
  417 +#endif
  418 +#ifdef CONFIG_BOOTM_RTEMS
  419 + [IH_OS_RTEMS] = do_bootm_rtems,
  420 +#endif
  421 +#if defined(CONFIG_BOOTM_OSE)
  422 + [IH_OS_OSE] = do_bootm_ose,
  423 +#endif
  424 +#if defined(CONFIG_BOOTM_PLAN9)
  425 + [IH_OS_PLAN9] = do_bootm_plan9,
  426 +#endif
  427 +#if defined(CONFIG_BOOTM_VXWORKS) && \
  428 + (defined(CONFIG_PPC) || defined(CONFIG_ARM))
  429 + [IH_OS_VXWORKS] = do_bootm_vxworks,
  430 +#endif
  431 +#if defined(CONFIG_CMD_ELF)
  432 + [IH_OS_QNX] = do_bootm_qnxelf,
  433 +#endif
  434 +#ifdef CONFIG_INTEGRITY
  435 + [IH_OS_INTEGRITY] = do_bootm_integrity,
  436 +#endif
  437 +};
  438 +
  439 +/* Allow for arch specific config before we boot */
  440 +static void __arch_preboot_os(void)
  441 +{
  442 + /* please define platform specific arch_preboot_os() */
  443 +}
  444 +void arch_preboot_os(void) __attribute__((weak, alias("__arch_preboot_os")));
  445 +
  446 +int boot_selected_os(int argc, char * const argv[], int state,
  447 + bootm_headers_t *images, boot_os_fn *boot_fn)
  448 +{
  449 + arch_preboot_os();
  450 + boot_fn(state, argc, argv, images);
  451 +
  452 + /* Stand-alone may return when 'autostart' is 'no' */
  453 + if (images->os.type == IH_TYPE_STANDALONE ||
  454 + state == BOOTM_STATE_OS_FAKE_GO) /* We expect to return */
  455 + return 0;
  456 + bootstage_error(BOOTSTAGE_ID_BOOT_OS_RETURNED);
  457 +#ifdef DEBUG
  458 + puts("\n## Control returned to monitor - resetting...\n");
  459 +#endif
  460 + return BOOTM_ERR_RESET;
  461 +}
  462 +
  463 +boot_os_fn *bootm_os_get_boot_func(int os)
  464 +{
  465 +#ifdef CONFIG_NEEDS_MANUAL_RELOC
  466 + static bool relocated;
  467 +
  468 + if (!relocated) {
  469 + int i;
  470 +
  471 + /* relocate boot function table */
  472 + for (i = 0; i < ARRAY_SIZE(boot_os); i++)
  473 + if (boot_os[i] != NULL)
  474 + boot_os[i] += gd->reloc_off;
  475 +
  476 + relocated = true;
  477 + }
  478 +#endif
  479 + return boot_os[os];
  480 +}
Changes suppressed. Click to show
... ... @@ -5,58 +5,25 @@
5 5 * SPDX-License-Identifier: GPL-2.0+
6 6 */
7 7  
8   -
9 8 /*
10 9 * Boot support
11 10 */
12 11 #include <common.h>
13   -#include <watchdog.h>
  12 +#include <bootm.h>
14 13 #include <command.h>
15   -#include <image.h>
16   -#include <malloc.h>
17   -#include <u-boot/zlib.h>
18   -#include <bzlib.h>
19 14 #include <environment.h>
  15 +#include <image.h>
20 16 #include <lmb.h>
21   -#include <linux/ctype.h>
  17 +#include <malloc.h>
  18 +#include <nand.h>
22 19 #include <asm/byteorder.h>
23   -#include <asm/io.h>
24 20 #include <linux/compiler.h>
  21 +#include <linux/ctype.h>
  22 +#include <linux/err.h>
  23 +#include <u-boot/zlib.h>
25 24  
26   -#if defined(CONFIG_BOOTM_VXWORKS) && \
27   - (defined(CONFIG_PPC) || defined(CONFIG_ARM))
28   -#include <vxworks.h>
29   -#endif
30   -
31   -#if defined(CONFIG_CMD_USB)
32   -#include <usb.h>
33   -#endif
34   -
35   -#if defined(CONFIG_OF_LIBFDT)
36   -#include <libfdt.h>
37   -#include <fdt_support.h>
38   -#endif
39   -
40   -#ifdef CONFIG_LZMA
41   -#include <lzma/LzmaTypes.h>
42   -#include <lzma/LzmaDec.h>
43   -#include <lzma/LzmaTools.h>
44   -#endif /* CONFIG_LZMA */
45   -
46   -#ifdef CONFIG_LZO
47   -#include <linux/lzo.h>
48   -#endif /* CONFIG_LZO */
49   -
50 25 DECLARE_GLOBAL_DATA_PTR;
51 26  
52   -#ifndef CONFIG_SYS_BOOTM_LEN
53   -#define CONFIG_SYS_BOOTM_LEN 0x800000 /* use 8MByte as default max gunzip size */
54   -#endif
55   -
56   -#ifdef CONFIG_BZIP2
57   -extern void bz_internal_error(int);
58   -#endif
59   -
60 27 #if defined(CONFIG_CMD_IMI)
61 28 static int image_info(unsigned long addr);
62 29 #endif
63 30  
... ... @@ -71,465 +38,8 @@
71 38 static int do_imls(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]);
72 39 #endif
73 40  
74   -#include <linux/err.h>
75   -#include <nand.h>
76   -
77   -#if defined(CONFIG_SILENT_CONSOLE) && !defined(CONFIG_SILENT_U_BOOT_ONLY)
78   -static void fixup_silent_linux(void);
79   -#endif
80   -
81   -static int do_bootm_standalone(int flag, int argc, char * const argv[],
82   - bootm_headers_t *images);
83   -
84   -static const void *boot_get_kernel(cmd_tbl_t *cmdtp, int flag, int argc,
85   - char * const argv[], bootm_headers_t *images,
86   - ulong *os_data, ulong *os_len);
87   -
88   -/*
89   - * Continue booting an OS image; caller already has:
90   - * - copied image header to global variable `header'
91   - * - checked header magic number, checksums (both header & image),
92   - * - verified image architecture (PPC) and type (KERNEL or MULTI),
93   - * - loaded (first part of) image to header load address,
94   - * - disabled interrupts.
95   - *
96   - * @flag: Flags indicating what to do (BOOTM_STATE_...)
97   - * @argc: Number of arguments. Note that the arguments are shifted down
98   - * so that 0 is the first argument not processed by U-Boot, and
99   - * argc is adjusted accordingly. This avoids confusion as to how
100   - * many arguments are available for the OS.
101   - * @images: Pointers to os/initrd/fdt
102   - * @return 1 on error. On success the OS boots so this function does
103   - * not return.
104   - */
105   -typedef int boot_os_fn(int flag, int argc, char * const argv[],
106   - bootm_headers_t *images);
107   -
108   -#ifdef CONFIG_BOOTM_LINUX
109   -extern boot_os_fn do_bootm_linux;
110   -#endif
111   -#ifdef CONFIG_BOOTM_NETBSD
112   -static boot_os_fn do_bootm_netbsd;
113   -#endif
114   -#if defined(CONFIG_LYNXKDI)
115   -static boot_os_fn do_bootm_lynxkdi;
116   -extern void lynxkdi_boot(image_header_t *);
117   -#endif
118   -#ifdef CONFIG_BOOTM_RTEMS
119   -static boot_os_fn do_bootm_rtems;
120   -#endif
121   -#if defined(CONFIG_BOOTM_OSE)
122   -static boot_os_fn do_bootm_ose;
123   -#endif
124   -#if defined(CONFIG_BOOTM_PLAN9)
125   -static boot_os_fn do_bootm_plan9;
126   -#endif
127   -#if defined(CONFIG_BOOTM_VXWORKS) && \
128   - (defined(CONFIG_PPC) || defined(CONFIG_ARM))
129   -static boot_os_fn do_bootm_vxworks;
130   -#endif
131   -#if defined(CONFIG_CMD_ELF)
132   -static boot_os_fn do_bootm_qnxelf;
133   -int do_bootvx(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]);
134   -int do_bootelf(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]);
135   -#endif
136   -#if defined(CONFIG_INTEGRITY)
137   -static boot_os_fn do_bootm_integrity;
138   -#endif
139   -
140   -static boot_os_fn *boot_os[] = {
141   - [IH_OS_U_BOOT] = do_bootm_standalone,
142   -#ifdef CONFIG_BOOTM_LINUX
143   - [IH_OS_LINUX] = do_bootm_linux,
144   -#endif
145   -#ifdef CONFIG_BOOTM_NETBSD
146   - [IH_OS_NETBSD] = do_bootm_netbsd,
147   -#endif
148   -#ifdef CONFIG_LYNXKDI
149   - [IH_OS_LYNXOS] = do_bootm_lynxkdi,
150   -#endif
151   -#ifdef CONFIG_BOOTM_RTEMS
152   - [IH_OS_RTEMS] = do_bootm_rtems,
153   -#endif
154   -#if defined(CONFIG_BOOTM_OSE)
155   - [IH_OS_OSE] = do_bootm_ose,
156   -#endif
157   -#if defined(CONFIG_BOOTM_PLAN9)
158   - [IH_OS_PLAN9] = do_bootm_plan9,
159   -#endif
160   -#if defined(CONFIG_BOOTM_VXWORKS) && \
161   - (defined(CONFIG_PPC) || defined(CONFIG_ARM))
162   - [IH_OS_VXWORKS] = do_bootm_vxworks,
163   -#endif
164   -#if defined(CONFIG_CMD_ELF)
165   - [IH_OS_QNX] = do_bootm_qnxelf,
166   -#endif
167   -#ifdef CONFIG_INTEGRITY
168   - [IH_OS_INTEGRITY] = do_bootm_integrity,
169   -#endif
170   -};
171   -
172 41 bootm_headers_t images; /* pointers to os/initrd/fdt images */
173 42  
174   -/* Allow for arch specific config before we boot */
175   -static void __arch_preboot_os(void)
176   -{
177   - /* please define platform specific arch_preboot_os() */
178   -}
179   -void arch_preboot_os(void) __attribute__((weak, alias("__arch_preboot_os")));
180   -
181   -#define IH_INITRD_ARCH IH_ARCH_DEFAULT
182   -
183   -#ifdef CONFIG_LMB
184   -static void boot_start_lmb(bootm_headers_t *images)
185   -{
186   - ulong mem_start;
187   - phys_size_t mem_size;
188   -
189   - lmb_init(&images->lmb);
190   -
191   - mem_start = getenv_bootm_low();
192   - mem_size = getenv_bootm_size();
193   -
194   - lmb_add(&images->lmb, (phys_addr_t)mem_start, mem_size);
195   -
196   - arch_lmb_reserve(&images->lmb);
197   - board_lmb_reserve(&images->lmb);
198   -}
199   -#else
200   -#define lmb_reserve(lmb, base, size)
201   -static inline void boot_start_lmb(bootm_headers_t *images) { }
202   -#endif
203   -
204   -static int bootm_start(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
205   -{
206   - memset((void *)&images, 0, sizeof(images));
207   - images.verify = getenv_yesno("verify");
208   -
209   - boot_start_lmb(&images);
210   -
211   - bootstage_mark_name(BOOTSTAGE_ID_BOOTM_START, "bootm_start");
212   - images.state = BOOTM_STATE_START;
213   -
214   - return 0;
215   -}
216   -
217   -static int bootm_find_os(cmd_tbl_t *cmdtp, int flag, int argc,
218   - char * const argv[])
219   -{
220   - const void *os_hdr;
221   - bool ep_found = false;
222   -
223   - /* get kernel image header, start address and length */
224   - os_hdr = boot_get_kernel(cmdtp, flag, argc, argv,
225   - &images, &images.os.image_start, &images.os.image_len);
226   - if (images.os.image_len == 0) {
227   - puts("ERROR: can't get kernel image!\n");
228   - return 1;
229   - }
230   -
231   - /* get image parameters */
232   - switch (genimg_get_format(os_hdr)) {
233   -#if defined(CONFIG_IMAGE_FORMAT_LEGACY)
234   - case IMAGE_FORMAT_LEGACY:
235   - images.os.type = image_get_type(os_hdr);
236   - images.os.comp = image_get_comp(os_hdr);
237   - images.os.os = image_get_os(os_hdr);
238   -
239   - images.os.end = image_get_image_end(os_hdr);
240   - images.os.load = image_get_load(os_hdr);
241   - break;
242   -#endif
243   -#if defined(CONFIG_FIT)
244   - case IMAGE_FORMAT_FIT:
245   - if (fit_image_get_type(images.fit_hdr_os,
246   - images.fit_noffset_os, &images.os.type)) {
247   - puts("Can't get image type!\n");
248   - bootstage_error(BOOTSTAGE_ID_FIT_TYPE);
249   - return 1;
250   - }
251   -
252   - if (fit_image_get_comp(images.fit_hdr_os,
253   - images.fit_noffset_os, &images.os.comp)) {
254   - puts("Can't get image compression!\n");
255   - bootstage_error(BOOTSTAGE_ID_FIT_COMPRESSION);
256   - return 1;
257   - }
258   -
259   - if (fit_image_get_os(images.fit_hdr_os,
260   - images.fit_noffset_os, &images.os.os)) {
261   - puts("Can't get image OS!\n");
262   - bootstage_error(BOOTSTAGE_ID_FIT_OS);
263   - return 1;
264   - }
265   -
266   - images.os.end = fit_get_end(images.fit_hdr_os);
267   -
268   - if (fit_image_get_load(images.fit_hdr_os, images.fit_noffset_os,
269   - &images.os.load)) {
270   - puts("Can't get image load address!\n");
271   - bootstage_error(BOOTSTAGE_ID_FIT_LOADADDR);
272   - return 1;
273   - }
274   - break;
275   -#endif
276   -#ifdef CONFIG_ANDROID_BOOT_IMAGE
277   - case IMAGE_FORMAT_ANDROID:
278   - images.os.type = IH_TYPE_KERNEL;
279   - images.os.comp = IH_COMP_NONE;
280   - images.os.os = IH_OS_LINUX;
281   - images.ep = images.os.load;
282   - ep_found = true;
283   -
284   - images.os.end = android_image_get_end(os_hdr);
285   - images.os.load = android_image_get_kload(os_hdr);
286   - break;
287   -#endif
288   - default:
289   - puts("ERROR: unknown image format type!\n");
290   - return 1;
291   - }
292   -
293   - /* find kernel entry point */
294   - if (images.legacy_hdr_valid) {
295   - images.ep = image_get_ep(&images.legacy_hdr_os_copy);
296   -#if defined(CONFIG_FIT)
297   - } else if (images.fit_uname_os) {
298   - int ret;
299   -
300   - ret = fit_image_get_entry(images.fit_hdr_os,
301   - images.fit_noffset_os, &images.ep);
302   - if (ret) {
303   - puts("Can't get entry point property!\n");
304   - return 1;
305   - }
306   -#endif
307   - } else if (!ep_found) {
308   - puts("Could not find kernel entry point!\n");
309   - return 1;
310   - }
311   -
312   - if (images.os.type == IH_TYPE_KERNEL_NOLOAD) {
313   - images.os.load = images.os.image_start;
314   - images.ep += images.os.load;
315   - }
316   -
317   - images.os.start = (ulong)os_hdr;
318   -
319   - return 0;
320   -}
321   -
322   -static int bootm_find_ramdisk(int flag, int argc, char * const argv[])
323   -{
324   - int ret;
325   -
326   - /* find ramdisk */
327   - ret = boot_get_ramdisk(argc, argv, &images, IH_INITRD_ARCH,
328   - &images.rd_start, &images.rd_end);
329   - if (ret) {
330   - puts("Ramdisk image is corrupt or invalid\n");
331   - return 1;
332   - }
333   -
334   - return 0;
335   -}
336   -
337   -#if defined(CONFIG_OF_LIBFDT)
338   -static int bootm_find_fdt(int flag, int argc, char * const argv[])
339   -{
340   - int ret;
341   -
342   - /* find flattened device tree */
343   - ret = boot_get_fdt(flag, argc, argv, IH_ARCH_DEFAULT, &images,
344   - &images.ft_addr, &images.ft_len);
345   - if (ret) {
346   - puts("Could not find a valid device tree\n");
347   - return 1;
348   - }
349   -
350   - set_working_fdt_addr(images.ft_addr);
351   -
352   - return 0;
353   -}
354   -#endif
355   -
356   -static int bootm_find_other(cmd_tbl_t *cmdtp, int flag, int argc,
357   - char * const argv[])
358   -{
359   - if (((images.os.type == IH_TYPE_KERNEL) ||
360   - (images.os.type == IH_TYPE_KERNEL_NOLOAD) ||
361   - (images.os.type == IH_TYPE_MULTI)) &&
362   - (images.os.os == IH_OS_LINUX ||
363   - images.os.os == IH_OS_VXWORKS)) {
364   - if (bootm_find_ramdisk(flag, argc, argv))
365   - return 1;
366   -
367   -#if defined(CONFIG_OF_LIBFDT)
368   - if (bootm_find_fdt(flag, argc, argv))
369   - return 1;
370   -#endif
371   - }
372   -
373   - return 0;
374   -}
375   -
376   -#define BOOTM_ERR_RESET -1
377   -#define BOOTM_ERR_OVERLAP -2
378   -#define BOOTM_ERR_UNIMPLEMENTED -3
379   -static int bootm_load_os(bootm_headers_t *images, unsigned long *load_end,
380   - int boot_progress)
381   -{
382   - image_info_t os = images->os;
383   - uint8_t comp = os.comp;
384   - ulong load = os.load;
385   - ulong blob_start = os.start;
386   - ulong blob_end = os.end;
387   - ulong image_start = os.image_start;
388   - ulong image_len = os.image_len;
389   - __maybe_unused uint unc_len = CONFIG_SYS_BOOTM_LEN;
390   - int no_overlap = 0;
391   - void *load_buf, *image_buf;
392   -#if defined(CONFIG_LZMA) || defined(CONFIG_LZO)
393   - int ret;
394   -#endif /* defined(CONFIG_LZMA) || defined(CONFIG_LZO) */
395   -
396   - const char *type_name = genimg_get_type_name(os.type);
397   -
398   - load_buf = map_sysmem(load, unc_len);
399   - image_buf = map_sysmem(image_start, image_len);
400   - switch (comp) {
401   - case IH_COMP_NONE:
402   - if (load == image_start) {
403   - printf(" XIP %s ... ", type_name);
404   - no_overlap = 1;
405   - } else {
406   - printf(" Loading %s ... ", type_name);
407   - memmove_wd(load_buf, image_buf, image_len, CHUNKSZ);
408   - }
409   - *load_end = load + image_len;
410   - break;
411   -#ifdef CONFIG_GZIP
412   - case IH_COMP_GZIP:
413   - printf(" Uncompressing %s ... ", type_name);
414   - if (gunzip(load_buf, unc_len, image_buf, &image_len) != 0) {
415   - puts("GUNZIP: uncompress, out-of-mem or overwrite "
416   - "error - must RESET board to recover\n");
417   - if (boot_progress)
418   - bootstage_error(BOOTSTAGE_ID_DECOMP_IMAGE);
419   - return BOOTM_ERR_RESET;
420   - }
421   -
422   - *load_end = load + image_len;
423   - break;
424   -#endif /* CONFIG_GZIP */
425   -#ifdef CONFIG_BZIP2
426   - case IH_COMP_BZIP2:
427   - printf(" Uncompressing %s ... ", type_name);
428   - /*
429   - * If we've got less than 4 MB of malloc() space,
430   - * use slower decompression algorithm which requires
431   - * at most 2300 KB of memory.
432   - */
433   - int i = BZ2_bzBuffToBuffDecompress(load_buf, &unc_len,
434   - image_buf, image_len,
435   - CONFIG_SYS_MALLOC_LEN < (4096 * 1024), 0);
436   - if (i != BZ_OK) {
437   - printf("BUNZIP2: uncompress or overwrite error %d "
438   - "- must RESET board to recover\n", i);
439   - if (boot_progress)
440   - bootstage_error(BOOTSTAGE_ID_DECOMP_IMAGE);
441   - return BOOTM_ERR_RESET;
442   - }
443   -
444   - *load_end = load + unc_len;
445   - break;
446   -#endif /* CONFIG_BZIP2 */
447   -#ifdef CONFIG_LZMA
448   - case IH_COMP_LZMA: {
449   - SizeT lzma_len = unc_len;
450   - printf(" Uncompressing %s ... ", type_name);
451   -
452   - ret = lzmaBuffToBuffDecompress(load_buf, &lzma_len,
453   - image_buf, image_len);
454   - unc_len = lzma_len;
455   - if (ret != SZ_OK) {
456   - printf("LZMA: uncompress or overwrite error %d "
457   - "- must RESET board to recover\n", ret);
458   - bootstage_error(BOOTSTAGE_ID_DECOMP_IMAGE);
459   - return BOOTM_ERR_RESET;
460   - }
461   - *load_end = load + unc_len;
462   - break;
463   - }
464   -#endif /* CONFIG_LZMA */
465   -#ifdef CONFIG_LZO
466   - case IH_COMP_LZO: {
467   - size_t size = unc_len;
468   -
469   - printf(" Uncompressing %s ... ", type_name);
470   -
471   - ret = lzop_decompress(image_buf, image_len, load_buf, &size);
472   - if (ret != LZO_E_OK) {
473   - printf("LZO: uncompress or overwrite error %d "
474   - "- must RESET board to recover\n", ret);
475   - if (boot_progress)
476   - bootstage_error(BOOTSTAGE_ID_DECOMP_IMAGE);
477   - return BOOTM_ERR_RESET;
478   - }
479   -
480   - *load_end = load + size;
481   - break;
482   - }
483   -#endif /* CONFIG_LZO */
484   - default:
485   - printf("Unimplemented compression type %d\n", comp);
486   - return BOOTM_ERR_UNIMPLEMENTED;
487   - }
488   -
489   - flush_cache(load, (*load_end - load) * sizeof(ulong));
490   -
491   - puts("OK\n");
492   - debug(" kernel loaded at 0x%08lx, end = 0x%08lx\n", load, *load_end);
493   - bootstage_mark(BOOTSTAGE_ID_KERNEL_LOADED);
494   -
495   - if (!no_overlap && (load < blob_end) && (*load_end > blob_start)) {
496   - debug("images.os.start = 0x%lX, images.os.end = 0x%lx\n",
497   - blob_start, blob_end);
498   - debug("images.os.load = 0x%lx, load_end = 0x%lx\n", load,
499   - *load_end);
500   -
501   - /* Check what type of image this is. */
502   - if (images->legacy_hdr_valid) {
503   - if (image_get_type(&images->legacy_hdr_os_copy)
504   - == IH_TYPE_MULTI)
505   - puts("WARNING: legacy format multi component image overwritten\n");
506   - return BOOTM_ERR_OVERLAP;
507   - } else {
508   - puts("ERROR: new format image overwritten - must RESET the board to recover\n");
509   - bootstage_error(BOOTSTAGE_ID_OVERWRITTEN);
510   - return BOOTM_ERR_RESET;
511   - }
512   - }
513   -
514   - return 0;
515   -}
516   -
517   -static int do_bootm_standalone(int flag, int argc, char * const argv[],
518   - bootm_headers_t *images)
519   -{
520   - char *s;
521   - int (*appl)(int, char * const []);
522   -
523   - /* Don't start if "autostart" is set to "no" */
524   - if (((s = getenv("autostart")) != NULL) && (strcmp(s, "no") == 0)) {
525   - setenv_hex("filesize", images->os.image_len);
526   - return 0;
527   - }
528   - appl = (int (*)(int, char * const []))images->ep;
529   - appl(argc, argv);
530   - return 0;
531   -}
532   -
533 43 /* we overload the cmd field with our state machine info instead of a
534 44 * function pointer */
535 45 static cmd_tbl_t cmd_bootm_sub[] = {
... ... @@ -548,210 +58,6 @@
548 58 U_BOOT_CMD_MKENT(go, 0, 1, (void *)BOOTM_STATE_OS_GO, "", ""),
549 59 };
550 60  
551   -static int boot_selected_os(int argc, char * const argv[], int state,
552   - bootm_headers_t *images, boot_os_fn *boot_fn)
553   -{
554   - arch_preboot_os();
555   - boot_fn(state, argc, argv, images);
556   -
557   - /* Stand-alone may return when 'autostart' is 'no' */
558   - if (images->os.type == IH_TYPE_STANDALONE ||
559   - state == BOOTM_STATE_OS_FAKE_GO) /* We expect to return */
560   - return 0;
561   - bootstage_error(BOOTSTAGE_ID_BOOT_OS_RETURNED);
562   -#ifdef DEBUG
563   - puts("\n## Control returned to monitor - resetting...\n");
564   -#endif
565   - return BOOTM_ERR_RESET;
566   -}
567   -
568   -/**
569   - * bootm_disable_interrupts() - Disable interrupts in preparation for load/boot
570   - *
571   - * @return interrupt flag (0 if interrupts were disabled, non-zero if they were
572   - * enabled)
573   - */
574   -static ulong bootm_disable_interrupts(void)
575   -{
576   - ulong iflag;
577   -
578   - /*
579   - * We have reached the point of no return: we are going to
580   - * overwrite all exception vector code, so we cannot easily
581   - * recover from any failures any more...
582   - */
583   - iflag = disable_interrupts();
584   -#ifdef CONFIG_NETCONSOLE
585   - /* Stop the ethernet stack if NetConsole could have left it up */
586   - eth_halt();
587   - eth_unregister(eth_get_dev());
588   -#endif
589   -
590   -#if defined(CONFIG_CMD_USB)
591   - /*
592   - * turn off USB to prevent the host controller from writing to the
593   - * SDRAM while Linux is booting. This could happen (at least for OHCI
594   - * controller), because the HCCA (Host Controller Communication Area)
595   - * lies within the SDRAM and the host controller writes continously to
596   - * this area (as busmaster!). The HccaFrameNumber is for example
597   - * updated every 1 ms within the HCCA structure in SDRAM! For more
598   - * details see the OpenHCI specification.
599   - */
600   - usb_stop();
601   -#endif
602   - return iflag;
603   -}
604   -
605   -/**
606   - * Execute selected states of the bootm command.
607   - *
608   - * Note the arguments to this state must be the first argument, Any 'bootm'
609   - * or sub-command arguments must have already been taken.
610   - *
611   - * Note that if states contains more than one flag it MUST contain
612   - * BOOTM_STATE_START, since this handles and consumes the command line args.
613   - *
614   - * Also note that aside from boot_os_fn functions and bootm_load_os no other
615   - * functions we store the return value of in 'ret' may use a negative return
616   - * value, without special handling.
617   - *
618   - * @param cmdtp Pointer to bootm command table entry
619   - * @param flag Command flags (CMD_FLAG_...)
620   - * @param argc Number of subcommand arguments (0 = no arguments)
621   - * @param argv Arguments
622   - * @param states Mask containing states to run (BOOTM_STATE_...)
623   - * @param images Image header information
624   - * @param boot_progress 1 to show boot progress, 0 to not do this
625   - * @return 0 if ok, something else on error. Some errors will cause this
626   - * function to perform a reboot! If states contains BOOTM_STATE_OS_GO
627   - * then the intent is to boot an OS, so this function will not return
628   - * unless the image type is standalone.
629   - */
630   -static int do_bootm_states(cmd_tbl_t *cmdtp, int flag, int argc,
631   - char * const argv[], int states, bootm_headers_t *images,
632   - int boot_progress)
633   -{
634   - boot_os_fn *boot_fn;
635   - ulong iflag = 0;
636   - int ret = 0, need_boot_fn;
637   -
638   - images->state |= states;
639   -
640   - /*
641   - * Work through the states and see how far we get. We stop on
642   - * any error.
643   - */
644   - if (states & BOOTM_STATE_START)
645   - ret = bootm_start(cmdtp, flag, argc, argv);
646   -
647   - if (!ret && (states & BOOTM_STATE_FINDOS))
648   - ret = bootm_find_os(cmdtp, flag, argc, argv);
649   -
650   - if (!ret && (states & BOOTM_STATE_FINDOTHER)) {
651   - ret = bootm_find_other(cmdtp, flag, argc, argv);
652   - argc = 0; /* consume the args */
653   - }
654   -
655   - /* Load the OS */
656   - if (!ret && (states & BOOTM_STATE_LOADOS)) {
657   - ulong load_end;
658   -
659   - iflag = bootm_disable_interrupts();
660   - ret = bootm_load_os(images, &load_end, 0);
661   - if (ret == 0)
662   - lmb_reserve(&images->lmb, images->os.load,
663   - (load_end - images->os.load));
664   - else if (ret && ret != BOOTM_ERR_OVERLAP)
665   - goto err;
666   - else if (ret == BOOTM_ERR_OVERLAP)
667   - ret = 0;
668   -#if defined(CONFIG_SILENT_CONSOLE) && !defined(CONFIG_SILENT_U_BOOT_ONLY)
669   - if (images->os.os == IH_OS_LINUX)
670   - fixup_silent_linux();
671   -#endif
672   - }
673   -
674   - /* Relocate the ramdisk */
675   -#ifdef CONFIG_SYS_BOOT_RAMDISK_HIGH
676   - if (!ret && (states & BOOTM_STATE_RAMDISK)) {
677   - ulong rd_len = images->rd_end - images->rd_start;
678   -
679   - ret = boot_ramdisk_high(&images->lmb, images->rd_start,
680   - rd_len, &images->initrd_start, &images->initrd_end);
681   - if (!ret) {
682   - setenv_hex("initrd_start", images->initrd_start);
683   - setenv_hex("initrd_end", images->initrd_end);
684   - }
685   - }
686   -#endif
687   -#if defined(CONFIG_OF_LIBFDT) && defined(CONFIG_LMB)
688   - if (!ret && (states & BOOTM_STATE_FDT)) {
689   - boot_fdt_add_mem_rsv_regions(&images->lmb, images->ft_addr);
690   - ret = boot_relocate_fdt(&images->lmb, &images->ft_addr,
691   - &images->ft_len);
692   - }
693   -#endif
694   -
695   - /* From now on, we need the OS boot function */
696   - if (ret)
697   - return ret;
698   - boot_fn = boot_os[images->os.os];
699   - need_boot_fn = states & (BOOTM_STATE_OS_CMDLINE |
700   - BOOTM_STATE_OS_BD_T | BOOTM_STATE_OS_PREP |
701   - BOOTM_STATE_OS_FAKE_GO | BOOTM_STATE_OS_GO);
702   - if (boot_fn == NULL && need_boot_fn) {
703   - if (iflag)
704   - enable_interrupts();
705   - printf("ERROR: booting os '%s' (%d) is not supported\n",
706   - genimg_get_os_name(images->os.os), images->os.os);
707   - bootstage_error(BOOTSTAGE_ID_CHECK_BOOT_OS);
708   - return 1;
709   - }
710   -
711   - /* Call various other states that are not generally used */
712   - if (!ret && (states & BOOTM_STATE_OS_CMDLINE))
713   - ret = boot_fn(BOOTM_STATE_OS_CMDLINE, argc, argv, images);
714   - if (!ret && (states & BOOTM_STATE_OS_BD_T))
715   - ret = boot_fn(BOOTM_STATE_OS_BD_T, argc, argv, images);
716   - if (!ret && (states & BOOTM_STATE_OS_PREP))
717   - ret = boot_fn(BOOTM_STATE_OS_PREP, argc, argv, images);
718   -
719   -#ifdef CONFIG_TRACE
720   - /* Pretend to run the OS, then run a user command */
721   - if (!ret && (states & BOOTM_STATE_OS_FAKE_GO)) {
722   - char *cmd_list = getenv("fakegocmd");
723   -
724   - ret = boot_selected_os(argc, argv, BOOTM_STATE_OS_FAKE_GO,
725   - images, boot_fn);
726   - if (!ret && cmd_list)
727   - ret = run_command_list(cmd_list, -1, flag);
728   - }
729   -#endif
730   -
731   - /* Check for unsupported subcommand. */
732   - if (ret) {
733   - puts("subcommand not supported\n");
734   - return ret;
735   - }
736   -
737   - /* Now run the OS! We hope this doesn't return */
738   - if (!ret && (states & BOOTM_STATE_OS_GO))
739   - ret = boot_selected_os(argc, argv, BOOTM_STATE_OS_GO,
740   - images, boot_fn);
741   -
742   - /* Deal with any fallout */
743   -err:
744   - if (iflag)
745   - enable_interrupts();
746   -
747   - if (ret == BOOTM_ERR_UNIMPLEMENTED)
748   - bootstage_error(BOOTSTAGE_ID_DECOMP_UNIMPL);
749   - else if (ret == BOOTM_ERR_RESET)
750   - do_reset(cmdtp, flag, argc, argv);
751   -
752   - return ret;
753   -}
754   -
755 61 static int do_bootm_subcommand(cmd_tbl_t *cmdtp, int flag, int argc,
756 62 char * const argv[])
757 63 {
... ... @@ -793,11 +99,6 @@
793 99 if (!relocated) {
794 100 int i;
795 101  
796   - /* relocate boot function table */
797   - for (i = 0; i < ARRAY_SIZE(boot_os); i++)
798   - if (boot_os[i] != NULL)
799   - boot_os[i] += gd->reloc_off;
800   -
801 102 /* relocate names of sub-command table */
802 103 for (i = 0; i < ARRAY_SIZE(cmd_bootm_sub); i++)
803 104 cmd_bootm_sub[i].name += gd->reloc_off;
... ... @@ -849,196 +150,6 @@
849 150 return 0;
850 151 }
851 152  
852   -#if defined(CONFIG_IMAGE_FORMAT_LEGACY)
853   -/**
854   - * image_get_kernel - verify legacy format kernel image
855   - * @img_addr: in RAM address of the legacy format image to be verified
856   - * @verify: data CRC verification flag
857   - *
858   - * image_get_kernel() verifies legacy image integrity and returns pointer to
859   - * legacy image header if image verification was completed successfully.
860   - *
861   - * returns:
862   - * pointer to a legacy image header if valid image was found
863   - * otherwise return NULL
864   - */
865   -static image_header_t *image_get_kernel(ulong img_addr, int verify)
866   -{
867   - image_header_t *hdr = (image_header_t *)img_addr;
868   -
869   - if (!image_check_magic(hdr)) {
870   - puts("Bad Magic Number\n");
871   - bootstage_error(BOOTSTAGE_ID_CHECK_MAGIC);
872   - return NULL;
873   - }
874   - bootstage_mark(BOOTSTAGE_ID_CHECK_HEADER);
875   -
876   - if (!image_check_hcrc(hdr)) {
877   - puts("Bad Header Checksum\n");
878   - bootstage_error(BOOTSTAGE_ID_CHECK_HEADER);
879   - return NULL;
880   - }
881   -
882   - bootstage_mark(BOOTSTAGE_ID_CHECK_CHECKSUM);
883   - image_print_contents(hdr);
884   -
885   - if (verify) {
886   - puts(" Verifying Checksum ... ");
887   - if (!image_check_dcrc(hdr)) {
888   - printf("Bad Data CRC\n");
889   - bootstage_error(BOOTSTAGE_ID_CHECK_CHECKSUM);
890   - return NULL;
891   - }
892   - puts("OK\n");
893   - }
894   - bootstage_mark(BOOTSTAGE_ID_CHECK_ARCH);
895   -
896   - if (!image_check_target_arch(hdr)) {
897   - printf("Unsupported Architecture 0x%x\n", image_get_arch(hdr));
898   - bootstage_error(BOOTSTAGE_ID_CHECK_ARCH);
899   - return NULL;
900   - }
901   - return hdr;
902   -}
903   -#endif
904   -
905   -/**
906   - * boot_get_kernel - find kernel image
907   - * @os_data: pointer to a ulong variable, will hold os data start address
908   - * @os_len: pointer to a ulong variable, will hold os data length
909   - *
910   - * boot_get_kernel() tries to find a kernel image, verifies its integrity
911   - * and locates kernel data.
912   - *
913   - * returns:
914   - * pointer to image header if valid image was found, plus kernel start
915   - * address and length, otherwise NULL
916   - */
917   -static const void *boot_get_kernel(cmd_tbl_t *cmdtp, int flag, int argc,
918   - char * const argv[], bootm_headers_t *images, ulong *os_data,
919   - ulong *os_len)
920   -{
921   -#if defined(CONFIG_IMAGE_FORMAT_LEGACY)
922   - image_header_t *hdr;
923   -#endif
924   - ulong img_addr;
925   - const void *buf;
926   -#if defined(CONFIG_FIT)
927   - const char *fit_uname_config = NULL;
928   - const char *fit_uname_kernel = NULL;
929   - int os_noffset;
930   -#endif
931   -
932   - /* find out kernel image address */
933   - if (argc < 1) {
934   - img_addr = load_addr;
935   - debug("* kernel: default image load address = 0x%08lx\n",
936   - load_addr);
937   -#if defined(CONFIG_FIT)
938   - } else if (fit_parse_conf(argv[0], load_addr, &img_addr,
939   - &fit_uname_config)) {
940   - debug("* kernel: config '%s' from image at 0x%08lx\n",
941   - fit_uname_config, img_addr);
942   - } else if (fit_parse_subimage(argv[0], load_addr, &img_addr,
943   - &fit_uname_kernel)) {
944   - debug("* kernel: subimage '%s' from image at 0x%08lx\n",
945   - fit_uname_kernel, img_addr);
946   -#endif
947   - } else {
948   - img_addr = simple_strtoul(argv[0], NULL, 16);
949   - debug("* kernel: cmdline image address = 0x%08lx\n", img_addr);
950   - }
951   -
952   - bootstage_mark(BOOTSTAGE_ID_CHECK_MAGIC);
953   -
954   - /* copy from dataflash if needed */
955   - img_addr = genimg_get_image(img_addr);
956   -
957   - /* check image type, for FIT images get FIT kernel node */
958   - *os_data = *os_len = 0;
959   - buf = map_sysmem(img_addr, 0);
960   - switch (genimg_get_format(buf)) {
961   -#if defined(CONFIG_IMAGE_FORMAT_LEGACY)
962   - case IMAGE_FORMAT_LEGACY:
963   - printf("## Booting kernel from Legacy Image at %08lx ...\n",
964   - img_addr);
965   - hdr = image_get_kernel(img_addr, images->verify);
966   - if (!hdr)
967   - return NULL;
968   - bootstage_mark(BOOTSTAGE_ID_CHECK_IMAGETYPE);
969   -
970   - /* get os_data and os_len */
971   - switch (image_get_type(hdr)) {
972   - case IH_TYPE_KERNEL:
973   - case IH_TYPE_KERNEL_NOLOAD:
974   - *os_data = image_get_data(hdr);
975   - *os_len = image_get_data_size(hdr);
976   - break;
977   - case IH_TYPE_MULTI:
978   - image_multi_getimg(hdr, 0, os_data, os_len);
979   - break;
980   - case IH_TYPE_STANDALONE:
981   - *os_data = image_get_data(hdr);
982   - *os_len = image_get_data_size(hdr);
983   - break;
984   - default:
985   - printf("Wrong Image Type for %s command\n",
986   - cmdtp->name);
987   - bootstage_error(BOOTSTAGE_ID_CHECK_IMAGETYPE);
988   - return NULL;
989   - }
990   -
991   - /*
992   - * copy image header to allow for image overwrites during
993   - * kernel decompression.
994   - */
995   - memmove(&images->legacy_hdr_os_copy, hdr,
996   - sizeof(image_header_t));
997   -
998   - /* save pointer to image header */
999   - images->legacy_hdr_os = hdr;
1000   -
1001   - images->legacy_hdr_valid = 1;
1002   - bootstage_mark(BOOTSTAGE_ID_DECOMP_IMAGE);
1003   - break;
1004   -#endif
1005   -#if defined(CONFIG_FIT)
1006   - case IMAGE_FORMAT_FIT:
1007   - os_noffset = fit_image_load(images, FIT_KERNEL_PROP,
1008   - img_addr,
1009   - &fit_uname_kernel, &fit_uname_config,
1010   - IH_ARCH_DEFAULT, IH_TYPE_KERNEL,
1011   - BOOTSTAGE_ID_FIT_KERNEL_START,
1012   - FIT_LOAD_IGNORED, os_data, os_len);
1013   - if (os_noffset < 0)
1014   - return NULL;
1015   -
1016   - images->fit_hdr_os = map_sysmem(img_addr, 0);
1017   - images->fit_uname_os = fit_uname_kernel;
1018   - images->fit_uname_cfg = fit_uname_config;
1019   - images->fit_noffset_os = os_noffset;
1020   - break;
1021   -#endif
1022   -#ifdef CONFIG_ANDROID_BOOT_IMAGE
1023   - case IMAGE_FORMAT_ANDROID:
1024   - printf("## Booting Android Image at 0x%08lx ...\n", img_addr);
1025   - if (android_image_get_kernel((void *)img_addr, images->verify,
1026   - os_data, os_len))
1027   - return NULL;
1028   - break;
1029   -#endif
1030   - default:
1031   - printf("Wrong Image Format for %s command\n", cmdtp->name);
1032   - bootstage_error(BOOTSTAGE_ID_FIT_KERNEL_INFO);
1033   - return NULL;
1034   - }
1035   -
1036   - debug(" kernel data at 0x%08lx, len = 0x%08lx (%ld)\n",
1037   - *os_data, *os_len, *os_len);
1038   -
1039   - return buf;
1040   -}
1041   -
1042 153 #ifdef CONFIG_SYS_LONGHELP
1043 154 static char bootm_help_text[] =
1044 155 "[addr [arg ...]]\n - boot application image stored in memory\n"
... ... @@ -1420,441 +531,6 @@
1420 531 );
1421 532 #endif
1422 533  
1423   -/*******************************************************************/
1424   -/* helper routines */
1425   -/*******************************************************************/
1426   -#if defined(CONFIG_SILENT_CONSOLE) && !defined(CONFIG_SILENT_U_BOOT_ONLY)
1427   -
1428   -#define CONSOLE_ARG "console="
1429   -#define CONSOLE_ARG_LEN (sizeof(CONSOLE_ARG) - 1)
1430   -
1431   -static void fixup_silent_linux(void)
1432   -{
1433   - char *buf;
1434   - const char *env_val;
1435   - char *cmdline = getenv("bootargs");
1436   - int want_silent;
1437   -
1438   - /*
1439   - * Only fix cmdline when requested. The environment variable can be:
1440   - *
1441   - * no - we never fixup
1442   - * yes - we always fixup
1443   - * unset - we rely on the console silent flag
1444   - */
1445   - want_silent = getenv_yesno("silent_linux");
1446   - if (want_silent == 0)
1447   - return;
1448   - else if (want_silent == -1 && !(gd->flags & GD_FLG_SILENT))
1449   - return;
1450   -
1451   - debug("before silent fix-up: %s\n", cmdline);
1452   - if (cmdline && (cmdline[0] != '\0')) {
1453   - char *start = strstr(cmdline, CONSOLE_ARG);
1454   -
1455   - /* Allocate space for maximum possible new command line */
1456   - buf = malloc(strlen(cmdline) + 1 + CONSOLE_ARG_LEN + 1);
1457   - if (!buf) {
1458   - debug("%s: out of memory\n", __func__);
1459   - return;
1460   - }
1461   -
1462   - if (start) {
1463   - char *end = strchr(start, ' ');
1464   - int num_start_bytes = start - cmdline + CONSOLE_ARG_LEN;
1465   -
1466   - strncpy(buf, cmdline, num_start_bytes);
1467   - if (end)
1468   - strcpy(buf + num_start_bytes, end);
1469   - else
1470   - buf[num_start_bytes] = '\0';
1471   - } else {
1472   - sprintf(buf, "%s %s", cmdline, CONSOLE_ARG);
1473   - }
1474   - env_val = buf;
1475   - } else {
1476   - buf = NULL;
1477   - env_val = CONSOLE_ARG;
1478   - }
1479   -
1480   - setenv("bootargs", env_val);
1481   - debug("after silent fix-up: %s\n", env_val);
1482   - free(buf);
1483   -}
1484   -#endif /* CONFIG_SILENT_CONSOLE */
1485   -
1486   -#if defined(CONFIG_BOOTM_NETBSD) || defined(CONFIG_BOOTM_PLAN9)
1487   -static void copy_args(char *dest, int argc, char * const argv[], char delim)
1488   -{
1489   - int i;
1490   -
1491   - for (i = 0; i < argc; i++) {
1492   - if (i > 0)
1493   - *dest++ = delim;
1494   - strcpy(dest, argv[i]);
1495   - dest += strlen(argv[i]);
1496   - }
1497   -}
1498   -#endif
1499   -
1500   -/*******************************************************************/
1501   -/* OS booting routines */
1502   -/*******************************************************************/
1503   -
1504   -#ifdef CONFIG_BOOTM_NETBSD
1505   -static int do_bootm_netbsd(int flag, int argc, char * const argv[],
1506   - bootm_headers_t *images)
1507   -{
1508   - void (*loader)(bd_t *, image_header_t *, char *, char *);
1509   - image_header_t *os_hdr, *hdr;
1510   - ulong kernel_data, kernel_len;
1511   - char *consdev;
1512   - char *cmdline;
1513   -
1514   - if (flag != BOOTM_STATE_OS_GO)
1515   - return 0;
1516   -
1517   -#if defined(CONFIG_FIT)
1518   - if (!images->legacy_hdr_valid) {
1519   - fit_unsupported_reset("NetBSD");
1520   - return 1;
1521   - }
1522   -#endif
1523   - hdr = images->legacy_hdr_os;
1524   -
1525   - /*
1526   - * Booting a (NetBSD) kernel image
1527   - *
1528   - * This process is pretty similar to a standalone application:
1529   - * The (first part of an multi-) image must be a stage-2 loader,
1530   - * which in turn is responsible for loading & invoking the actual
1531   - * kernel. The only differences are the parameters being passed:
1532   - * besides the board info strucure, the loader expects a command
1533   - * line, the name of the console device, and (optionally) the
1534   - * address of the original image header.
1535   - */
1536   - os_hdr = NULL;
1537   - if (image_check_type(&images->legacy_hdr_os_copy, IH_TYPE_MULTI)) {
1538   - image_multi_getimg(hdr, 1, &kernel_data, &kernel_len);
1539   - if (kernel_len)
1540   - os_hdr = hdr;
1541   - }
1542   -
1543   - consdev = "";
1544   -#if defined(CONFIG_8xx_CONS_SMC1)
1545   - consdev = "smc1";
1546   -#elif defined(CONFIG_8xx_CONS_SMC2)
1547   - consdev = "smc2";
1548   -#elif defined(CONFIG_8xx_CONS_SCC2)
1549   - consdev = "scc2";
1550   -#elif defined(CONFIG_8xx_CONS_SCC3)
1551   - consdev = "scc3";
1552   -#endif
1553   -
1554   - if (argc > 0) {
1555   - ulong len;
1556   - int i;
1557   -
1558   - for (i = 0, len = 0; i < argc; i += 1)
1559   - len += strlen(argv[i]) + 1;
1560   - cmdline = malloc(len);
1561   - copy_args(cmdline, argc, argv, ' ');
1562   - } else if ((cmdline = getenv("bootargs")) == NULL) {
1563   - cmdline = "";
1564   - }
1565   -
1566   - loader = (void (*)(bd_t *, image_header_t *, char *, char *))images->ep;
1567   -
1568   - printf("## Transferring control to NetBSD stage-2 loader "
1569   - "(at address %08lx) ...\n",
1570   - (ulong)loader);
1571   -
1572   - bootstage_mark(BOOTSTAGE_ID_RUN_OS);
1573   -
1574   - /*
1575   - * NetBSD Stage-2 Loader Parameters:
1576   - * arg[0]: pointer to board info data
1577   - * arg[1]: image load address
1578   - * arg[2]: char pointer to the console device to use
1579   - * arg[3]: char pointer to the boot arguments
1580   - */
1581   - (*loader)(gd->bd, os_hdr, consdev, cmdline);
1582   -
1583   - return 1;
1584   -}
1585   -#endif /* CONFIG_BOOTM_NETBSD*/
1586   -
1587   -#ifdef CONFIG_LYNXKDI
1588   -static int do_bootm_lynxkdi(int flag, int argc, char * const argv[],
1589   - bootm_headers_t *images)
1590   -{
1591   - image_header_t *hdr = &images->legacy_hdr_os_copy;
1592   -
1593   - if (flag != BOOTM_STATE_OS_GO)
1594   - return 0;
1595   -
1596   -#if defined(CONFIG_FIT)
1597   - if (!images->legacy_hdr_valid) {
1598   - fit_unsupported_reset("Lynx");
1599   - return 1;
1600   - }
1601   -#endif
1602   -
1603   - lynxkdi_boot((image_header_t *)hdr);
1604   -
1605   - return 1;
1606   -}
1607   -#endif /* CONFIG_LYNXKDI */
1608   -
1609   -#ifdef CONFIG_BOOTM_RTEMS
1610   -static int do_bootm_rtems(int flag, int argc, char * const argv[],
1611   - bootm_headers_t *images)
1612   -{
1613   - void (*entry_point)(bd_t *);
1614   -
1615   - if (flag != BOOTM_STATE_OS_GO)
1616   - return 0;
1617   -
1618   -#if defined(CONFIG_FIT)
1619   - if (!images->legacy_hdr_valid) {
1620   - fit_unsupported_reset("RTEMS");
1621   - return 1;
1622   - }
1623   -#endif
1624   -
1625   - entry_point = (void (*)(bd_t *))images->ep;
1626   -
1627   - printf("## Transferring control to RTEMS (at address %08lx) ...\n",
1628   - (ulong)entry_point);
1629   -
1630   - bootstage_mark(BOOTSTAGE_ID_RUN_OS);
1631   -
1632   - /*
1633   - * RTEMS Parameters:
1634   - * r3: ptr to board info data
1635   - */
1636   - (*entry_point)(gd->bd);
1637   -
1638   - return 1;
1639   -}
1640   -#endif /* CONFIG_BOOTM_RTEMS */
1641   -
1642   -#if defined(CONFIG_BOOTM_OSE)
1643   -static int do_bootm_ose(int flag, int argc, char * const argv[],
1644   - bootm_headers_t *images)
1645   -{
1646   - void (*entry_point)(void);
1647   -
1648   - if (flag != BOOTM_STATE_OS_GO)
1649   - return 0;
1650   -
1651   -#if defined(CONFIG_FIT)
1652   - if (!images->legacy_hdr_valid) {
1653   - fit_unsupported_reset("OSE");
1654   - return 1;
1655   - }
1656   -#endif
1657   -
1658   - entry_point = (void (*)(void))images->ep;
1659   -
1660   - printf("## Transferring control to OSE (at address %08lx) ...\n",
1661   - (ulong)entry_point);
1662   -
1663   - bootstage_mark(BOOTSTAGE_ID_RUN_OS);
1664   -
1665   - /*
1666   - * OSE Parameters:
1667   - * None
1668   - */
1669   - (*entry_point)();
1670   -
1671   - return 1;
1672   -}
1673   -#endif /* CONFIG_BOOTM_OSE */
1674   -
1675   -#if defined(CONFIG_BOOTM_PLAN9)
1676   -static int do_bootm_plan9(int flag, int argc, char * const argv[],
1677   - bootm_headers_t *images)
1678   -{
1679   - void (*entry_point)(void);
1680   - char *s;
1681   -
1682   - if (flag != BOOTM_STATE_OS_GO)
1683   - return 0;
1684   -
1685   -#if defined(CONFIG_FIT)
1686   - if (!images->legacy_hdr_valid) {
1687   - fit_unsupported_reset("Plan 9");
1688   - return 1;
1689   - }
1690   -#endif
1691   -
1692   - /* See README.plan9 */
1693   - s = getenv("confaddr");
1694   - if (s != NULL) {
1695   - char *confaddr = (char *)simple_strtoul(s, NULL, 16);
1696   -
1697   - if (argc > 0) {
1698   - copy_args(confaddr, argc, argv, '\n');
1699   - } else {
1700   - s = getenv("bootargs");
1701   - if (s != NULL)
1702   - strcpy(confaddr, s);
1703   - }
1704   - }
1705   -
1706   - entry_point = (void (*)(void))images->ep;
1707   -
1708   - printf("## Transferring control to Plan 9 (at address %08lx) ...\n",
1709   - (ulong)entry_point);
1710   -
1711   - bootstage_mark(BOOTSTAGE_ID_RUN_OS);
1712   -
1713   - /*
1714   - * Plan 9 Parameters:
1715   - * None
1716   - */
1717   - (*entry_point)();
1718   -
1719   - return 1;
1720   -}
1721   -#endif /* CONFIG_BOOTM_PLAN9 */
1722   -
1723   -#if defined(CONFIG_BOOTM_VXWORKS) && \
1724   - (defined(CONFIG_PPC) || defined(CONFIG_ARM))
1725   -
1726   -void do_bootvx_fdt(bootm_headers_t *images)
1727   -{
1728   -#if defined(CONFIG_OF_LIBFDT)
1729   - int ret;
1730   - char *bootline;
1731   - ulong of_size = images->ft_len;
1732   - char **of_flat_tree = &images->ft_addr;
1733   - struct lmb *lmb = &images->lmb;
1734   -
1735   - if (*of_flat_tree) {
1736   - boot_fdt_add_mem_rsv_regions(lmb, *of_flat_tree);
1737   -
1738   - ret = boot_relocate_fdt(lmb, of_flat_tree, &of_size);
1739   - if (ret)
1740   - return;
1741   -
1742   - ret = fdt_add_subnode(*of_flat_tree, 0, "chosen");
1743   - if ((ret >= 0 || ret == -FDT_ERR_EXISTS)) {
1744   - bootline = getenv("bootargs");
1745   - if (bootline) {
1746   - ret = fdt_find_and_setprop(*of_flat_tree,
1747   - "/chosen", "bootargs",
1748   - bootline,
1749   - strlen(bootline) + 1, 1);
1750   - if (ret < 0) {
1751   - printf("## ERROR: %s : %s\n", __func__,
1752   - fdt_strerror(ret));
1753   - return;
1754   - }
1755   - }
1756   - } else {
1757   - printf("## ERROR: %s : %s\n", __func__,
1758   - fdt_strerror(ret));
1759   - return;
1760   - }
1761   - }
1762   -#endif
1763   -
1764   - boot_prep_vxworks(images);
1765   -
1766   - bootstage_mark(BOOTSTAGE_ID_RUN_OS);
1767   -
1768   -#if defined(CONFIG_OF_LIBFDT)
1769   - printf("## Starting vxWorks at 0x%08lx, device tree at 0x%08lx ...\n",
1770   - (ulong)images->ep, (ulong)*of_flat_tree);
1771   -#else
1772   - printf("## Starting vxWorks at 0x%08lx\n", (ulong)images->ep);
1773   -#endif
1774   -
1775   - boot_jump_vxworks(images);
1776   -
1777   - puts("## vxWorks terminated\n");
1778   -}
1779   -
1780   -static int do_bootm_vxworks(int flag, int argc, char * const argv[],
1781   - bootm_headers_t *images)
1782   -{
1783   - if (flag != BOOTM_STATE_OS_GO)
1784   - return 0;
1785   -
1786   -#if defined(CONFIG_FIT)
1787   - if (!images->legacy_hdr_valid) {
1788   - fit_unsupported_reset("VxWorks");
1789   - return 1;
1790   - }
1791   -#endif
1792   -
1793   - do_bootvx_fdt(images);
1794   -
1795   - return 1;
1796   -}
1797   -#endif
1798   -
1799   -#if defined(CONFIG_CMD_ELF)
1800   -static int do_bootm_qnxelf(int flag, int argc, char * const argv[],
1801   - bootm_headers_t *images)
1802   -{
1803   - char *local_args[2];
1804   - char str[16];
1805   -
1806   - if (flag != BOOTM_STATE_OS_GO)
1807   - return 0;
1808   -
1809   -#if defined(CONFIG_FIT)
1810   - if (!images->legacy_hdr_valid) {
1811   - fit_unsupported_reset("QNX");
1812   - return 1;
1813   - }
1814   -#endif
1815   -
1816   - sprintf(str, "%lx", images->ep); /* write entry-point into string */
1817   - local_args[0] = argv[0];
1818   - local_args[1] = str; /* and provide it via the arguments */
1819   - do_bootelf(NULL, 0, 2, local_args);
1820   -
1821   - return 1;
1822   -}
1823   -#endif
1824   -
1825   -#ifdef CONFIG_INTEGRITY
1826   -static int do_bootm_integrity(int flag, int argc, char * const argv[],
1827   - bootm_headers_t *images)
1828   -{
1829   - void (*entry_point)(void);
1830   -
1831   - if (flag != BOOTM_STATE_OS_GO)
1832   - return 0;
1833   -
1834   -#if defined(CONFIG_FIT)
1835   - if (!images->legacy_hdr_valid) {
1836   - fit_unsupported_reset("INTEGRITY");
1837   - return 1;
1838   - }
1839   -#endif
1840   -
1841   - entry_point = (void (*)(void))images->ep;
1842   -
1843   - printf("## Transferring control to INTEGRITY (at address %08lx) ...\n",
1844   - (ulong)entry_point);
1845   -
1846   - bootstage_mark(BOOTSTAGE_ID_RUN_OS);
1847   -
1848   - /*
1849   - * INTEGRITY Parameters:
1850   - * None
1851   - */
1852   - (*entry_point)();
1853   -
1854   - return 1;
1855   -}
1856   -#endif
1857   -
1858 534 #ifdef CONFIG_CMD_BOOTZ
1859 535  
1860 536 int __weak bootz_setup(ulong image, ulong *start, ulong *end)
1861 537  
... ... @@ -1898,13 +574,8 @@
1898 574 * Handle the BOOTM_STATE_FINDOTHER state ourselves as we do not
1899 575 * have a header that provide this informaiton.
1900 576 */
1901   - if (bootm_find_ramdisk(flag, argc, argv))
  577 + if (bootm_find_ramdisk_fdt(flag, argc, argv))
1902 578 return 1;
1903   -
1904   -#if defined(CONFIG_OF_LIBFDT)
1905   - if (bootm_find_fdt(flag, argc, argv))
1906   - return 1;
1907   -#endif
1908 579  
1909 580 return 0;
1910 581 }
  1 +/*
  2 + * (C) Copyright 2000-2009
  3 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
  4 + *
  5 + * SPDX-License-Identifier: GPL-2.0+
  6 + */
  7 +
  8 +#ifndef _BOOTM_H
  9 +#define _BOOTM_H
  10 +
  11 +#include <command.h>
  12 +#include <image.h>
  13 +
  14 +#define BOOTM_ERR_RESET (-1)
  15 +#define BOOTM_ERR_OVERLAP (-2)
  16 +#define BOOTM_ERR_UNIMPLEMENTED (-3)
  17 +
  18 +/*
  19 + * Continue booting an OS image; caller already has:
  20 + * - copied image header to global variable `header'
  21 + * - checked header magic number, checksums (both header & image),
  22 + * - verified image architecture (PPC) and type (KERNEL or MULTI),
  23 + * - loaded (first part of) image to header load address,
  24 + * - disabled interrupts.
  25 + *
  26 + * @flag: Flags indicating what to do (BOOTM_STATE_...)
  27 + * @argc: Number of arguments. Note that the arguments are shifted down
  28 + * so that 0 is the first argument not processed by U-Boot, and
  29 + * argc is adjusted accordingly. This avoids confusion as to how
  30 + * many arguments are available for the OS.
  31 + * @images: Pointers to os/initrd/fdt
  32 + * @return 1 on error. On success the OS boots so this function does
  33 + * not return.
  34 + */
  35 +typedef int boot_os_fn(int flag, int argc, char * const argv[],
  36 + bootm_headers_t *images);
  37 +
  38 +extern boot_os_fn do_bootm_linux;
  39 +int do_bootelf(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]);
  40 +void lynxkdi_boot(image_header_t *hdr);
  41 +
  42 +boot_os_fn *bootm_os_get_boot_func(int os);
  43 +
  44 +int boot_selected_os(int argc, char * const argv[], int state,
  45 + bootm_headers_t *images, boot_os_fn *boot_fn);
  46 +
  47 +ulong bootm_disable_interrupts(void);
  48 +
  49 +/* This is a special function used by bootz */
  50 +int bootm_find_ramdisk_fdt(int flag, int argc, char * const argv[]);
  51 +
  52 +int do_bootm_states(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[],
  53 + int states, bootm_headers_t *images, int boot_progress);
  54 +
  55 +#endif