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