uboot/common/bootm.c
<<
>>
Prefs
   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 USE_HOSTCC
   9#include <common.h>
  10#include <bootstage.h>
  11#include <bzlib.h>
  12#include <errno.h>
  13#include <fdt_support.h>
  14#include <lmb.h>
  15#include <malloc.h>
  16#include <mapmem.h>
  17#include <asm/io.h>
  18#include <linux/lzo.h>
  19#include <lzma/LzmaTypes.h>
  20#include <lzma/LzmaDec.h>
  21#include <lzma/LzmaTools.h>
  22#if defined(CONFIG_CMD_USB)
  23#include <usb.h>
  24#endif
  25#else
  26#include "mkimage.h"
  27#endif
  28
  29#include <command.h>
  30#include <bootm.h>
  31#include <image.h>
  32
  33#ifndef CONFIG_SYS_BOOTM_LEN
  34/* use 8MByte as default max gunzip size */
  35#define CONFIG_SYS_BOOTM_LEN    0x800000
  36#endif
  37
  38#define IH_INITRD_ARCH IH_ARCH_DEFAULT
  39
  40#ifndef USE_HOSTCC
  41
  42DECLARE_GLOBAL_DATA_PTR;
  43
  44bootm_headers_t images;         /* pointers to os/initrd/fdt images */
  45
  46static const void *boot_get_kernel(cmd_tbl_t *cmdtp, int flag, int argc,
  47                                   char * const argv[], bootm_headers_t *images,
  48                                   ulong *os_data, ulong *os_len);
  49
  50#ifdef CONFIG_LMB
  51static void boot_start_lmb(bootm_headers_t *images)
  52{
  53        ulong           mem_start;
  54        phys_size_t     mem_size;
  55
  56        lmb_init(&images->lmb);
  57
  58        mem_start = env_get_bootm_low();
  59        mem_size = env_get_bootm_size();
  60
  61        lmb_add(&images->lmb, (phys_addr_t)mem_start, mem_size);
  62
  63        arch_lmb_reserve(&images->lmb);
  64        board_lmb_reserve(&images->lmb);
  65}
  66#else
  67#define lmb_reserve(lmb, base, size)
  68static inline void boot_start_lmb(bootm_headers_t *images) { }
  69#endif
  70
  71static int bootm_start(cmd_tbl_t *cmdtp, int flag, int argc,
  72                       char * const argv[])
  73{
  74        memset((void *)&images, 0, sizeof(images));
  75        images.verify = env_get_yesno("verify");
  76
  77        boot_start_lmb(&images);
  78
  79        bootstage_mark_name(BOOTSTAGE_ID_BOOTM_START, "bootm_start");
  80        images.state = BOOTM_STATE_START;
  81
  82        return 0;
  83}
  84
  85static int bootm_find_os(cmd_tbl_t *cmdtp, int flag, int argc,
  86                         char * const argv[])
  87{
  88        const void *os_hdr;
  89        bool ep_found = false;
  90        int ret;
  91
  92        /* get kernel image header, start address and length */
  93        os_hdr = boot_get_kernel(cmdtp, flag, argc, argv,
  94                        &images, &images.os.image_start, &images.os.image_len);
  95        if (images.os.image_len == 0) {
  96                puts("ERROR: can't get kernel image!\n");
  97                return 1;
  98        }
  99
 100        /* get image parameters */
 101        switch (genimg_get_format(os_hdr)) {
 102#if defined(CONFIG_IMAGE_FORMAT_LEGACY)
 103        case IMAGE_FORMAT_LEGACY:
 104                images.os.type = image_get_type(os_hdr);
 105                images.os.comp = image_get_comp(os_hdr);
 106                images.os.os = image_get_os(os_hdr);
 107
 108                images.os.end = image_get_image_end(os_hdr);
 109                images.os.load = image_get_load(os_hdr);
 110                images.os.arch = image_get_arch(os_hdr);
 111                break;
 112#endif
 113#if IMAGE_ENABLE_FIT
 114        case IMAGE_FORMAT_FIT:
 115                if (fit_image_get_type(images.fit_hdr_os,
 116                                       images.fit_noffset_os,
 117                                       &images.os.type)) {
 118                        puts("Can't get image type!\n");
 119                        bootstage_error(BOOTSTAGE_ID_FIT_TYPE);
 120                        return 1;
 121                }
 122
 123                if (fit_image_get_comp(images.fit_hdr_os,
 124                                       images.fit_noffset_os,
 125                                       &images.os.comp)) {
 126                        puts("Can't get image compression!\n");
 127                        bootstage_error(BOOTSTAGE_ID_FIT_COMPRESSION);
 128                        return 1;
 129                }
 130
 131                if (fit_image_get_os(images.fit_hdr_os, images.fit_noffset_os,
 132                                     &images.os.os)) {
 133                        puts("Can't get image OS!\n");
 134                        bootstage_error(BOOTSTAGE_ID_FIT_OS);
 135                        return 1;
 136                }
 137
 138                if (fit_image_get_arch(images.fit_hdr_os,
 139                                       images.fit_noffset_os,
 140                                       &images.os.arch)) {
 141                        puts("Can't get image ARCH!\n");
 142                        return 1;
 143                }
 144
 145                images.os.end = fit_get_end(images.fit_hdr_os);
 146
 147                if (fit_image_get_load(images.fit_hdr_os, images.fit_noffset_os,
 148                                       &images.os.load)) {
 149                        puts("Can't get image load address!\n");
 150                        bootstage_error(BOOTSTAGE_ID_FIT_LOADADDR);
 151                        return 1;
 152                }
 153                break;
 154#endif
 155#ifdef CONFIG_ANDROID_BOOT_IMAGE
 156        case IMAGE_FORMAT_ANDROID:
 157                images.os.type = IH_TYPE_KERNEL;
 158                images.os.comp = IH_COMP_NONE;
 159                images.os.os = IH_OS_LINUX;
 160
 161                images.os.end = android_image_get_end(os_hdr);
 162                images.os.load = android_image_get_kload(os_hdr);
 163                images.ep = images.os.load;
 164                ep_found = true;
 165                break;
 166#endif
 167        default:
 168                puts("ERROR: unknown image format type!\n");
 169                return 1;
 170        }
 171
 172        /* If we have a valid setup.bin, we will use that for entry (x86) */
 173        if (images.os.arch == IH_ARCH_I386 ||
 174            images.os.arch == IH_ARCH_X86_64) {
 175                ulong len;
 176
 177                ret = boot_get_setup(&images, IH_ARCH_I386, &images.ep, &len);
 178                if (ret < 0 && ret != -ENOENT) {
 179                        puts("Could not find a valid setup.bin for x86\n");
 180                        return 1;
 181                }
 182                /* Kernel entry point is the setup.bin */
 183        } else if (images.legacy_hdr_valid) {
 184                images.ep = image_get_ep(&images.legacy_hdr_os_copy);
 185#if IMAGE_ENABLE_FIT
 186        } else if (images.fit_uname_os) {
 187                int ret;
 188
 189                ret = fit_image_get_entry(images.fit_hdr_os,
 190                                          images.fit_noffset_os, &images.ep);
 191                if (ret) {
 192                        puts("Can't get entry point property!\n");
 193                        return 1;
 194                }
 195#endif
 196        } else if (!ep_found) {
 197                puts("Could not find kernel entry point!\n");
 198                return 1;
 199        }
 200
 201        if (images.os.type == IH_TYPE_KERNEL_NOLOAD) {
 202                images.os.load = images.os.image_start;
 203                images.ep += images.os.load;
 204        }
 205
 206        images.os.start = map_to_sysmem(os_hdr);
 207
 208        return 0;
 209}
 210
 211/**
 212 * bootm_find_images - wrapper to find and locate various images
 213 * @flag: Ignored Argument
 214 * @argc: command argument count
 215 * @argv: command argument list
 216 *
 217 * boot_find_images() will attempt to load an available ramdisk,
 218 * flattened device tree, as well as specifically marked
 219 * "loadable" images (loadables are FIT only)
 220 *
 221 * Note: bootm_find_images will skip an image if it is not found
 222 *
 223 * @return:
 224 *     0, if all existing images were loaded correctly
 225 *     1, if an image is found but corrupted, or invalid
 226 */
 227int bootm_find_images(int flag, int argc, char * const argv[])
 228{
 229        int ret;
 230
 231        /* find ramdisk */
 232        ret = boot_get_ramdisk(argc, argv, &images, IH_INITRD_ARCH,
 233                               &images.rd_start, &images.rd_end);
 234        if (ret) {
 235                puts("Ramdisk image is corrupt or invalid\n");
 236                return 1;
 237        }
 238
 239#if IMAGE_ENABLE_OF_LIBFDT
 240        /* find flattened device tree */
 241        ret = boot_get_fdt(flag, argc, argv, IH_ARCH_DEFAULT, &images,
 242                           &images.ft_addr, &images.ft_len);
 243        if (ret) {
 244                puts("Could not find a valid device tree\n");
 245                return 1;
 246        }
 247        set_working_fdt_addr((ulong)images.ft_addr);
 248#endif
 249
 250#if IMAGE_ENABLE_FIT
 251#if defined(CONFIG_FPGA) && defined(CONFIG_FPGA_XILINX)
 252        /* find bitstreams */
 253        ret = boot_get_fpga(argc, argv, &images, IH_ARCH_DEFAULT,
 254                            NULL, NULL);
 255        if (ret) {
 256                printf("FPGA image is corrupted or invalid\n");
 257                return 1;
 258        }
 259#endif
 260
 261        /* find all of the loadables */
 262        ret = boot_get_loadable(argc, argv, &images, IH_ARCH_DEFAULT,
 263                               NULL, NULL);
 264        if (ret) {
 265                printf("Loadable(s) is corrupt or invalid\n");
 266                return 1;
 267        }
 268#endif
 269
 270        return 0;
 271}
 272
 273static int bootm_find_other(cmd_tbl_t *cmdtp, int flag, int argc,
 274                            char * const argv[])
 275{
 276        if (((images.os.type == IH_TYPE_KERNEL) ||
 277             (images.os.type == IH_TYPE_KERNEL_NOLOAD) ||
 278             (images.os.type == IH_TYPE_MULTI)) &&
 279            (images.os.os == IH_OS_LINUX ||
 280                 images.os.os == IH_OS_VXWORKS))
 281                return bootm_find_images(flag, argc, argv);
 282
 283        return 0;
 284}
 285#endif /* USE_HOSTC */
 286
 287/**
 288 * print_decomp_msg() - Print a suitable decompression/loading message
 289 *
 290 * @type:       OS type (IH_OS_...)
 291 * @comp_type:  Compression type being used (IH_COMP_...)
 292 * @is_xip:     true if the load address matches the image start
 293 */
 294static void print_decomp_msg(int comp_type, int type, bool is_xip)
 295{
 296        const char *name = genimg_get_type_name(type);
 297
 298        if (comp_type == IH_COMP_NONE)
 299                printf("   %s %s ... ", is_xip ? "XIP" : "Loading", name);
 300        else
 301                printf("   Uncompressing %s ... ", name);
 302}
 303
 304/**
 305 * handle_decomp_error() - display a decompression error
 306 *
 307 * This function tries to produce a useful message. In the case where the
 308 * uncompressed size is the same as the available space, we can assume that
 309 * the image is too large for the buffer.
 310 *
 311 * @comp_type:          Compression type being used (IH_COMP_...)
 312 * @uncomp_size:        Number of bytes uncompressed
 313 * @unc_len:            Amount of space available for decompression
 314 * @ret:                Error code to report
 315 * @return BOOTM_ERR_RESET, indicating that the board must be reset
 316 */
 317static int handle_decomp_error(int comp_type, size_t uncomp_size,
 318                               size_t unc_len, int ret)
 319{
 320        const char *name = genimg_get_comp_name(comp_type);
 321
 322        if (uncomp_size >= unc_len)
 323                printf("Image too large: increase CONFIG_SYS_BOOTM_LEN\n");
 324        else
 325                printf("%s: uncompress error %d\n", name, ret);
 326
 327        /*
 328         * The decompression routines are now safe, so will not write beyond
 329         * their bounds. Probably it is not necessary to reset, but maintain
 330         * the current behaviour for now.
 331         */
 332        printf("Must RESET board to recover\n");
 333#ifndef USE_HOSTCC
 334        bootstage_error(BOOTSTAGE_ID_DECOMP_IMAGE);
 335#endif
 336
 337        return BOOTM_ERR_RESET;
 338}
 339
 340int bootm_decomp_image(int comp, ulong load, ulong image_start, int type,
 341                       void *load_buf, void *image_buf, ulong image_len,
 342                       uint unc_len, ulong *load_end)
 343{
 344        int ret = 0;
 345
 346        *load_end = load;
 347        print_decomp_msg(comp, type, load == image_start);
 348
 349        /*
 350         * Load the image to the right place, decompressing if needed. After
 351         * this, image_len will be set to the number of uncompressed bytes
 352         * loaded, ret will be non-zero on error.
 353         */
 354        switch (comp) {
 355        case IH_COMP_NONE:
 356                if (load == image_start)
 357                        break;
 358                if (image_len <= unc_len)
 359                        memmove_wd(load_buf, image_buf, image_len, CHUNKSZ);
 360                else
 361                        ret = 1;
 362                break;
 363#ifdef CONFIG_GZIP
 364        case IH_COMP_GZIP: {
 365                ret = gunzip(load_buf, unc_len, image_buf, &image_len);
 366                break;
 367        }
 368#endif /* CONFIG_GZIP */
 369#ifdef CONFIG_BZIP2
 370        case IH_COMP_BZIP2: {
 371                uint size = unc_len;
 372
 373                /*
 374                 * If we've got less than 4 MB of malloc() space,
 375                 * use slower decompression algorithm which requires
 376                 * at most 2300 KB of memory.
 377                 */
 378                ret = BZ2_bzBuffToBuffDecompress(load_buf, &size,
 379                        image_buf, image_len,
 380                        CONFIG_SYS_MALLOC_LEN < (4096 * 1024), 0);
 381                image_len = size;
 382                break;
 383        }
 384#endif /* CONFIG_BZIP2 */
 385#ifdef CONFIG_LZMA
 386        case IH_COMP_LZMA: {
 387                SizeT lzma_len = unc_len;
 388
 389                ret = lzmaBuffToBuffDecompress(load_buf, &lzma_len,
 390                                               image_buf, image_len);
 391                image_len = lzma_len;
 392                break;
 393        }
 394#endif /* CONFIG_LZMA */
 395#ifdef CONFIG_LZO
 396        case IH_COMP_LZO: {
 397                size_t size = unc_len;
 398
 399                ret = lzop_decompress(image_buf, image_len, load_buf, &size);
 400                image_len = size;
 401                break;
 402        }
 403#endif /* CONFIG_LZO */
 404#ifdef CONFIG_LZ4
 405        case IH_COMP_LZ4: {
 406                size_t size = unc_len;
 407
 408                ret = ulz4fn(image_buf, image_len, load_buf, &size);
 409                image_len = size;
 410                break;
 411        }
 412#endif /* CONFIG_LZ4 */
 413        default:
 414                printf("Unimplemented compression type %d\n", comp);
 415                return BOOTM_ERR_UNIMPLEMENTED;
 416        }
 417
 418        if (ret)
 419                return handle_decomp_error(comp, image_len, unc_len, ret);
 420        *load_end = load + image_len;
 421
 422        puts("OK\n");
 423
 424        return 0;
 425}
 426
 427#ifndef USE_HOSTCC
 428static int bootm_load_os(bootm_headers_t *images, unsigned long *load_end,
 429                         int boot_progress)
 430{
 431        image_info_t os = images->os;
 432        ulong load = os.load;
 433        ulong blob_start = os.start;
 434        ulong blob_end = os.end;
 435        ulong image_start = os.image_start;
 436        ulong image_len = os.image_len;
 437        bool no_overlap;
 438        void *load_buf, *image_buf;
 439        int err;
 440
 441        load_buf = map_sysmem(load, 0);
 442        image_buf = map_sysmem(os.image_start, image_len);
 443        err = bootm_decomp_image(os.comp, load, os.image_start, os.type,
 444                                 load_buf, image_buf, image_len,
 445                                 CONFIG_SYS_BOOTM_LEN, load_end);
 446        if (err) {
 447                bootstage_error(BOOTSTAGE_ID_DECOMP_IMAGE);
 448                return err;
 449        }
 450        flush_cache(load, ALIGN(*load_end - load, ARCH_DMA_MINALIGN));
 451
 452        debug("   kernel loaded at 0x%08lx, end = 0x%08lx\n", load, *load_end);
 453        bootstage_mark(BOOTSTAGE_ID_KERNEL_LOADED);
 454
 455        no_overlap = (os.comp == IH_COMP_NONE && load == image_start);
 456
 457        if (!no_overlap && (load < blob_end) && (*load_end > blob_start)) {
 458                debug("images.os.start = 0x%lX, images.os.end = 0x%lx\n",
 459                      blob_start, blob_end);
 460                debug("images.os.load = 0x%lx, load_end = 0x%lx\n", load,
 461                      *load_end);
 462
 463                /* Check what type of image this is. */
 464                if (images->legacy_hdr_valid) {
 465                        if (image_get_type(&images->legacy_hdr_os_copy)
 466                                        == IH_TYPE_MULTI)
 467                                puts("WARNING: legacy format multi component image overwritten\n");
 468                        return BOOTM_ERR_OVERLAP;
 469                } else {
 470                        puts("ERROR: new format image overwritten - must RESET the board to recover\n");
 471                        bootstage_error(BOOTSTAGE_ID_OVERWRITTEN);
 472                        return BOOTM_ERR_RESET;
 473                }
 474        }
 475
 476        return 0;
 477}
 478
 479/**
 480 * bootm_disable_interrupts() - Disable interrupts in preparation for load/boot
 481 *
 482 * @return interrupt flag (0 if interrupts were disabled, non-zero if they were
 483 *      enabled)
 484 */
 485ulong bootm_disable_interrupts(void)
 486{
 487        ulong iflag;
 488
 489        /*
 490         * We have reached the point of no return: we are going to
 491         * overwrite all exception vector code, so we cannot easily
 492         * recover from any failures any more...
 493         */
 494        iflag = disable_interrupts();
 495#ifdef CONFIG_NETCONSOLE
 496        /* Stop the ethernet stack if NetConsole could have left it up */
 497        eth_halt();
 498# ifndef CONFIG_DM_ETH
 499        eth_unregister(eth_get_dev());
 500# endif
 501#endif
 502
 503#if defined(CONFIG_CMD_USB)
 504        /*
 505         * turn off USB to prevent the host controller from writing to the
 506         * SDRAM while Linux is booting. This could happen (at least for OHCI
 507         * controller), because the HCCA (Host Controller Communication Area)
 508         * lies within the SDRAM and the host controller writes continously to
 509         * this area (as busmaster!). The HccaFrameNumber is for example
 510         * updated every 1 ms within the HCCA structure in SDRAM! For more
 511         * details see the OpenHCI specification.
 512         */
 513        usb_stop();
 514#endif
 515        return iflag;
 516}
 517
 518#if defined(CONFIG_SILENT_CONSOLE) && !defined(CONFIG_SILENT_U_BOOT_ONLY)
 519
 520#define CONSOLE_ARG     "console="
 521#define CONSOLE_ARG_LEN (sizeof(CONSOLE_ARG) - 1)
 522
 523static void fixup_silent_linux(void)
 524{
 525        char *buf;
 526        const char *env_val;
 527        char *cmdline = env_get("bootargs");
 528        int want_silent;
 529
 530        /*
 531         * Only fix cmdline when requested. The environment variable can be:
 532         *
 533         *      no - we never fixup
 534         *      yes - we always fixup
 535         *      unset - we rely on the console silent flag
 536         */
 537        want_silent = env_get_yesno("silent_linux");
 538        if (want_silent == 0)
 539                return;
 540        else if (want_silent == -1 && !(gd->flags & GD_FLG_SILENT))
 541                return;
 542
 543        debug("before silent fix-up: %s\n", cmdline);
 544        if (cmdline && (cmdline[0] != '\0')) {
 545                char *start = strstr(cmdline, CONSOLE_ARG);
 546
 547                /* Allocate space for maximum possible new command line */
 548                buf = malloc(strlen(cmdline) + 1 + CONSOLE_ARG_LEN + 1);
 549                if (!buf) {
 550                        debug("%s: out of memory\n", __func__);
 551                        return;
 552                }
 553
 554                if (start) {
 555                        char *end = strchr(start, ' ');
 556                        int num_start_bytes = start - cmdline + CONSOLE_ARG_LEN;
 557
 558                        strncpy(buf, cmdline, num_start_bytes);
 559                        if (end)
 560                                strcpy(buf + num_start_bytes, end);
 561                        else
 562                                buf[num_start_bytes] = '\0';
 563                } else {
 564                        sprintf(buf, "%s %s", cmdline, CONSOLE_ARG);
 565                }
 566                env_val = buf;
 567        } else {
 568                buf = NULL;
 569                env_val = CONSOLE_ARG;
 570        }
 571
 572        env_set("bootargs", env_val);
 573        debug("after silent fix-up: %s\n", env_val);
 574        free(buf);
 575}
 576#endif /* CONFIG_SILENT_CONSOLE */
 577
 578/**
 579 * Execute selected states of the bootm command.
 580 *
 581 * Note the arguments to this state must be the first argument, Any 'bootm'
 582 * or sub-command arguments must have already been taken.
 583 *
 584 * Note that if states contains more than one flag it MUST contain
 585 * BOOTM_STATE_START, since this handles and consumes the command line args.
 586 *
 587 * Also note that aside from boot_os_fn functions and bootm_load_os no other
 588 * functions we store the return value of in 'ret' may use a negative return
 589 * value, without special handling.
 590 *
 591 * @param cmdtp         Pointer to bootm command table entry
 592 * @param flag          Command flags (CMD_FLAG_...)
 593 * @param argc          Number of subcommand arguments (0 = no arguments)
 594 * @param argv          Arguments
 595 * @param states        Mask containing states to run (BOOTM_STATE_...)
 596 * @param images        Image header information
 597 * @param boot_progress 1 to show boot progress, 0 to not do this
 598 * @return 0 if ok, something else on error. Some errors will cause this
 599 *      function to perform a reboot! If states contains BOOTM_STATE_OS_GO
 600 *      then the intent is to boot an OS, so this function will not return
 601 *      unless the image type is standalone.
 602 */
 603int do_bootm_states(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[],
 604                    int states, bootm_headers_t *images, int boot_progress)
 605{
 606        boot_os_fn *boot_fn;
 607        ulong iflag = 0;
 608        int ret = 0, need_boot_fn;
 609
 610        images->state |= states;
 611
 612        /*
 613         * Work through the states and see how far we get. We stop on
 614         * any error.
 615         */
 616        if (states & BOOTM_STATE_START)
 617                ret = bootm_start(cmdtp, flag, argc, argv);
 618
 619        if (!ret && (states & BOOTM_STATE_FINDOS))
 620                ret = bootm_find_os(cmdtp, flag, argc, argv);
 621
 622        if (!ret && (states & BOOTM_STATE_FINDOTHER))
 623                ret = bootm_find_other(cmdtp, flag, argc, argv);
 624
 625        /* Load the OS */
 626        if (!ret && (states & BOOTM_STATE_LOADOS)) {
 627                ulong load_end;
 628
 629                iflag = bootm_disable_interrupts();
 630                ret = bootm_load_os(images, &load_end, 0);
 631                if (ret == 0)
 632                        lmb_reserve(&images->lmb, images->os.load,
 633                                    (load_end - images->os.load));
 634                else if (ret && ret != BOOTM_ERR_OVERLAP)
 635                        goto err;
 636                else if (ret == BOOTM_ERR_OVERLAP)
 637                        ret = 0;
 638        }
 639
 640        /* Relocate the ramdisk */
 641#ifdef CONFIG_SYS_BOOT_RAMDISK_HIGH
 642        if (!ret && (states & BOOTM_STATE_RAMDISK)) {
 643                ulong rd_len = images->rd_end - images->rd_start;
 644
 645                ret = boot_ramdisk_high(&images->lmb, images->rd_start,
 646                        rd_len, &images->initrd_start, &images->initrd_end);
 647                if (!ret) {
 648                        env_set_hex("initrd_start", images->initrd_start);
 649                        env_set_hex("initrd_end", images->initrd_end);
 650                }
 651        }
 652#endif
 653#if IMAGE_ENABLE_OF_LIBFDT && defined(CONFIG_LMB)
 654        if (!ret && (states & BOOTM_STATE_FDT)) {
 655                boot_fdt_add_mem_rsv_regions(&images->lmb, images->ft_addr);
 656                ret = boot_relocate_fdt(&images->lmb, &images->ft_addr,
 657                                        &images->ft_len);
 658        }
 659#endif
 660
 661        /* From now on, we need the OS boot function */
 662        if (ret)
 663                return ret;
 664        boot_fn = bootm_os_get_boot_func(images->os.os);
 665        need_boot_fn = states & (BOOTM_STATE_OS_CMDLINE |
 666                        BOOTM_STATE_OS_BD_T | BOOTM_STATE_OS_PREP |
 667                        BOOTM_STATE_OS_FAKE_GO | BOOTM_STATE_OS_GO);
 668        if (boot_fn == NULL && need_boot_fn) {
 669                if (iflag)
 670                        enable_interrupts();
 671                printf("ERROR: booting os '%s' (%d) is not supported\n",
 672                       genimg_get_os_name(images->os.os), images->os.os);
 673                bootstage_error(BOOTSTAGE_ID_CHECK_BOOT_OS);
 674                return 1;
 675        }
 676
 677
 678        /* Call various other states that are not generally used */
 679        if (!ret && (states & BOOTM_STATE_OS_CMDLINE))
 680                ret = boot_fn(BOOTM_STATE_OS_CMDLINE, argc, argv, images);
 681        if (!ret && (states & BOOTM_STATE_OS_BD_T))
 682                ret = boot_fn(BOOTM_STATE_OS_BD_T, argc, argv, images);
 683        if (!ret && (states & BOOTM_STATE_OS_PREP)) {
 684#if defined(CONFIG_SILENT_CONSOLE) && !defined(CONFIG_SILENT_U_BOOT_ONLY)
 685                if (images->os.os == IH_OS_LINUX)
 686                        fixup_silent_linux();
 687#endif
 688                ret = boot_fn(BOOTM_STATE_OS_PREP, argc, argv, images);
 689        }
 690
 691#ifdef CONFIG_TRACE
 692        /* Pretend to run the OS, then run a user command */
 693        if (!ret && (states & BOOTM_STATE_OS_FAKE_GO)) {
 694                char *cmd_list = env_get("fakegocmd");
 695
 696                ret = boot_selected_os(argc, argv, BOOTM_STATE_OS_FAKE_GO,
 697                                images, boot_fn);
 698                if (!ret && cmd_list)
 699                        ret = run_command_list(cmd_list, -1, flag);
 700        }
 701#endif
 702
 703        /* Check for unsupported subcommand. */
 704        if (ret) {
 705                puts("subcommand not supported\n");
 706                return ret;
 707        }
 708
 709        /* Now run the OS! We hope this doesn't return */
 710        if (!ret && (states & BOOTM_STATE_OS_GO))
 711                ret = boot_selected_os(argc, argv, BOOTM_STATE_OS_GO,
 712                                images, boot_fn);
 713
 714        /* Deal with any fallout */
 715err:
 716        if (iflag)
 717                enable_interrupts();
 718
 719        if (ret == BOOTM_ERR_UNIMPLEMENTED)
 720                bootstage_error(BOOTSTAGE_ID_DECOMP_UNIMPL);
 721        else if (ret == BOOTM_ERR_RESET)
 722                do_reset(cmdtp, flag, argc, argv);
 723
 724        return ret;
 725}
 726
 727#if defined(CONFIG_IMAGE_FORMAT_LEGACY)
 728/**
 729 * image_get_kernel - verify legacy format kernel image
 730 * @img_addr: in RAM address of the legacy format image to be verified
 731 * @verify: data CRC verification flag
 732 *
 733 * image_get_kernel() verifies legacy image integrity and returns pointer to
 734 * legacy image header if image verification was completed successfully.
 735 *
 736 * returns:
 737 *     pointer to a legacy image header if valid image was found
 738 *     otherwise return NULL
 739 */
 740static image_header_t *image_get_kernel(ulong img_addr, int verify)
 741{
 742        image_header_t *hdr = (image_header_t *)img_addr;
 743
 744        if (!image_check_magic(hdr)) {
 745                puts("Bad Magic Number\n");
 746                bootstage_error(BOOTSTAGE_ID_CHECK_MAGIC);
 747                return NULL;
 748        }
 749        bootstage_mark(BOOTSTAGE_ID_CHECK_HEADER);
 750
 751        if (!image_check_hcrc(hdr)) {
 752                puts("Bad Header Checksum\n");
 753                bootstage_error(BOOTSTAGE_ID_CHECK_HEADER);
 754                return NULL;
 755        }
 756
 757        bootstage_mark(BOOTSTAGE_ID_CHECK_CHECKSUM);
 758        image_print_contents(hdr);
 759
 760        if (verify) {
 761                puts("   Verifying Checksum ... ");
 762                if (!image_check_dcrc(hdr)) {
 763                        printf("Bad Data CRC\n");
 764                        bootstage_error(BOOTSTAGE_ID_CHECK_CHECKSUM);
 765                        return NULL;
 766                }
 767                puts("OK\n");
 768        }
 769        bootstage_mark(BOOTSTAGE_ID_CHECK_ARCH);
 770
 771        if (!image_check_target_arch(hdr)) {
 772                printf("Unsupported Architecture 0x%x\n", image_get_arch(hdr));
 773                bootstage_error(BOOTSTAGE_ID_CHECK_ARCH);
 774                return NULL;
 775        }
 776        return hdr;
 777}
 778#endif
 779
 780/**
 781 * boot_get_kernel - find kernel image
 782 * @os_data: pointer to a ulong variable, will hold os data start address
 783 * @os_len: pointer to a ulong variable, will hold os data length
 784 *
 785 * boot_get_kernel() tries to find a kernel image, verifies its integrity
 786 * and locates kernel data.
 787 *
 788 * returns:
 789 *     pointer to image header if valid image was found, plus kernel start
 790 *     address and length, otherwise NULL
 791 */
 792static const void *boot_get_kernel(cmd_tbl_t *cmdtp, int flag, int argc,
 793                                   char * const argv[], bootm_headers_t *images,
 794                                   ulong *os_data, ulong *os_len)
 795{
 796#if defined(CONFIG_IMAGE_FORMAT_LEGACY)
 797        image_header_t  *hdr;
 798#endif
 799        ulong           img_addr;
 800        const void *buf;
 801        const char      *fit_uname_config = NULL;
 802        const char      *fit_uname_kernel = NULL;
 803#if IMAGE_ENABLE_FIT
 804        int             os_noffset;
 805#endif
 806
 807        img_addr = genimg_get_kernel_addr_fit(argc < 1 ? NULL : argv[0],
 808                                              &fit_uname_config,
 809                                              &fit_uname_kernel);
 810
 811        bootstage_mark(BOOTSTAGE_ID_CHECK_MAGIC);
 812
 813        /* copy from dataflash if needed */
 814        img_addr = genimg_get_image(img_addr);
 815
 816        /* check image type, for FIT images get FIT kernel node */
 817        *os_data = *os_len = 0;
 818        buf = map_sysmem(img_addr, 0);
 819        switch (genimg_get_format(buf)) {
 820#if defined(CONFIG_IMAGE_FORMAT_LEGACY)
 821        case IMAGE_FORMAT_LEGACY:
 822                printf("## Booting kernel from Legacy Image at %08lx ...\n",
 823                       img_addr);
 824                hdr = image_get_kernel(img_addr, images->verify);
 825                if (!hdr)
 826                        return NULL;
 827                bootstage_mark(BOOTSTAGE_ID_CHECK_IMAGETYPE);
 828
 829                /* get os_data and os_len */
 830                switch (image_get_type(hdr)) {
 831                case IH_TYPE_KERNEL:
 832                case IH_TYPE_KERNEL_NOLOAD:
 833                        *os_data = image_get_data(hdr);
 834                        *os_len = image_get_data_size(hdr);
 835                        break;
 836                case IH_TYPE_MULTI:
 837                        image_multi_getimg(hdr, 0, os_data, os_len);
 838                        break;
 839                case IH_TYPE_STANDALONE:
 840                        *os_data = image_get_data(hdr);
 841                        *os_len = image_get_data_size(hdr);
 842                        break;
 843                default:
 844                        printf("Wrong Image Type for %s command\n",
 845                               cmdtp->name);
 846                        bootstage_error(BOOTSTAGE_ID_CHECK_IMAGETYPE);
 847                        return NULL;
 848                }
 849
 850                /*
 851                 * copy image header to allow for image overwrites during
 852                 * kernel decompression.
 853                 */
 854                memmove(&images->legacy_hdr_os_copy, hdr,
 855                        sizeof(image_header_t));
 856
 857                /* save pointer to image header */
 858                images->legacy_hdr_os = hdr;
 859
 860                images->legacy_hdr_valid = 1;
 861                bootstage_mark(BOOTSTAGE_ID_DECOMP_IMAGE);
 862                break;
 863#endif
 864#if IMAGE_ENABLE_FIT
 865        case IMAGE_FORMAT_FIT:
 866                os_noffset = fit_image_load(images, img_addr,
 867                                &fit_uname_kernel, &fit_uname_config,
 868                                IH_ARCH_DEFAULT, IH_TYPE_KERNEL,
 869                                BOOTSTAGE_ID_FIT_KERNEL_START,
 870                                FIT_LOAD_IGNORED, os_data, os_len);
 871                if (os_noffset < 0)
 872                        return NULL;
 873
 874                images->fit_hdr_os = map_sysmem(img_addr, 0);
 875                images->fit_uname_os = fit_uname_kernel;
 876                images->fit_uname_cfg = fit_uname_config;
 877                images->fit_noffset_os = os_noffset;
 878                break;
 879#endif
 880#ifdef CONFIG_ANDROID_BOOT_IMAGE
 881        case IMAGE_FORMAT_ANDROID:
 882                printf("## Booting Android Image at 0x%08lx ...\n", img_addr);
 883                if (android_image_get_kernel(buf, images->verify,
 884                                             os_data, os_len))
 885                        return NULL;
 886                break;
 887#endif
 888        default:
 889                printf("Wrong Image Format for %s command\n", cmdtp->name);
 890                bootstage_error(BOOTSTAGE_ID_FIT_KERNEL_INFO);
 891                return NULL;
 892        }
 893
 894        debug("   kernel data at 0x%08lx, len = 0x%08lx (%ld)\n",
 895              *os_data, *os_len, *os_len);
 896
 897        return buf;
 898}
 899#else /* USE_HOSTCC */
 900
 901void memmove_wd(void *to, void *from, size_t len, ulong chunksz)
 902{
 903        memmove(to, from, len);
 904}
 905
 906static int bootm_host_load_image(const void *fit, int req_image_type)
 907{
 908        const char *fit_uname_config = NULL;
 909        ulong data, len;
 910        bootm_headers_t images;
 911        int noffset;
 912        ulong load_end;
 913        uint8_t image_type;
 914        uint8_t imape_comp;
 915        void *load_buf;
 916        int ret;
 917
 918        memset(&images, '\0', sizeof(images));
 919        images.verify = 1;
 920        noffset = fit_image_load(&images, (ulong)fit,
 921                NULL, &fit_uname_config,
 922                IH_ARCH_DEFAULT, req_image_type, -1,
 923                FIT_LOAD_IGNORED, &data, &len);
 924        if (noffset < 0)
 925                return noffset;
 926        if (fit_image_get_type(fit, noffset, &image_type)) {
 927                puts("Can't get image type!\n");
 928                return -EINVAL;
 929        }
 930
 931        if (fit_image_get_comp(fit, noffset, &imape_comp)) {
 932                puts("Can't get image compression!\n");
 933                return -EINVAL;
 934        }
 935
 936        /* Allow the image to expand by a factor of 4, should be safe */
 937        load_buf = malloc((1 << 20) + len * 4);
 938        ret = bootm_decomp_image(imape_comp, 0, data, image_type, load_buf,
 939                                 (void *)data, len, CONFIG_SYS_BOOTM_LEN,
 940                                 &load_end);
 941        free(load_buf);
 942
 943        if (ret && ret != BOOTM_ERR_UNIMPLEMENTED)
 944                return ret;
 945
 946        return 0;
 947}
 948
 949int bootm_host_load_images(const void *fit, int cfg_noffset)
 950{
 951        static uint8_t image_types[] = {
 952                IH_TYPE_KERNEL,
 953                IH_TYPE_FLATDT,
 954                IH_TYPE_RAMDISK,
 955        };
 956        int err = 0;
 957        int i;
 958
 959        for (i = 0; i < ARRAY_SIZE(image_types); i++) {
 960                int ret;
 961
 962                ret = bootm_host_load_image(fit, image_types[i]);
 963                if (!err && ret && ret != -ENOENT)
 964                        err = ret;
 965        }
 966
 967        /* Return the first error we found */
 968        return err;
 969}
 970
 971#endif /* ndef USE_HOSTCC */
 972