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