uboot/arch/x86/lib/zimage.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0+
   2/*
   3 * Copyright (c) 2011 The Chromium OS Authors.
   4 * (C) Copyright 2002
   5 * Daniel Engström, Omicron Ceti AB, <daniel@omicron.se>
   6 */
   7
   8/*
   9 * Linux x86 zImage and bzImage loading
  10 *
  11 * based on the procdure described in
  12 * linux/Documentation/i386/boot.txt
  13 */
  14
  15#define LOG_CATEGORY    LOGC_BOOT
  16
  17#include <common.h>
  18#include <bootm.h>
  19#include <command.h>
  20#include <env.h>
  21#include <init.h>
  22#include <irq_func.h>
  23#include <log.h>
  24#include <malloc.h>
  25#include <acpi/acpi_table.h>
  26#include <asm/io.h>
  27#include <asm/ptrace.h>
  28#include <asm/zimage.h>
  29#include <asm/byteorder.h>
  30#include <asm/bootm.h>
  31#include <asm/bootparam.h>
  32#include <asm/efi.h>
  33#include <asm/global_data.h>
  34#ifdef CONFIG_SYS_COREBOOT
  35#include <asm/arch/timestamp.h>
  36#endif
  37#include <linux/compiler.h>
  38#include <linux/ctype.h>
  39#include <linux/libfdt.h>
  40
  41DECLARE_GLOBAL_DATA_PTR;
  42
  43/*
  44 * Memory lay-out:
  45 *
  46 * relative to setup_base (which is 0x90000 currently)
  47 *
  48 *      0x0000-0x7FFF   Real mode kernel
  49 *      0x8000-0x8FFF   Stack and heap
  50 *      0x9000-0x90FF   Kernel command line
  51 */
  52#define DEFAULT_SETUP_BASE      0x90000
  53#define COMMAND_LINE_OFFSET     0x9000
  54#define HEAP_END_OFFSET         0x8e00
  55
  56#define COMMAND_LINE_SIZE       2048
  57
  58/**
  59 * struct zboot_state - Current state of the boot
  60 *
  61 * @bzimage_addr: Address of the bzImage to boot
  62 * @bzimage_size: Size of the bzImage, or 0 to detect this
  63 * @initrd_addr: Address of the initial ramdisk, or 0 if none
  64 * @initrd_size: Size of the initial ramdisk, or 0 if none
  65 * @load_address: Address where the bzImage is moved before booting, either
  66 *      BZIMAGE_LOAD_ADDR or ZIMAGE_LOAD_ADDR
  67 * @base_ptr: Pointer to the boot parameters, typically at address
  68 *      DEFAULT_SETUP_BASE
  69 * @cmdline: Environment variable containing the 'override' command line, or
  70 *      NULL to use the one in the setup block
  71 */
  72struct zboot_state {
  73        ulong bzimage_addr;
  74        ulong bzimage_size;
  75        ulong initrd_addr;
  76        ulong initrd_size;
  77        ulong load_address;
  78        struct boot_params *base_ptr;
  79        char *cmdline;
  80} state;
  81
  82enum {
  83        ZBOOT_STATE_START       = BIT(0),
  84        ZBOOT_STATE_LOAD        = BIT(1),
  85        ZBOOT_STATE_SETUP       = BIT(2),
  86        ZBOOT_STATE_INFO        = BIT(3),
  87        ZBOOT_STATE_GO          = BIT(4),
  88
  89        /* This one doesn't execute automatically, so stop the count before 5 */
  90        ZBOOT_STATE_DUMP        = BIT(5),
  91        ZBOOT_STATE_COUNT       = 5,
  92};
  93
  94static void build_command_line(char *command_line, int auto_boot)
  95{
  96        char *env_command_line;
  97
  98        command_line[0] = '\0';
  99
 100        env_command_line =  env_get("bootargs");
 101
 102        /* set console= argument if we use a serial console */
 103        if (!strstr(env_command_line, "console=")) {
 104                if (!strcmp(env_get("stdout"), "serial")) {
 105
 106                        /* We seem to use serial console */
 107                        sprintf(command_line, "console=ttyS0,%s ",
 108                                env_get("baudrate"));
 109                }
 110        }
 111
 112        if (auto_boot)
 113                strcat(command_line, "auto ");
 114
 115        if (env_command_line)
 116                strcat(command_line, env_command_line);
 117#ifdef DEBUG
 118        printf("Kernel command line:");
 119        puts(command_line);
 120        printf("\n");
 121#endif
 122}
 123
 124static int kernel_magic_ok(struct setup_header *hdr)
 125{
 126        if (KERNEL_MAGIC != hdr->boot_flag) {
 127                printf("Error: Invalid Boot Flag "
 128                        "(found 0x%04x, expected 0x%04x)\n",
 129                        hdr->boot_flag, KERNEL_MAGIC);
 130                return 0;
 131        } else {
 132                printf("Valid Boot Flag\n");
 133                return 1;
 134        }
 135}
 136
 137static int get_boot_protocol(struct setup_header *hdr, bool verbose)
 138{
 139        if (hdr->header == KERNEL_V2_MAGIC) {
 140                if (verbose)
 141                        printf("Magic signature found\n");
 142                return hdr->version;
 143        } else {
 144                /* Very old kernel */
 145                if (verbose)
 146                        printf("Magic signature not found\n");
 147                return 0x0100;
 148        }
 149}
 150
 151static int setup_device_tree(struct setup_header *hdr, const void *fdt_blob)
 152{
 153        int bootproto = get_boot_protocol(hdr, false);
 154        struct setup_data *sd;
 155        int size;
 156
 157        if (bootproto < 0x0209)
 158                return -ENOTSUPP;
 159
 160        if (!fdt_blob)
 161                return 0;
 162
 163        size = fdt_totalsize(fdt_blob);
 164        if (size < 0)
 165                return -EINVAL;
 166
 167        size += sizeof(struct setup_data);
 168        sd = (struct setup_data *)malloc(size);
 169        if (!sd) {
 170                printf("Not enough memory for DTB setup data\n");
 171                return -ENOMEM;
 172        }
 173
 174        sd->next = hdr->setup_data;
 175        sd->type = SETUP_DTB;
 176        sd->len = fdt_totalsize(fdt_blob);
 177        memcpy(sd->data, fdt_blob, sd->len);
 178        hdr->setup_data = (unsigned long)sd;
 179
 180        return 0;
 181}
 182
 183static const char *get_kernel_version(struct boot_params *params,
 184                                      void *kernel_base)
 185{
 186        struct setup_header *hdr = &params->hdr;
 187        int bootproto;
 188        const char *s, *end;
 189
 190        bootproto = get_boot_protocol(hdr, false);
 191        if (bootproto < 0x0200 || hdr->setup_sects < 15)
 192                return NULL;
 193
 194        /* sanity-check the kernel version in case it is missing */
 195        for (s = kernel_base + hdr->kernel_version + 0x200, end = s + 0x100; *s;
 196             s++) {
 197                if (!isprint(*s))
 198                        return NULL;
 199        }
 200
 201        return kernel_base + hdr->kernel_version + 0x200;
 202}
 203
 204struct boot_params *load_zimage(char *image, unsigned long kernel_size,
 205                                ulong *load_addressp)
 206{
 207        struct boot_params *setup_base;
 208        const char *version;
 209        int setup_size;
 210        int bootproto;
 211        int big_image;
 212
 213        struct boot_params *params = (struct boot_params *)image;
 214        struct setup_header *hdr = &params->hdr;
 215
 216        /* base address for real-mode segment */
 217        setup_base = (struct boot_params *)DEFAULT_SETUP_BASE;
 218
 219        if (!kernel_magic_ok(hdr))
 220                return 0;
 221
 222        /* determine size of setup */
 223        if (0 == hdr->setup_sects) {
 224                log_warning("Setup Sectors = 0 (defaulting to 4)\n");
 225                setup_size = 5 * 512;
 226        } else {
 227                setup_size = (hdr->setup_sects + 1) * 512;
 228        }
 229
 230        log_debug("Setup Size = 0x%8.8lx\n", (ulong)setup_size);
 231
 232        if (setup_size > SETUP_MAX_SIZE)
 233                printf("Error: Setup is too large (%d bytes)\n", setup_size);
 234
 235        /* determine boot protocol version */
 236        bootproto = get_boot_protocol(hdr, true);
 237
 238        log_debug("Using boot protocol version %x.%02x\n",
 239                  (bootproto & 0xff00) >> 8, bootproto & 0xff);
 240
 241        version = get_kernel_version(params, image);
 242        if (version)
 243                printf("Linux kernel version %s\n", version);
 244        else
 245                printf("Setup Sectors < 15 - Cannot print kernel version\n");
 246
 247        /* Determine image type */
 248        big_image = (bootproto >= 0x0200) &&
 249                    (hdr->loadflags & BIG_KERNEL_FLAG);
 250
 251        /* Determine load address */
 252        if (big_image)
 253                *load_addressp = BZIMAGE_LOAD_ADDR;
 254        else
 255                *load_addressp = ZIMAGE_LOAD_ADDR;
 256
 257        printf("Building boot_params at 0x%8.8lx\n", (ulong)setup_base);
 258        memset(setup_base, 0, sizeof(*setup_base));
 259        setup_base->hdr = params->hdr;
 260
 261        if (bootproto >= 0x0204)
 262                kernel_size = hdr->syssize * 16;
 263        else
 264                kernel_size -= setup_size;
 265
 266        if (bootproto == 0x0100) {
 267                /*
 268                 * A very old kernel MUST have its real-mode code
 269                 * loaded at 0x90000
 270                 */
 271                if ((ulong)setup_base != 0x90000) {
 272                        /* Copy the real-mode kernel */
 273                        memmove((void *)0x90000, setup_base, setup_size);
 274
 275                        /* Copy the command line */
 276                        memmove((void *)0x99000,
 277                                (u8 *)setup_base + COMMAND_LINE_OFFSET,
 278                                COMMAND_LINE_SIZE);
 279
 280                         /* Relocated */
 281                        setup_base = (struct boot_params *)0x90000;
 282                }
 283
 284                /* It is recommended to clear memory up to the 32K mark */
 285                memset((u8 *)0x90000 + setup_size, 0,
 286                       SETUP_MAX_SIZE - setup_size);
 287        }
 288
 289        if (big_image) {
 290                if (kernel_size > BZIMAGE_MAX_SIZE) {
 291                        printf("Error: bzImage kernel too big! "
 292                                "(size: %ld, max: %d)\n",
 293                                kernel_size, BZIMAGE_MAX_SIZE);
 294                        return 0;
 295                }
 296        } else if ((kernel_size) > ZIMAGE_MAX_SIZE) {
 297                printf("Error: zImage kernel too big! (size: %ld, max: %d)\n",
 298                       kernel_size, ZIMAGE_MAX_SIZE);
 299                return 0;
 300        }
 301
 302        printf("Loading %s at address %lx (%ld bytes)\n",
 303               big_image ? "bzImage" : "zImage", *load_addressp, kernel_size);
 304
 305        memmove((void *)*load_addressp, image + setup_size, kernel_size);
 306
 307        return setup_base;
 308}
 309
 310int setup_zimage(struct boot_params *setup_base, char *cmd_line, int auto_boot,
 311                 ulong initrd_addr, ulong initrd_size, ulong cmdline_force)
 312{
 313        struct setup_header *hdr = &setup_base->hdr;
 314        int bootproto = get_boot_protocol(hdr, false);
 315
 316        log_debug("Setup E820 entries\n");
 317        if (IS_ENABLED(CONFIG_COREBOOT_SYSINFO)) {
 318                setup_base->e820_entries = cb_install_e820_map(
 319                        ARRAY_SIZE(setup_base->e820_map), setup_base->e820_map);
 320        } else {
 321                setup_base->e820_entries = install_e820_map(
 322                        ARRAY_SIZE(setup_base->e820_map), setup_base->e820_map);
 323        }
 324
 325        if (bootproto == 0x0100) {
 326                setup_base->screen_info.cl_magic = COMMAND_LINE_MAGIC;
 327                setup_base->screen_info.cl_offset = COMMAND_LINE_OFFSET;
 328        }
 329        if (bootproto >= 0x0200) {
 330                hdr->type_of_loader = 0x80;     /* U-Boot version 0 */
 331                if (initrd_addr) {
 332                        printf("Initial RAM disk at linear address "
 333                               "0x%08lx, size %ld bytes\n",
 334                               initrd_addr, initrd_size);
 335
 336                        hdr->ramdisk_image = initrd_addr;
 337                        hdr->ramdisk_size = initrd_size;
 338                }
 339        }
 340
 341        if (bootproto >= 0x0201) {
 342                hdr->heap_end_ptr = HEAP_END_OFFSET;
 343                hdr->loadflags |= HEAP_FLAG;
 344        }
 345
 346        if (cmd_line) {
 347                int max_size = 0xff;
 348                int ret;
 349
 350                log_debug("Setup cmdline\n");
 351                if (bootproto >= 0x0206)
 352                        max_size = hdr->cmdline_size;
 353                if (bootproto >= 0x0202) {
 354                        hdr->cmd_line_ptr = (uintptr_t)cmd_line;
 355                } else if (bootproto >= 0x0200) {
 356                        setup_base->screen_info.cl_magic = COMMAND_LINE_MAGIC;
 357                        setup_base->screen_info.cl_offset =
 358                                (uintptr_t)cmd_line - (uintptr_t)setup_base;
 359
 360                        hdr->setup_move_size = 0x9100;
 361                }
 362
 363                /* build command line at COMMAND_LINE_OFFSET */
 364                if (cmdline_force)
 365                        strcpy(cmd_line, (char *)cmdline_force);
 366                else
 367                        build_command_line(cmd_line, auto_boot);
 368                ret = bootm_process_cmdline(cmd_line, max_size, BOOTM_CL_ALL);
 369                if (ret) {
 370                        printf("Cmdline setup failed (max_size=%x, bootproto=%x, err=%d)\n",
 371                               max_size, bootproto, ret);
 372                        return ret;
 373                }
 374                printf("Kernel command line: \"");
 375                puts(cmd_line);
 376                printf("\"\n");
 377        }
 378
 379        if (IS_ENABLED(CONFIG_INTEL_MID) && bootproto >= 0x0207)
 380                hdr->hardware_subarch = X86_SUBARCH_INTEL_MID;
 381
 382        if (IS_ENABLED(CONFIG_GENERATE_ACPI_TABLE))
 383                setup_base->acpi_rsdp_addr = acpi_get_rsdp_addr();
 384
 385        log_debug("Setup devicetree\n");
 386        setup_device_tree(hdr, (const void *)env_get_hex("fdtaddr", 0));
 387        setup_video(&setup_base->screen_info);
 388
 389        if (IS_ENABLED(CONFIG_EFI_STUB))
 390                setup_efi_info(&setup_base->efi_info);
 391
 392        return 0;
 393}
 394
 395static int do_zboot_start(struct cmd_tbl *cmdtp, int flag, int argc,
 396                          char *const argv[])
 397{
 398        const char *s;
 399
 400        memset(&state, '\0', sizeof(state));
 401        if (argc >= 2) {
 402                /* argv[1] holds the address of the bzImage */
 403                s = argv[1];
 404        } else {
 405                s = env_get("fileaddr");
 406        }
 407
 408        if (s)
 409                state.bzimage_addr = hextoul(s, NULL);
 410
 411        if (argc >= 3) {
 412                /* argv[2] holds the size of the bzImage */
 413                state.bzimage_size = hextoul(argv[2], NULL);
 414        }
 415
 416        if (argc >= 4)
 417                state.initrd_addr = hextoul(argv[3], NULL);
 418        if (argc >= 5)
 419                state.initrd_size = hextoul(argv[4], NULL);
 420        if (argc >= 6) {
 421                /*
 422                 * When the base_ptr is passed in, we assume that the image is
 423                 * already loaded at the address given by argv[1] and therefore
 424                 * the original bzImage is somewhere else, or not accessible.
 425                 * In any case, we don't need access to the bzImage since all
 426                 * the processing is assumed to be done.
 427                 *
 428                 * So set the base_ptr to the given address, use this arg as the
 429                 * load address and set bzimage_addr to 0 so we know that it
 430                 * cannot be proceesed (or processed again).
 431                 */
 432                state.base_ptr = (void *)hextoul(argv[5], NULL);
 433                state.load_address = state.bzimage_addr;
 434                state.bzimage_addr = 0;
 435        }
 436        if (argc >= 7)
 437                state.cmdline = env_get(argv[6]);
 438
 439        return 0;
 440}
 441
 442static int do_zboot_load(struct cmd_tbl *cmdtp, int flag, int argc,
 443                         char *const argv[])
 444{
 445        struct boot_params *base_ptr;
 446
 447        if (state.base_ptr) {
 448                struct boot_params *from = (struct boot_params *)state.base_ptr;
 449
 450                base_ptr = (struct boot_params *)DEFAULT_SETUP_BASE;
 451                log_debug("Building boot_params at 0x%8.8lx\n",
 452                          (ulong)base_ptr);
 453                memset(base_ptr, '\0', sizeof(*base_ptr));
 454                base_ptr->hdr = from->hdr;
 455        } else {
 456                base_ptr = load_zimage((void *)state.bzimage_addr, state.bzimage_size,
 457                                       &state.load_address);
 458                if (!base_ptr) {
 459                        puts("## Kernel loading failed ...\n");
 460                        return CMD_RET_FAILURE;
 461                }
 462        }
 463        state.base_ptr = base_ptr;
 464        if (env_set_hex("zbootbase", (ulong)base_ptr) ||
 465            env_set_hex("zbootaddr", state.load_address))
 466                return CMD_RET_FAILURE;
 467
 468        return 0;
 469}
 470
 471static int do_zboot_setup(struct cmd_tbl *cmdtp, int flag, int argc,
 472                          char *const argv[])
 473{
 474        struct boot_params *base_ptr = state.base_ptr;
 475        int ret;
 476
 477        if (!base_ptr) {
 478                printf("base is not set: use 'zboot load' first\n");
 479                return CMD_RET_FAILURE;
 480        }
 481        ret = setup_zimage(base_ptr, (char *)base_ptr + COMMAND_LINE_OFFSET,
 482                           0, state.initrd_addr, state.initrd_size,
 483                           (ulong)state.cmdline);
 484        if (ret) {
 485                puts("Setting up boot parameters failed ...\n");
 486                return CMD_RET_FAILURE;
 487        }
 488
 489        return 0;
 490}
 491
 492static int do_zboot_info(struct cmd_tbl *cmdtp, int flag, int argc,
 493                         char *const argv[])
 494{
 495        printf("Kernel loaded at %08lx, setup_base=%p\n",
 496               state.load_address, state.base_ptr);
 497
 498        return 0;
 499}
 500
 501static int do_zboot_go(struct cmd_tbl *cmdtp, int flag, int argc,
 502                       char *const argv[])
 503{
 504        int ret;
 505
 506        disable_interrupts();
 507
 508        /* we assume that the kernel is in place */
 509        ret = boot_linux_kernel((ulong)state.base_ptr, state.load_address,
 510                                false);
 511        printf("Kernel returned! (err=%d)\n", ret);
 512
 513        return CMD_RET_FAILURE;
 514}
 515
 516static void print_num(const char *name, ulong value)
 517{
 518        printf("%-20s: %lx\n", name, value);
 519}
 520
 521static void print_num64(const char *name, u64 value)
 522{
 523        printf("%-20s: %llx\n", name, value);
 524}
 525
 526static const char *const e820_type_name[E820_COUNT] = {
 527        [E820_RAM] = "RAM",
 528        [E820_RESERVED] = "Reserved",
 529        [E820_ACPI] = "ACPI",
 530        [E820_NVS] = "ACPI NVS",
 531        [E820_UNUSABLE] = "Unusable",
 532};
 533
 534static const char *const bootloader_id[] = {
 535        "LILO",
 536        "Loadlin",
 537        "bootsect-loader",
 538        "Syslinux",
 539        "Etherboot/gPXE/iPXE",
 540        "ELILO",
 541        "undefined",
 542        "GRUB",
 543        "U-Boot",
 544        "Xen",
 545        "Gujin",
 546        "Qemu",
 547        "Arcturus Networks uCbootloader",
 548        "kexec-tools",
 549        "Extended",
 550        "Special",
 551        "Reserved",
 552        "Minimal Linux Bootloader",
 553        "OVMF UEFI virtualization stack",
 554};
 555
 556struct flag_info {
 557        uint bit;
 558        const char *name;
 559};
 560
 561static struct flag_info load_flags[] = {
 562        { LOADED_HIGH, "loaded-high" },
 563        { QUIET_FLAG, "quiet" },
 564        { KEEP_SEGMENTS, "keep-segments" },
 565        { CAN_USE_HEAP, "can-use-heap" },
 566};
 567
 568static struct flag_info xload_flags[] = {
 569        { XLF_KERNEL_64, "64-bit-entry" },
 570        { XLF_CAN_BE_LOADED_ABOVE_4G, "can-load-above-4gb" },
 571        { XLF_EFI_HANDOVER_32, "32-efi-handoff" },
 572        { XLF_EFI_HANDOVER_64, "64-efi-handoff" },
 573        { XLF_EFI_KEXEC, "kexec-efi-runtime" },
 574};
 575
 576static void print_flags(struct flag_info *flags, int count, uint value)
 577{
 578        int i;
 579
 580        printf("%-20s:", "");
 581        for (i = 0; i < count; i++) {
 582                uint mask = flags[i].bit;
 583
 584                if (value & mask)
 585                        printf(" %s", flags[i].name);
 586        }
 587        printf("\n");
 588}
 589
 590static void show_loader(struct setup_header *hdr)
 591{
 592        bool version_valid = false;
 593        int type, version;
 594        const char *name;
 595
 596        type = hdr->type_of_loader >> 4;
 597        version = hdr->type_of_loader & 0xf;
 598        if (type == 0xe)
 599                type = 0x10 + hdr->ext_loader_type;
 600        version |= hdr->ext_loader_ver << 4;
 601        if (!hdr->type_of_loader) {
 602                name = "pre-2.00 bootloader";
 603        } else if (hdr->type_of_loader == 0xff) {
 604                name = "unknown";
 605        } else if (type < ARRAY_SIZE(bootloader_id)) {
 606                name = bootloader_id[type];
 607                version_valid = true;
 608        } else {
 609                name = "undefined";
 610        }
 611        printf("%20s  %s", "", name);
 612        if (version_valid)
 613                printf(", version %x", version);
 614        printf("\n");
 615}
 616
 617void zimage_dump(struct boot_params *base_ptr)
 618{
 619        struct setup_header *hdr;
 620        const char *version;
 621        int i;
 622
 623        printf("Setup located at %p:\n\n", base_ptr);
 624        print_num64("ACPI RSDP addr", base_ptr->acpi_rsdp_addr);
 625
 626        printf("E820: %d entries\n", base_ptr->e820_entries);
 627        if (base_ptr->e820_entries) {
 628                printf("%18s  %16s  %s\n", "Addr", "Size", "Type");
 629                for (i = 0; i < base_ptr->e820_entries; i++) {
 630                        struct e820_entry *entry = &base_ptr->e820_map[i];
 631
 632                        printf("%12llx  %10llx  %s\n", entry->addr, entry->size,
 633                               entry->type < E820_COUNT ?
 634                               e820_type_name[entry->type] :
 635                               simple_itoa(entry->type));
 636                }
 637        }
 638
 639        hdr = &base_ptr->hdr;
 640        print_num("Setup sectors", hdr->setup_sects);
 641        print_num("Root flags", hdr->root_flags);
 642        print_num("Sys size", hdr->syssize);
 643        print_num("RAM size", hdr->ram_size);
 644        print_num("Video mode", hdr->vid_mode);
 645        print_num("Root dev", hdr->root_dev);
 646        print_num("Boot flag", hdr->boot_flag);
 647        print_num("Jump", hdr->jump);
 648        print_num("Header", hdr->header);
 649        if (hdr->header == KERNEL_V2_MAGIC)
 650                printf("%-20s  %s\n", "", "Kernel V2");
 651        else
 652                printf("%-20s  %s\n", "", "Ancient kernel, using version 100");
 653        print_num("Version", hdr->version);
 654        print_num("Real mode switch", hdr->realmode_swtch);
 655        print_num("Start sys", hdr->start_sys);
 656        print_num("Kernel version", hdr->kernel_version);
 657        version = get_kernel_version(base_ptr, (void *)state.bzimage_addr);
 658        if (version)
 659                printf("   @%p: %s\n", version, version);
 660        print_num("Type of loader", hdr->type_of_loader);
 661        show_loader(hdr);
 662        print_num("Load flags", hdr->loadflags);
 663        print_flags(load_flags, ARRAY_SIZE(load_flags), hdr->loadflags);
 664        print_num("Setup move size", hdr->setup_move_size);
 665        print_num("Code32 start", hdr->code32_start);
 666        print_num("Ramdisk image", hdr->ramdisk_image);
 667        print_num("Ramdisk size", hdr->ramdisk_size);
 668        print_num("Bootsect kludge", hdr->bootsect_kludge);
 669        print_num("Heap end ptr", hdr->heap_end_ptr);
 670        print_num("Ext loader ver", hdr->ext_loader_ver);
 671        print_num("Ext loader type", hdr->ext_loader_type);
 672        print_num("Command line ptr", hdr->cmd_line_ptr);
 673        if (hdr->cmd_line_ptr) {
 674                printf("   ");
 675                /* Use puts() to avoid limits from CONFIG_SYS_PBSIZE */
 676                puts((char *)(ulong)hdr->cmd_line_ptr);
 677                printf("\n");
 678        }
 679        print_num("Initrd addr max", hdr->initrd_addr_max);
 680        print_num("Kernel alignment", hdr->kernel_alignment);
 681        print_num("Relocatable kernel", hdr->relocatable_kernel);
 682        print_num("Min alignment", hdr->min_alignment);
 683        if (hdr->min_alignment)
 684                printf("%-20s: %x\n", "", 1 << hdr->min_alignment);
 685        print_num("Xload flags", hdr->xloadflags);
 686        print_flags(xload_flags, ARRAY_SIZE(xload_flags), hdr->xloadflags);
 687        print_num("Cmdline size", hdr->cmdline_size);
 688        print_num("Hardware subarch", hdr->hardware_subarch);
 689        print_num64("HW subarch data", hdr->hardware_subarch_data);
 690        print_num("Payload offset", hdr->payload_offset);
 691        print_num("Payload length", hdr->payload_length);
 692        print_num64("Setup data", hdr->setup_data);
 693        print_num64("Pref address", hdr->pref_address);
 694        print_num("Init size", hdr->init_size);
 695        print_num("Handover offset", hdr->handover_offset);
 696        if (get_boot_protocol(hdr, false) >= 0x215)
 697                print_num("Kernel info offset", hdr->kernel_info_offset);
 698}
 699
 700static int do_zboot_dump(struct cmd_tbl *cmdtp, int flag, int argc,
 701                         char *const argv[])
 702{
 703        struct boot_params *base_ptr = state.base_ptr;
 704
 705        if (argc > 1)
 706                base_ptr = (void *)hextoul(argv[1], NULL);
 707        if (!base_ptr) {
 708                printf("No zboot setup_base\n");
 709                return CMD_RET_FAILURE;
 710        }
 711        zimage_dump(base_ptr);
 712
 713        return 0;
 714}
 715
 716/* Note: This defines the complete_zboot() function */
 717U_BOOT_SUBCMDS(zboot,
 718        U_BOOT_CMD_MKENT(start, 8, 1, do_zboot_start, "", ""),
 719        U_BOOT_CMD_MKENT(load, 1, 1, do_zboot_load, "", ""),
 720        U_BOOT_CMD_MKENT(setup, 1, 1, do_zboot_setup, "", ""),
 721        U_BOOT_CMD_MKENT(info, 1, 1, do_zboot_info, "", ""),
 722        U_BOOT_CMD_MKENT(go, 1, 1, do_zboot_go, "", ""),
 723        U_BOOT_CMD_MKENT(dump, 2, 1, do_zboot_dump, "", ""),
 724)
 725
 726int do_zboot_states(struct cmd_tbl *cmdtp, int flag, int argc,
 727                    char *const argv[], int state_mask)
 728{
 729        int i;
 730
 731        for (i = 0; i < ZBOOT_STATE_COUNT; i++) {
 732                struct cmd_tbl *cmd = &zboot_subcmds[i];
 733                int mask = 1 << i;
 734                int ret;
 735
 736                if (mask & state_mask) {
 737                        ret = cmd->cmd(cmd, flag, argc, argv);
 738                        if (ret)
 739                                return ret;
 740                }
 741        }
 742
 743        return 0;
 744}
 745
 746int do_zboot_parent(struct cmd_tbl *cmdtp, int flag, int argc,
 747                    char *const argv[], int *repeatable)
 748{
 749        /* determine if we have a sub command */
 750        if (argc > 1) {
 751                char *endp;
 752
 753                hextoul(argv[1], &endp);
 754                /*
 755                 * endp pointing to nul means that argv[1] was just a valid
 756                 * number, so pass it along to the normal processing
 757                 */
 758                if (*endp)
 759                        return do_zboot(cmdtp, flag, argc, argv, repeatable);
 760        }
 761
 762        do_zboot_states(cmdtp, flag, argc, argv, ZBOOT_STATE_START |
 763                        ZBOOT_STATE_LOAD | ZBOOT_STATE_SETUP |
 764                        ZBOOT_STATE_INFO | ZBOOT_STATE_GO);
 765
 766        return CMD_RET_FAILURE;
 767}
 768
 769U_BOOT_CMDREP_COMPLETE(
 770        zboot, 8, do_zboot_parent, "Boot bzImage",
 771        "[addr] [size] [initrd addr] [initrd size] [setup] [cmdline]\n"
 772        "      addr -        The optional starting address of the bzimage.\n"
 773        "                    If not set it defaults to the environment\n"
 774        "                    variable \"fileaddr\".\n"
 775        "      size -        The optional size of the bzimage. Defaults to\n"
 776        "                    zero.\n"
 777        "      initrd addr - The address of the initrd image to use, if any.\n"
 778        "      initrd size - The size of the initrd image to use, if any.\n"
 779        "      setup -       The address of the kernel setup region, if this\n"
 780        "                    is not at addr\n"
 781        "      cmdline -     Environment variable containing the kernel\n"
 782        "                    command line, to override U-Boot's normal\n"
 783        "                    cmdline generation\n"
 784        "\n"
 785        "Sub-commands to do part of the zboot sequence:\n"
 786        "\tstart [addr [arg ...]] - specify arguments\n"
 787        "\tload   - load OS image\n"
 788        "\tsetup  - set up table\n"
 789        "\tinfo   - show summary info\n"
 790        "\tgo     - start OS\n"
 791        "\tdump [addr]    - dump info (optional address of boot params)",
 792        complete_zboot
 793);
 794