blob: 290c9f0eeb2239263bfb0f237dbf4dce4e76af1d [file] [log] [blame]
b.liue9582032025-04-17 19:18:16 +08001/*
2 * (C) Copyright 2000-2009
3 * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
4 *
5 * SPDX-License-Identifier: GPL-2.0+
6 */
7
8
9/*
10 * Boot support
11 */
12#include <common.h>
13#include <watchdog.h>
14#include <command.h>
15#include <image.h>
16#include <malloc.h>
17#include <u-boot/zlib.h>
18#include <bzlib.h>
19#include <environment.h>
20#include <lmb.h>
21#include <linux/ctype.h>
22#include <asm/byteorder.h>
23#include <asm/io.h>
24#include <linux/compiler.h>
25
26#if defined(CONFIG_BOOTM_VXWORKS) && \
27 (defined(CONFIG_PPC) || defined(CONFIG_ARM))
28#include <vxworks.h>
29#endif
30
31#if defined(CONFIG_CMD_USB)
32#include <usb.h>
33#endif
34
35#ifdef CONFIG_SYS_HUSH_PARSER
36#include <hush.h>
37#endif
38
39#if defined(CONFIG_OF_LIBFDT)
40#include <libfdt.h>
41#include <fdt_support.h>
42#endif
43
44#ifdef CONFIG_LZMA
45#include <lzma/LzmaTypes.h>
46#include <lzma/LzmaDec.h>
47#include <lzma/LzmaTools.h>
48#endif /* CONFIG_LZMA */
49
50#ifdef CONFIG_LZO
51#include <linux/lzo.h>
52#endif /* CONFIG_LZO */
53
54DECLARE_GLOBAL_DATA_PTR;
55
56#ifndef CONFIG_SYS_BOOTM_LEN
57#define CONFIG_SYS_BOOTM_LEN 0x800000 /* use 8MByte as default max gunzip size */
58#endif
59
60#ifdef CONFIG_BZIP2
61extern void bz_internal_error(int);
62#endif
63
64#if defined(CONFIG_CMD_IMI)
65static int image_info(unsigned long addr);
66#endif
67
68#if defined(CONFIG_CMD_IMLS)
69#include <flash.h>
70#include <mtd/cfi_flash.h>
71extern flash_info_t flash_info[]; /* info for FLASH chips */
72#endif
73
74#if defined(CONFIG_CMD_IMLS) || defined(CONFIG_CMD_IMLS_NAND)
75static int do_imls(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]);
76#endif
77
78#include <linux/err.h>
79#include <nand.h>
80
81#ifdef CONFIG_MRVL_BOOT
82#include <mv_boot.h>
83#endif
84
85#if defined(CONFIG_SILENT_CONSOLE) && !defined(CONFIG_SILENT_U_BOOT_ONLY)
86static void fixup_silent_linux(void);
87#endif
88
89static int do_bootm_standalone(int flag, int argc, char * const argv[],
90 bootm_headers_t *images);
91
92static const void *boot_get_kernel(cmd_tbl_t *cmdtp, int flag, int argc,
93 char * const argv[], bootm_headers_t *images,
94 ulong *os_data, ulong *os_len);
95
96/*
97 * Continue booting an OS image; caller already has:
98 * - copied image header to global variable `header'
99 * - checked header magic number, checksums (both header & image),
100 * - verified image architecture (PPC) and type (KERNEL or MULTI),
101 * - loaded (first part of) image to header load address,
102 * - disabled interrupts.
103 *
104 * @flag: Flags indicating what to do (BOOTM_STATE_...)
105 * @argc: Number of arguments. Note that the arguments are shifted down
106 * so that 0 is the first argument not processed by U-Boot, and
107 * argc is adjusted accordingly. This avoids confusion as to how
108 * many arguments are available for the OS.
109 * @images: Pointers to os/initrd/fdt
110 * @return 1 on error. On success the OS boots so this function does
111 * not return.
112 */
113typedef int boot_os_fn(int flag, int argc, char * const argv[],
114 bootm_headers_t *images);
115
116#ifdef CONFIG_BOOTM_LINUX
117extern boot_os_fn do_bootm_linux;
118#endif
119#ifdef CONFIG_BOOTM_NETBSD
120static boot_os_fn do_bootm_netbsd;
121#endif
122#if defined(CONFIG_LYNXKDI)
123static boot_os_fn do_bootm_lynxkdi;
124extern void lynxkdi_boot(image_header_t *);
125#endif
126#ifdef CONFIG_BOOTM_RTEMS
127static boot_os_fn do_bootm_rtems;
128#endif
129#if defined(CONFIG_BOOTM_OSE)
130static boot_os_fn do_bootm_ose;
131#endif
132#if defined(CONFIG_BOOTM_PLAN9)
133static boot_os_fn do_bootm_plan9;
134#endif
135#if defined(CONFIG_BOOTM_VXWORKS) && \
136 (defined(CONFIG_PPC) || defined(CONFIG_ARM))
137static boot_os_fn do_bootm_vxworks;
138#endif
139#if defined(CONFIG_CMD_ELF)
140static boot_os_fn do_bootm_qnxelf;
141int do_bootvx(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]);
142int do_bootelf(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]);
143#endif
144#if defined(CONFIG_INTEGRITY)
145static boot_os_fn do_bootm_integrity;
146#endif
147
148static boot_os_fn *boot_os[] = {
149 [IH_OS_U_BOOT] = do_bootm_standalone,
150#ifdef CONFIG_BOOTM_LINUX
151 [IH_OS_LINUX] = do_bootm_linux,
152#endif
153#ifdef CONFIG_BOOTM_NETBSD
154 [IH_OS_NETBSD] = do_bootm_netbsd,
155#endif
156#ifdef CONFIG_LYNXKDI
157 [IH_OS_LYNXOS] = do_bootm_lynxkdi,
158#endif
159#ifdef CONFIG_BOOTM_RTEMS
160 [IH_OS_RTEMS] = do_bootm_rtems,
161#endif
162#if defined(CONFIG_BOOTM_OSE)
163 [IH_OS_OSE] = do_bootm_ose,
164#endif
165#if defined(CONFIG_BOOTM_PLAN9)
166 [IH_OS_PLAN9] = do_bootm_plan9,
167#endif
168#if defined(CONFIG_BOOTM_VXWORKS) && \
169 (defined(CONFIG_PPC) || defined(CONFIG_ARM))
170 [IH_OS_VXWORKS] = do_bootm_vxworks,
171#endif
172#if defined(CONFIG_CMD_ELF)
173 [IH_OS_QNX] = do_bootm_qnxelf,
174#endif
175#ifdef CONFIG_INTEGRITY
176 [IH_OS_INTEGRITY] = do_bootm_integrity,
177#endif
178};
179
180bootm_headers_t images; /* pointers to os/initrd/fdt images */
181
182/* Allow for arch specific config before we boot */
183static void __arch_preboot_os(void)
184{
185 /* please define platform specific arch_preboot_os() */
186}
187void arch_preboot_os(void) __attribute__((weak, alias("__arch_preboot_os")));
188
189#define IH_INITRD_ARCH IH_ARCH_DEFAULT
190
191#ifdef CONFIG_LMB
192static void boot_start_lmb(bootm_headers_t *images)
193{
194 ulong mem_start;
195 phys_size_t mem_size;
196
197 lmb_init(&images->lmb);
198
199 mem_start = getenv_bootm_low();
200 mem_size = getenv_bootm_size();
201
202 lmb_add(&images->lmb, (phys_addr_t)mem_start, mem_size);
203
204 arch_lmb_reserve(&images->lmb);
205 board_lmb_reserve(&images->lmb);
206}
207#else
208#define lmb_reserve(lmb, base, size)
209static inline void boot_start_lmb(bootm_headers_t *images) { }
210#endif
211
212static int bootm_start(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
213{
214 memset((void *)&images, 0, sizeof(images));
215 images.verify = getenv_yesno("verify");
216
217 boot_start_lmb(&images);
218
219 bootstage_mark_name(BOOTSTAGE_ID_BOOTM_START, "bootm_start");
220 images.state = BOOTM_STATE_START;
221
222 return 0;
223}
224
225static int bootm_find_os(cmd_tbl_t *cmdtp, int flag, int argc,
226 char * const argv[])
227{
228 const void *os_hdr;
229
230 /* get kernel image header, start address and length */
231 os_hdr = boot_get_kernel(cmdtp, flag, argc, argv,
232 &images, &images.os.image_start, &images.os.image_len);
233 if (images.os.image_len == 0) {
234 puts("ERROR: can't get kernel image!\n");
235 return 1;
236 }
237
238 /* get image parameters */
239 switch (genimg_get_format(os_hdr)) {
240 case IMAGE_FORMAT_LEGACY:
241 images.os.type = image_get_type(os_hdr);
242 images.os.comp = image_get_comp(os_hdr);
243 images.os.os = image_get_os(os_hdr);
244
245 images.os.end = image_get_image_end(os_hdr);
246 images.os.load = image_get_load(os_hdr);
247 break;
248#if defined(CONFIG_FIT)
249 case IMAGE_FORMAT_FIT:
250 if (fit_image_get_type(images.fit_hdr_os,
251 images.fit_noffset_os, &images.os.type)) {
252 puts("Can't get image type!\n");
253 bootstage_error(BOOTSTAGE_ID_FIT_TYPE);
254 return 1;
255 }
256
257 if (fit_image_get_comp(images.fit_hdr_os,
258 images.fit_noffset_os, &images.os.comp)) {
259 puts("Can't get image compression!\n");
260 bootstage_error(BOOTSTAGE_ID_FIT_COMPRESSION);
261 return 1;
262 }
263
264 if (fit_image_get_os(images.fit_hdr_os,
265 images.fit_noffset_os, &images.os.os)) {
266 puts("Can't get image OS!\n");
267 bootstage_error(BOOTSTAGE_ID_FIT_OS);
268 return 1;
269 }
270
271 images.os.end = fit_get_end(images.fit_hdr_os);
272
273 if (fit_image_get_load(images.fit_hdr_os, images.fit_noffset_os,
274 &images.os.load)) {
275 puts("Can't get image load address!\n");
276 bootstage_error(BOOTSTAGE_ID_FIT_LOADADDR);
277 return 1;
278 }
279 break;
280#endif
281 default:
282 puts("ERROR: unknown image format type!\n");
283 return 1;
284 }
285
286 /* find kernel entry point */
287 if (images.legacy_hdr_valid) {
288 images.ep = image_get_ep(&images.legacy_hdr_os_copy);
289#if defined(CONFIG_FIT)
290 } else if (images.fit_uname_os) {
291 int ret;
292
293 ret = fit_image_get_entry(images.fit_hdr_os,
294 images.fit_noffset_os, &images.ep);
295 if (ret) {
296 puts("Can't get entry point property!\n");
297 return 1;
298 }
299#endif
300 } else {
301 puts("Could not find kernel entry point!\n");
302 return 1;
303 }
304
305 if (images.os.type == IH_TYPE_KERNEL_NOLOAD) {
306 images.os.load = images.os.image_start;
307 images.ep += images.os.load;
308 }
309
310 images.os.start = (ulong)os_hdr;
311
312 return 0;
313}
314
315static int bootm_find_ramdisk(int flag, int argc, char * const argv[])
316{
317 int ret;
318
319 /* find ramdisk */
320 ret = boot_get_ramdisk(argc, argv, &images, IH_INITRD_ARCH,
321 &images.rd_start, &images.rd_end);
322 if (ret) {
323 puts("Ramdisk image is corrupt or invalid\n");
324 return 1;
325 }
326
327 return 0;
328}
329
330#if defined(CONFIG_OF_LIBFDT)
331static int bootm_find_fdt(int flag, int argc, char * const argv[])
332{
333 int ret;
334
335 /* find flattened device tree */
336 ret = boot_get_fdt(flag, argc, argv, IH_ARCH_DEFAULT, &images,
337 &images.ft_addr, &images.ft_len);
338 if (ret) {
339 puts("Could not find a valid device tree\n");
340 return 1;
341 }
342
343 set_working_fdt_addr(images.ft_addr);
344
345 return 0;
346}
347#endif
348
349static int bootm_find_other(cmd_tbl_t *cmdtp, int flag, int argc,
350 char * const argv[])
351{
352 if (((images.os.type == IH_TYPE_KERNEL) ||
353 (images.os.type == IH_TYPE_KERNEL_NOLOAD) ||
354 (images.os.type == IH_TYPE_MULTI)) &&
355 (images.os.os == IH_OS_LINUX ||
356 images.os.os == IH_OS_VXWORKS)) {
357 if (bootm_find_ramdisk(flag, argc, argv))
358 return 1;
359
360#if defined(CONFIG_OF_LIBFDT)
361 if (bootm_find_fdt(flag, argc, argv))
362 return 1;
363#endif
364 }
365
366 return 0;
367}
368
369#define BOOTM_ERR_RESET -1
370#define BOOTM_ERR_OVERLAP -2
371#define BOOTM_ERR_UNIMPLEMENTED -3
372static int bootm_load_os(bootm_headers_t *images, unsigned long *load_end,
373 int boot_progress)
374{
375 image_info_t os = images->os;
376 uint8_t comp = os.comp;
377 ulong load = os.load;
378 ulong blob_start = os.start;
379 ulong blob_end = os.end;
380 ulong image_start = os.image_start;
381 ulong image_len = os.image_len;
382 __maybe_unused uint unc_len = CONFIG_SYS_BOOTM_LEN;
383 int no_overlap = 0;
384 void *load_buf, *image_buf;
385#if defined(CONFIG_LZMA) || defined(CONFIG_LZO)
386 int ret;
387#endif /* defined(CONFIG_LZMA) || defined(CONFIG_LZO) */
388
389 const char *type_name = genimg_get_type_name(os.type);
390
391 load_buf = map_sysmem(load, unc_len);
392 image_buf = map_sysmem(image_start, image_len);
393 switch (comp) {
394 case IH_COMP_NONE:
395 if (load == blob_start || load == image_start) {
396 printf(" XIP %s ... ", type_name);
397 no_overlap = 1;
398 } else {
399 printf(" Loading %s ... ", type_name);
400 memmove_wd(load_buf, image_buf, image_len, CHUNKSZ);
401 }
402 *load_end = load + image_len;
403 break;
404#ifdef CONFIG_GZIP
405 case IH_COMP_GZIP:
406 printf(" Uncompressing %s ... ", type_name);
407 if (gunzip(load_buf, unc_len, image_buf, &image_len) != 0) {
408 puts("GUNZIP: uncompress, out-of-mem or overwrite "
409 "error - must RESET board to recover\n");
410 if (boot_progress)
411 bootstage_error(BOOTSTAGE_ID_DECOMP_IMAGE);
412 return BOOTM_ERR_RESET;
413 }
414
415 *load_end = load + image_len;
416 break;
417#endif /* CONFIG_GZIP */
418#ifdef CONFIG_BZIP2
419 case IH_COMP_BZIP2:
420 printf(" Uncompressing %s ... ", type_name);
421 /*
422 * If we've got less than 4 MB of malloc() space,
423 * use slower decompression algorithm which requires
424 * at most 2300 KB of memory.
425 */
426 int i = BZ2_bzBuffToBuffDecompress(load_buf, &unc_len,
427 image_buf, image_len,
428 CONFIG_SYS_MALLOC_LEN < (4096 * 1024), 0);
429 if (i != BZ_OK) {
430 printf("BUNZIP2: uncompress or overwrite error %d "
431 "- must RESET board to recover\n", i);
432 if (boot_progress)
433 bootstage_error(BOOTSTAGE_ID_DECOMP_IMAGE);
434 return BOOTM_ERR_RESET;
435 }
436
437 *load_end = load + unc_len;
438 break;
439#endif /* CONFIG_BZIP2 */
440#ifdef CONFIG_LZMA
441 case IH_COMP_LZMA: {
442 SizeT lzma_len = unc_len;
443 printf(" Uncompressing %s ... ", type_name);
444
445 ret = lzmaBuffToBuffDecompress(load_buf, &lzma_len,
446 image_buf, image_len);
447 unc_len = lzma_len;
448 if (ret != SZ_OK) {
449 printf("LZMA: uncompress or overwrite error %d "
450 "- must RESET board to recover\n", ret);
451 bootstage_error(BOOTSTAGE_ID_DECOMP_IMAGE);
452 return BOOTM_ERR_RESET;
453 }
454 *load_end = load + unc_len;
455 break;
456 }
457#endif /* CONFIG_LZMA */
458#ifdef CONFIG_LZO
459 case IH_COMP_LZO: {
460 size_t size;
461
462 printf(" Uncompressing %s ... ", type_name);
463
464 ret = lzop_decompress(image_buf, image_len, load_buf, &size);
465 if (ret != LZO_E_OK) {
466 printf("LZO: uncompress or overwrite error %d "
467 "- must RESET board to recover\n", ret);
468 if (boot_progress)
469 bootstage_error(BOOTSTAGE_ID_DECOMP_IMAGE);
470 return BOOTM_ERR_RESET;
471 }
472
473 *load_end = load + size;
474 break;
475 }
476#endif /* CONFIG_LZO */
477 default:
478 printf("Unimplemented compression type %d\n", comp);
479 return BOOTM_ERR_UNIMPLEMENTED;
480 }
481
482 flush_cache(load, (*load_end - load) * sizeof(ulong));
483
484 puts("OK\n");
485 debug(" kernel loaded at 0x%08lx, end = 0x%08lx\n", load, *load_end);
486 bootstage_mark(BOOTSTAGE_ID_KERNEL_LOADED);
487
488 if (!no_overlap && (load < blob_end) && (*load_end > blob_start)) {
489 debug("images.os.start = 0x%lX, images.os.end = 0x%lx\n",
490 blob_start, blob_end);
491 debug("images.os.load = 0x%lx, load_end = 0x%lx\n", load,
492 *load_end);
493
494 /* Check what type of image this is. */
495 if (images->legacy_hdr_valid) {
496 if (image_get_type(&images->legacy_hdr_os_copy)
497 == IH_TYPE_MULTI)
498 puts("WARNING: legacy format multi component image overwritten\n");
499 return BOOTM_ERR_OVERLAP;
500 } else {
501 puts("ERROR: new format image overwritten - must RESET the board to recover\n");
502 bootstage_error(BOOTSTAGE_ID_OVERWRITTEN);
503 return BOOTM_ERR_RESET;
504 }
505 }
506
507 return 0;
508}
509
510static int do_bootm_standalone(int flag, int argc, char * const argv[],
511 bootm_headers_t *images)
512{
513 char *s;
514 int (*appl)(int, char * const []);
515
516 /* Don't start if "autostart" is set to "no" */
517 if (((s = getenv("autostart")) != NULL) && (strcmp(s, "no") == 0)) {
518 setenv_hex("filesize", images->os.image_len);
519 return 0;
520 }
521 appl = (int (*)(int, char * const []))(ulong)ntohl(images->ep);
522 (*appl)(argc, argv);
523 return 0;
524}
525
526/* we overload the cmd field with our state machine info instead of a
527 * function pointer */
528static cmd_tbl_t cmd_bootm_sub[] = {
529 U_BOOT_CMD_MKENT(start, 0, 1, (void *)BOOTM_STATE_START, "", ""),
530 U_BOOT_CMD_MKENT(loados, 0, 1, (void *)BOOTM_STATE_LOADOS, "", ""),
531#ifdef CONFIG_SYS_BOOT_RAMDISK_HIGH
532 U_BOOT_CMD_MKENT(ramdisk, 0, 1, (void *)BOOTM_STATE_RAMDISK, "", ""),
533#endif
534#ifdef CONFIG_OF_LIBFDT
535 U_BOOT_CMD_MKENT(fdt, 0, 1, (void *)BOOTM_STATE_FDT, "", ""),
536#endif
537 U_BOOT_CMD_MKENT(cmdline, 0, 1, (void *)BOOTM_STATE_OS_CMDLINE, "", ""),
538 U_BOOT_CMD_MKENT(bdt, 0, 1, (void *)BOOTM_STATE_OS_BD_T, "", ""),
539 U_BOOT_CMD_MKENT(prep, 0, 1, (void *)BOOTM_STATE_OS_PREP, "", ""),
540 U_BOOT_CMD_MKENT(fake, 0, 1, (void *)BOOTM_STATE_OS_FAKE_GO, "", ""),
541 U_BOOT_CMD_MKENT(go, 0, 1, (void *)BOOTM_STATE_OS_GO, "", ""),
542};
543
544static int boot_selected_os(int argc, char * const argv[], int state,
545 bootm_headers_t *images, boot_os_fn *boot_fn)
546{
547 arch_preboot_os();
548 boot_fn(state, argc, argv, images);
549
550 /* Stand-alone may return when 'autostart' is 'no' */
551 if (images->os.type == IH_TYPE_STANDALONE ||
552 state == BOOTM_STATE_OS_FAKE_GO) /* We expect to return */
553 return 0;
554 bootstage_error(BOOTSTAGE_ID_BOOT_OS_RETURNED);
555#ifdef DEBUG
556 puts("\n## Control returned to monitor - resetting...\n");
557#endif
558 return BOOTM_ERR_RESET;
559}
560
561/**
562 * bootm_disable_interrupts() - Disable interrupts in preparation for load/boot
563 *
564 * @return interrupt flag (0 if interrupts were disabled, non-zero if they were
565 * enabled)
566 */
567static ulong bootm_disable_interrupts(void)
568{
569 ulong iflag;
570
571 /*
572 * We have reached the point of no return: we are going to
573 * overwrite all exception vector code, so we cannot easily
574 * recover from any failures any more...
575 */
576 iflag = disable_interrupts();
577#ifdef CONFIG_NETCONSOLE
578 /* Stop the ethernet stack if NetConsole could have left it up */
579 eth_halt();
580 eth_unregister(eth_get_dev());
581#endif
582
583#if defined(CONFIG_CMD_USB)
584 /*
585 * turn off USB to prevent the host controller from writing to the
586 * SDRAM while Linux is booting. This could happen (at least for OHCI
587 * controller), because the HCCA (Host Controller Communication Area)
588 * lies within the SDRAM and the host controller writes continously to
589 * this area (as busmaster!). The HccaFrameNumber is for example
590 * updated every 1 ms within the HCCA structure in SDRAM! For more
591 * details see the OpenHCI specification.
592 */
593 usb_stop();
594#endif
595 return iflag;
596}
597
598/**
599 * Execute selected states of the bootm command.
600 *
601 * Note the arguments to this state must be the first argument, Any 'bootm'
602 * or sub-command arguments must have already been taken.
603 *
604 * Note that if states contains more than one flag it MUST contain
605 * BOOTM_STATE_START, since this handles and consumes the command line args.
606 *
607 * Also note that aside from boot_os_fn functions and bootm_load_os no other
608 * functions we store the return value of in 'ret' may use a negative return
609 * value, without special handling.
610 *
611 * @param cmdtp Pointer to bootm command table entry
612 * @param flag Command flags (CMD_FLAG_...)
613 * @param argc Number of subcommand arguments (0 = no arguments)
614 * @param argv Arguments
615 * @param states Mask containing states to run (BOOTM_STATE_...)
616 * @param images Image header information
617 * @param boot_progress 1 to show boot progress, 0 to not do this
618 * @return 0 if ok, something else on error. Some errors will cause this
619 * function to perform a reboot! If states contains BOOTM_STATE_OS_GO
620 * then the intent is to boot an OS, so this function will not return
621 * unless the image type is standalone.
622 */
623static int do_bootm_states(cmd_tbl_t *cmdtp, int flag, int argc,
624 char * const argv[], int states, bootm_headers_t *images,
625 int boot_progress)
626{
627 boot_os_fn *boot_fn;
628 ulong iflag = 0;
629 int ret = 0, need_boot_fn;
630
631 images->state |= states;
632
633 /*
634 * Work through the states and see how far we get. We stop on
635 * any error.
636 */
637 if (states & BOOTM_STATE_START)
638 ret = bootm_start(cmdtp, flag, argc, argv);
639
640 if (!ret && (states & BOOTM_STATE_FINDOS))
641 ret = bootm_find_os(cmdtp, flag, argc, argv);
642
643 if (!ret && (states & BOOTM_STATE_FINDOTHER)) {
644 ret = bootm_find_other(cmdtp, flag, argc, argv);
645 argc = 0; /* consume the args */
646 }
647
648 /* Load the OS */
649 if (!ret && (states & BOOTM_STATE_LOADOS)) {
650 ulong load_end;
651
652 iflag = bootm_disable_interrupts();
653 ret = bootm_load_os(images, &load_end, 0);
654 if (ret == 0)
655 lmb_reserve(&images->lmb, images->os.load,
656 (load_end - images->os.load));
657 else if (ret && ret != BOOTM_ERR_OVERLAP)
658 goto err;
659 else if (ret == BOOTM_ERR_OVERLAP)
660 ret = 0;
661#if defined(CONFIG_SILENT_CONSOLE) && !defined(CONFIG_SILENT_U_BOOT_ONLY)
662 if (images->os.os == IH_OS_LINUX)
663 fixup_silent_linux();
664#endif
665 }
666
667 /* Relocate the ramdisk */
668#ifdef CONFIG_SYS_BOOT_RAMDISK_HIGH
669 if (!ret && (states & BOOTM_STATE_RAMDISK)) {
670 ulong rd_len = images->rd_end - images->rd_start;
671
672 ret = boot_ramdisk_high(&images->lmb, images->rd_start,
673 rd_len, &images->initrd_start, &images->initrd_end);
674 if (!ret) {
675 setenv_hex("initrd_start", images->initrd_start);
676 setenv_hex("initrd_end", images->initrd_end);
677 }
678 }
679#endif
680#if defined(CONFIG_OF_LIBFDT) && defined(CONFIG_LMB)
681 if (!ret && (states & BOOTM_STATE_FDT)) {
682 boot_fdt_add_mem_rsv_regions(&images->lmb, images->ft_addr);
683 ret = boot_relocate_fdt(&images->lmb, &images->ft_addr,
684 &images->ft_len);
685 }
686#endif
687
688 /* From now on, we need the OS boot function */
689 if (ret)
690 return ret;
691 boot_fn = boot_os[images->os.os];
692 need_boot_fn = states & (BOOTM_STATE_OS_CMDLINE |
693 BOOTM_STATE_OS_BD_T | BOOTM_STATE_OS_PREP |
694 BOOTM_STATE_OS_FAKE_GO | BOOTM_STATE_OS_GO);
695 if (boot_fn == NULL && need_boot_fn) {
696 if (iflag)
697 enable_interrupts();
698 printf("ERROR: booting os '%s' (%d) is not supported\n",
699 genimg_get_os_name(images->os.os), images->os.os);
700 bootstage_error(BOOTSTAGE_ID_CHECK_BOOT_OS);
701 return 1;
702 }
703
704 /* Call various other states that are not generally used */
705 if (!ret && (states & BOOTM_STATE_OS_CMDLINE))
706 ret = boot_fn(BOOTM_STATE_OS_CMDLINE, argc, argv, images);
707 if (!ret && (states & BOOTM_STATE_OS_BD_T))
708 ret = boot_fn(BOOTM_STATE_OS_BD_T, argc, argv, images);
709 if (!ret && (states & BOOTM_STATE_OS_PREP))
710 ret = boot_fn(BOOTM_STATE_OS_PREP, argc, argv, images);
711
712#ifdef CONFIG_TRACE
713 /* Pretend to run the OS, then run a user command */
714 if (!ret && (states & BOOTM_STATE_OS_FAKE_GO)) {
715 char *cmd_list = getenv("fakegocmd");
716
717 ret = boot_selected_os(argc, argv, BOOTM_STATE_OS_FAKE_GO,
718 images, boot_fn);
719 if (!ret && cmd_list)
720 ret = run_command_list(cmd_list, -1, flag);
721 }
722#endif
723
724 /* Check for unsupported subcommand. */
725 if (ret) {
726 puts("subcommand not supported\n");
727 return ret;
728 }
729
730 /* Now run the OS! We hope this doesn't return */
731 if (!ret && (states & BOOTM_STATE_OS_GO))
732 ret = boot_selected_os(argc, argv, BOOTM_STATE_OS_GO,
733 images, boot_fn);
734
735 /* Deal with any fallout */
736err:
737 if (iflag)
738 enable_interrupts();
739
740 if (ret == BOOTM_ERR_UNIMPLEMENTED)
741 bootstage_error(BOOTSTAGE_ID_DECOMP_UNIMPL);
742 else if (ret == BOOTM_ERR_RESET)
743 do_reset(cmdtp, flag, argc, argv);
744
745 return ret;
746}
747
748static int do_bootm_subcommand(cmd_tbl_t *cmdtp, int flag, int argc,
749 char * const argv[])
750{
751 int ret = 0;
752 long state;
753 cmd_tbl_t *c;
754
755 c = find_cmd_tbl(argv[0], &cmd_bootm_sub[0], ARRAY_SIZE(cmd_bootm_sub));
756 argc--; argv++;
757
758 if (c) {
759 state = (long)c->cmd;
760 if (state == BOOTM_STATE_START)
761 state |= BOOTM_STATE_FINDOS | BOOTM_STATE_FINDOTHER;
762 } else {
763 /* Unrecognized command */
764 return CMD_RET_USAGE;
765 }
766
767 if (state != BOOTM_STATE_START && images.state >= state) {
768 printf("Trying to execute a command out of order\n");
769 return CMD_RET_USAGE;
770 }
771
772 ret = do_bootm_states(cmdtp, flag, argc, argv, state, &images, 0);
773
774 return ret;
775}
776
777/*******************************************************************/
778/* bootm - boot application image from image in memory */
779/*******************************************************************/
780
781int do_bootm(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
782{
783#ifdef CONFIG_NEEDS_MANUAL_RELOC
784 static int relocated = 0;
785
786 if (!relocated) {
787 int i;
788
789 /* relocate boot function table */
790 for (i = 0; i < ARRAY_SIZE(boot_os); i++)
791 if (boot_os[i] != NULL)
792 boot_os[i] += gd->reloc_off;
793
794 /* relocate names of sub-command table */
795 for (i = 0; i < ARRAY_SIZE(cmd_bootm_sub); i++)
796 cmd_bootm_sub[i].name += gd->reloc_off;
797
798 relocated = 1;
799 }
800#endif
801
802 /* determine if we have a sub command */
803 argc--; argv++;
804 if (argc > 0) {
805 char *endp;
806
807 simple_strtoul(argv[0], &endp, 16);
808 /* endp pointing to NULL means that argv[0] was just a
809 * valid number, pass it along to the normal bootm processing
810 *
811 * If endp is ':' or '#' assume a FIT identifier so pass
812 * along for normal processing.
813 *
814 * Right now we assume the first arg should never be '-'
815 */
816 if ((*endp != 0) && (*endp != ':') && (*endp != '#'))
817 return do_bootm_subcommand(cmdtp, flag, argc, argv);
818 }
819
820 return do_bootm_states(cmdtp, flag, argc, argv, BOOTM_STATE_START |
821 BOOTM_STATE_FINDOS | BOOTM_STATE_FINDOTHER |
822 BOOTM_STATE_LOADOS |
823#if defined(CONFIG_PPC) || defined(CONFIG_MIPS)
824 BOOTM_STATE_OS_CMDLINE |
825#endif
826 BOOTM_STATE_OS_PREP | BOOTM_STATE_OS_FAKE_GO |
827 BOOTM_STATE_OS_GO, &images, 1);
828}
829
830int bootm_maybe_autostart(cmd_tbl_t *cmdtp, const char *cmd)
831{
832 const char *ep = getenv("autostart");
833
834#ifdef CONFIG_MRVL_BOOT
835 image_load_notify(load_addr);
836 image_flash_notify(load_addr);
837#endif
838 if (ep && !strcmp(ep, "yes")) {
839#ifndef CONFIG_MRVL_BOOT
840 char *local_args[2];
841 local_args[0] = (char *)cmd;
842 local_args[1] = NULL;
843#endif
844 printf("Automatic boot of image at addr 0x%08lX ...\n", load_addr);
845#ifdef CONFIG_MRVL_BOOT
846 return run_command("boot", 0);
847#else
848 return do_bootm(cmdtp, 0, 1, local_args);
849#endif
850 }
851
852 return 0;
853}
854
855/**
856 * image_get_kernel - verify legacy format kernel image
857 * @img_addr: in RAM address of the legacy format image to be verified
858 * @verify: data CRC verification flag
859 *
860 * image_get_kernel() verifies legacy image integrity and returns pointer to
861 * legacy image header if image verification was completed successfully.
862 *
863 * returns:
864 * pointer to a legacy image header if valid image was found
865 * otherwise return NULL
866 */
867static image_header_t *image_get_kernel(ulong img_addr, int verify)
868{
869 image_header_t *hdr = (image_header_t *)img_addr;
870
871 if (!image_check_magic(hdr)) {
872 puts("Bad Magic Number\n");
873 bootstage_error(BOOTSTAGE_ID_CHECK_MAGIC);
874 return NULL;
875 }
876 bootstage_mark(BOOTSTAGE_ID_CHECK_HEADER);
877
878 if (!image_check_hcrc(hdr)) {
879 puts("Bad Header Checksum\n");
880 bootstage_error(BOOTSTAGE_ID_CHECK_HEADER);
881 return NULL;
882 }
883
884 bootstage_mark(BOOTSTAGE_ID_CHECK_CHECKSUM);
885 image_print_contents(hdr);
886
887 if (verify) {
888 puts(" Verifying Checksum ... ");
889 if (!image_check_dcrc(hdr)) {
890 printf("Bad Data CRC\n");
891 bootstage_error(BOOTSTAGE_ID_CHECK_CHECKSUM);
892 return NULL;
893 }
894 puts("OK\n");
895 }
896 bootstage_mark(BOOTSTAGE_ID_CHECK_ARCH);
897
898 if (!image_check_target_arch(hdr)) {
899 printf("Unsupported Architecture 0x%x\n", image_get_arch(hdr));
900 bootstage_error(BOOTSTAGE_ID_CHECK_ARCH);
901 return NULL;
902 }
903 return hdr;
904}
905
906/**
907 * boot_get_kernel - find kernel image
908 * @os_data: pointer to a ulong variable, will hold os data start address
909 * @os_len: pointer to a ulong variable, will hold os data length
910 *
911 * boot_get_kernel() tries to find a kernel image, verifies its integrity
912 * and locates kernel data.
913 *
914 * returns:
915 * pointer to image header if valid image was found, plus kernel start
916 * address and length, otherwise NULL
917 */
918static const void *boot_get_kernel(cmd_tbl_t *cmdtp, int flag, int argc,
919 char * const argv[], bootm_headers_t *images, ulong *os_data,
920 ulong *os_len)
921{
922 image_header_t *hdr;
923 ulong img_addr;
924 const void *buf;
925#if defined(CONFIG_FIT)
926 const char *fit_uname_config = NULL;
927 const char *fit_uname_kernel = NULL;
928 int os_noffset;
929#endif
930
931 /* find out kernel image address */
932 if (argc < 1) {
933 img_addr = load_addr;
934 debug("* kernel: default image load address = 0x%08lx\n",
935 load_addr);
936#if defined(CONFIG_FIT)
937 } else if (fit_parse_conf(argv[0], load_addr, &img_addr,
938 &fit_uname_config)) {
939 debug("* kernel: config '%s' from image at 0x%08lx\n",
940 fit_uname_config, img_addr);
941 } else if (fit_parse_subimage(argv[0], load_addr, &img_addr,
942 &fit_uname_kernel)) {
943 debug("* kernel: subimage '%s' from image at 0x%08lx\n",
944 fit_uname_kernel, img_addr);
945#endif
946 } else {
947 img_addr = simple_strtoul(argv[0], NULL, 16);
948 debug("* kernel: cmdline image address = 0x%08lx\n", img_addr);
949 }
950
951 bootstage_mark(BOOTSTAGE_ID_CHECK_MAGIC);
952
953 /* copy from dataflash if needed */
954 img_addr = genimg_get_image(img_addr);
955
956 /* check image type, for FIT images get FIT kernel node */
957 *os_data = *os_len = 0;
958 buf = map_sysmem(img_addr, 0);
959 switch (genimg_get_format(buf)) {
960 case IMAGE_FORMAT_LEGACY:
961 printf("## Booting kernel from Legacy Image at %08lx ...\n",
962 img_addr);
963 hdr = image_get_kernel(img_addr, images->verify);
964 if (!hdr)
965 return NULL;
966 bootstage_mark(BOOTSTAGE_ID_CHECK_IMAGETYPE);
967
968 /* get os_data and os_len */
969 switch (image_get_type(hdr)) {
970 case IH_TYPE_KERNEL:
971 case IH_TYPE_KERNEL_NOLOAD:
972 *os_data = image_get_data(hdr);
973 *os_len = image_get_data_size(hdr);
974 break;
975 case IH_TYPE_MULTI:
976 image_multi_getimg(hdr, 0, os_data, os_len);
977 break;
978 case IH_TYPE_STANDALONE:
979 *os_data = image_get_data(hdr);
980 *os_len = image_get_data_size(hdr);
981 break;
982 default:
983 printf("Wrong Image Type for %s command\n",
984 cmdtp->name);
985 bootstage_error(BOOTSTAGE_ID_CHECK_IMAGETYPE);
986 return NULL;
987 }
988
989 /*
990 * copy image header to allow for image overwrites during
991 * kernel decompression.
992 */
993 memmove(&images->legacy_hdr_os_copy, hdr,
994 sizeof(image_header_t));
995
996 /* save pointer to image header */
997 images->legacy_hdr_os = hdr;
998
999 images->legacy_hdr_valid = 1;
1000 bootstage_mark(BOOTSTAGE_ID_DECOMP_IMAGE);
1001 break;
1002#if defined(CONFIG_FIT)
1003 case IMAGE_FORMAT_FIT:
1004 os_noffset = fit_image_load(images, FIT_KERNEL_PROP,
1005 img_addr,
1006 &fit_uname_kernel, &fit_uname_config,
1007 IH_ARCH_DEFAULT, IH_TYPE_KERNEL,
1008 BOOTSTAGE_ID_FIT_KERNEL_START,
1009 FIT_LOAD_IGNORED, os_data, os_len);
1010 if (os_noffset < 0)
1011 return NULL;
1012
1013 images->fit_hdr_os = map_sysmem(img_addr, 0);
1014 images->fit_uname_os = fit_uname_kernel;
1015 images->fit_uname_cfg = fit_uname_config;
1016 images->fit_noffset_os = os_noffset;
1017 break;
1018#endif
1019 default:
1020 printf("Wrong Image Format for %s command\n", cmdtp->name);
1021 bootstage_error(BOOTSTAGE_ID_FIT_KERNEL_INFO);
1022 return NULL;
1023 }
1024
1025 debug(" kernel data at 0x%08lx, len = 0x%08lx (%ld)\n",
1026 *os_data, *os_len, *os_len);
1027
1028 return buf;
1029}
1030
1031#ifdef CONFIG_SYS_LONGHELP
1032static char bootm_help_text[] =
1033 "[addr [arg ...]]\n - boot application image stored in memory\n"
1034 "\tpassing arguments 'arg ...'; when booting a Linux kernel,\n"
1035 "\t'arg' can be the address of an initrd image\n"
1036#if defined(CONFIG_OF_LIBFDT)
1037 "\tWhen booting a Linux kernel which requires a flat device-tree\n"
1038 "\ta third argument is required which is the address of the\n"
1039 "\tdevice-tree blob. To boot that kernel without an initrd image,\n"
1040 "\tuse a '-' for the second argument. If you do not pass a third\n"
1041 "\ta bd_info struct will be passed instead\n"
1042#endif
1043#if defined(CONFIG_FIT)
1044 "\t\nFor the new multi component uImage format (FIT) addresses\n"
1045 "\tmust be extened to include component or configuration unit name:\n"
1046 "\taddr:<subimg_uname> - direct component image specification\n"
1047 "\taddr#<conf_uname> - configuration specification\n"
1048 "\tUse iminfo command to get the list of existing component\n"
1049 "\timages and configurations.\n"
1050#endif
1051 "\nSub-commands to do part of the bootm sequence. The sub-commands "
1052 "must be\n"
1053 "issued in the order below (it's ok to not issue all sub-commands):\n"
1054 "\tstart [addr [arg ...]]\n"
1055 "\tloados - load OS image\n"
1056#if defined(CONFIG_SYS_BOOT_RAMDISK_HIGH)
1057 "\tramdisk - relocate initrd, set env initrd_start/initrd_end\n"
1058#endif
1059#if defined(CONFIG_OF_LIBFDT)
1060 "\tfdt - relocate flat device tree\n"
1061#endif
1062 "\tcmdline - OS specific command line processing/setup\n"
1063 "\tbdt - OS specific bd_t processing\n"
1064 "\tprep - OS specific prep before relocation or go\n"
1065 "\tgo - start OS";
1066#endif
1067
1068U_BOOT_CMD(
1069 bootm, CONFIG_SYS_MAXARGS, 1, do_bootm,
1070 "boot application image from memory", bootm_help_text
1071);
1072
1073/*******************************************************************/
1074/* bootd - boot default image */
1075/*******************************************************************/
1076#if defined(CONFIG_CMD_BOOTD)
1077int do_bootd(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
1078{
1079 int rcode = 0;
1080
1081 if (run_command(getenv("bootcmd"), flag) < 0)
1082 rcode = 1;
1083 return rcode;
1084}
1085
1086U_BOOT_CMD(
1087 boot, 1, 1, do_bootd,
1088 "boot default, i.e., run 'bootcmd'",
1089 ""
1090);
1091
1092/* keep old command name "bootd" for backward compatibility */
1093U_BOOT_CMD(
1094 bootd, 1, 1, do_bootd,
1095 "boot default, i.e., run 'bootcmd'",
1096 ""
1097);
1098
1099#endif
1100
1101
1102/*******************************************************************/
1103/* iminfo - print header info for a requested image */
1104/*******************************************************************/
1105#if defined(CONFIG_CMD_IMI)
1106static int do_iminfo(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
1107{
1108 int arg;
1109 ulong addr;
1110 int rcode = 0;
1111
1112 if (argc < 2) {
1113 return image_info(load_addr);
1114 }
1115
1116 for (arg = 1; arg < argc; ++arg) {
1117 addr = simple_strtoul(argv[arg], NULL, 16);
1118 if (image_info(addr) != 0)
1119 rcode = 1;
1120 }
1121 return rcode;
1122}
1123
1124static int image_info(ulong addr)
1125{
1126 void *hdr = (void *)addr;
1127
1128 printf("\n## Checking Image at %08lx ...\n", addr);
1129
1130 switch (genimg_get_format(hdr)) {
1131 case IMAGE_FORMAT_LEGACY:
1132 puts(" Legacy image found\n");
1133 if (!image_check_magic(hdr)) {
1134 puts(" Bad Magic Number\n");
1135 return 1;
1136 }
1137
1138 if (!image_check_hcrc(hdr)) {
1139 puts(" Bad Header Checksum\n");
1140 return 1;
1141 }
1142
1143 image_print_contents(hdr);
1144
1145 puts(" Verifying Checksum ... ");
1146 if (!image_check_dcrc(hdr)) {
1147 puts(" Bad Data CRC\n");
1148 return 1;
1149 }
1150 puts("OK\n");
1151 return 0;
1152#if defined(CONFIG_FIT)
1153 case IMAGE_FORMAT_FIT:
1154 puts(" FIT image found\n");
1155
1156 if (!fit_check_format(hdr)) {
1157 puts("Bad FIT image format!\n");
1158 return 1;
1159 }
1160
1161 fit_print_contents(hdr);
1162
1163 if (!fit_all_image_verify(hdr)) {
1164 puts("Bad hash in FIT image!\n");
1165 return 1;
1166 }
1167
1168 return 0;
1169#endif
1170 default:
1171 puts("Unknown image format!\n");
1172 break;
1173 }
1174
1175 return 1;
1176}
1177
1178U_BOOT_CMD(
1179 iminfo, CONFIG_SYS_MAXARGS, 1, do_iminfo,
1180 "print header information for application image",
1181 "addr [addr ...]\n"
1182 " - print header information for application image starting at\n"
1183 " address 'addr' in memory; this includes verification of the\n"
1184 " image contents (magic number, header and payload checksums)"
1185);
1186#endif
1187
1188
1189/*******************************************************************/
1190/* imls - list all images found in flash */
1191/*******************************************************************/
1192#if defined(CONFIG_CMD_IMLS)
1193static int do_imls_nor(void)
1194{
1195 flash_info_t *info;
1196 int i, j;
1197 void *hdr;
1198
1199 for (i = 0, info = &flash_info[0];
1200 i < CONFIG_SYS_MAX_FLASH_BANKS; ++i, ++info) {
1201
1202 if (info->flash_id == FLASH_UNKNOWN)
1203 goto next_bank;
1204 for (j = 0; j < info->sector_count; ++j) {
1205
1206 hdr = (void *)info->start[j];
1207 if (!hdr)
1208 goto next_sector;
1209
1210 switch (genimg_get_format(hdr)) {
1211 case IMAGE_FORMAT_LEGACY:
1212 if (!image_check_hcrc(hdr))
1213 goto next_sector;
1214
1215 printf("Legacy Image at %08lX:\n", (ulong)hdr);
1216 image_print_contents(hdr);
1217
1218 puts(" Verifying Checksum ... ");
1219 if (!image_check_dcrc(hdr)) {
1220 puts("Bad Data CRC\n");
1221 } else {
1222 puts("OK\n");
1223 }
1224 break;
1225#if defined(CONFIG_FIT)
1226 case IMAGE_FORMAT_FIT:
1227 if (!fit_check_format(hdr))
1228 goto next_sector;
1229
1230 printf("FIT Image at %08lX:\n", (ulong)hdr);
1231 fit_print_contents(hdr);
1232 break;
1233#endif
1234 default:
1235 goto next_sector;
1236 }
1237
1238next_sector: ;
1239 }
1240next_bank: ;
1241 }
1242 return 0;
1243}
1244#endif
1245
1246#if defined(CONFIG_CMD_IMLS_NAND)
1247static int nand_imls_legacyimage(nand_info_t *nand, int nand_dev, loff_t off,
1248 size_t len)
1249{
1250 void *imgdata;
1251 int ret;
1252
1253 imgdata = malloc(len);
1254 if (!imgdata) {
1255 printf("May be a Legacy Image at NAND device %d offset %08llX:\n",
1256 nand_dev, off);
1257 printf(" Low memory(cannot allocate memory for image)\n");
1258 return -ENOMEM;
1259 }
1260
1261 ret = nand_read_skip_bad(nand, off, &len,
1262 imgdata);
1263 if (ret < 0 && ret != -EUCLEAN) {
1264 free(imgdata);
1265 return ret;
1266 }
1267
1268 if (!image_check_hcrc(imgdata)) {
1269 free(imgdata);
1270 return 0;
1271 }
1272
1273 printf("Legacy Image at NAND device %d offset %08llX:\n",
1274 nand_dev, off);
1275 image_print_contents(imgdata);
1276
1277 puts(" Verifying Checksum ... ");
1278 if (!image_check_dcrc(imgdata))
1279 puts("Bad Data CRC\n");
1280 else
1281 puts("OK\n");
1282
1283 free(imgdata);
1284
1285 return 0;
1286}
1287
1288static int nand_imls_fitimage(nand_info_t *nand, int nand_dev, loff_t off,
1289 size_t len)
1290{
1291 void *imgdata;
1292 int ret;
1293
1294 imgdata = malloc(len);
1295 if (!imgdata) {
1296 printf("May be a FIT Image at NAND device %d offset %08llX:\n",
1297 nand_dev, off);
1298 printf(" Low memory(cannot allocate memory for image)\n");
1299 return -ENOMEM;
1300 }
1301
1302 ret = nand_read_skip_bad(nand, off, &len,
1303 imgdata);
1304 if (ret < 0 && ret != -EUCLEAN) {
1305 free(imgdata);
1306 return ret;
1307 }
1308
1309 if (!fit_check_format(imgdata)) {
1310 free(imgdata);
1311 return 0;
1312 }
1313
1314 printf("FIT Image at NAND device %d offset %08llX:\n", nand_dev, off);
1315
1316 fit_print_contents(imgdata);
1317 free(imgdata);
1318
1319 return 0;
1320}
1321
1322static int do_imls_nand(void)
1323{
1324 nand_info_t *nand;
1325 int nand_dev = nand_curr_device;
1326 size_t len;
1327 loff_t off;
1328 u32 buffer[16];
1329
1330 if (nand_dev < 0 || nand_dev >= CONFIG_SYS_MAX_NAND_DEVICE) {
1331 puts("\nNo NAND devices available\n");
1332 return -ENODEV;
1333 }
1334
1335 printf("\n");
1336
1337 for (nand_dev = 0; nand_dev < CONFIG_SYS_MAX_NAND_DEVICE; nand_dev++) {
1338 nand = &nand_info[nand_dev];
1339 if (!nand->name || !nand->size)
1340 continue;
1341
1342 for (off = 0; off < nand->size; off += nand->erasesize) {
1343 const image_header_t *header;
1344 int ret;
1345
1346 if (nand_block_isbad(nand, off))
1347 continue;
1348
1349 len = sizeof(buffer);
1350
1351 ret = nand_read(nand, off, &len, (u8 *)buffer);
1352 if (ret < 0 && ret != -EUCLEAN) {
1353 printf("NAND read error %d at offset %08llX\n",
1354 ret, off);
1355 continue;
1356 }
1357
1358 switch (genimg_get_format(buffer)) {
1359 case IMAGE_FORMAT_LEGACY:
1360 header = (const image_header_t *)buffer;
1361
1362 len = image_get_image_size(header);
1363 nand_imls_legacyimage(nand, nand_dev, off, len);
1364 break;
1365#if defined(CONFIG_FIT)
1366 case IMAGE_FORMAT_FIT:
1367 len = fit_get_size(buffer);
1368 nand_imls_fitimage(nand, nand_dev, off, len);
1369 break;
1370#endif
1371 }
1372 }
1373 }
1374
1375 return 0;
1376}
1377#endif
1378
1379#if defined(CONFIG_CMD_IMLS) || defined(CONFIG_CMD_IMLS_NAND)
1380static int do_imls(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
1381{
1382 int ret_nor = 0, ret_nand = 0;
1383
1384#if defined(CONFIG_CMD_IMLS)
1385 ret_nor = do_imls_nor();
1386#endif
1387
1388#if defined(CONFIG_CMD_IMLS_NAND)
1389 ret_nand = do_imls_nand();
1390#endif
1391
1392 if (ret_nor)
1393 return ret_nor;
1394
1395 if (ret_nand)
1396 return ret_nand;
1397
1398 return (0);
1399}
1400
1401U_BOOT_CMD(
1402 imls, 1, 1, do_imls,
1403 "list all images found in flash",
1404 "\n"
1405 " - Prints information about all images found at sector/block\n"
1406 " boundaries in nor/nand flash."
1407);
1408#endif
1409
1410/*******************************************************************/
1411/* helper routines */
1412/*******************************************************************/
1413#if defined(CONFIG_SILENT_CONSOLE) && !defined(CONFIG_SILENT_U_BOOT_ONLY)
1414
1415#define CONSOLE_ARG "console="
1416#define CONSOLE_ARG_LEN (sizeof(CONSOLE_ARG) - 1)
1417
1418static void fixup_silent_linux(void)
1419{
1420 char *buf;
1421 const char *env_val;
1422 char *cmdline = getenv("bootargs");
1423 int want_silent;
1424
1425 /*
1426 * Only fix cmdline when requested. The environment variable can be:
1427 *
1428 * no - we never fixup
1429 * yes - we always fixup
1430 * unset - we rely on the console silent flag
1431 */
1432 want_silent = getenv_yesno("silent_linux");
1433 if (want_silent == 0)
1434 return;
1435 else if (want_silent == -1 && !(gd->flags & GD_FLG_SILENT))
1436 return;
1437
1438 debug("before silent fix-up: %s\n", cmdline);
1439 if (cmdline && (cmdline[0] != '\0')) {
1440 char *start = strstr(cmdline, CONSOLE_ARG);
1441
1442 /* Allocate space for maximum possible new command line */
1443 buf = malloc(strlen(cmdline) + 1 + CONSOLE_ARG_LEN + 1);
1444 if (!buf) {
1445 debug("%s: out of memory\n", __func__);
1446 return;
1447 }
1448
1449 if (start) {
1450 char *end = strchr(start, ' ');
1451 int num_start_bytes = start - cmdline + CONSOLE_ARG_LEN;
1452
1453 strncpy(buf, cmdline, num_start_bytes);
1454 if (end)
1455 strcpy(buf + num_start_bytes, end);
1456 else
1457 buf[num_start_bytes] = '\0';
1458 } else {
1459 sprintf(buf, "%s %s", cmdline, CONSOLE_ARG);
1460 }
1461 env_val = buf;
1462 } else {
1463 buf = NULL;
1464 env_val = CONSOLE_ARG;
1465 }
1466
1467 setenv("bootargs", env_val);
1468 debug("after silent fix-up: %s\n", env_val);
1469 free(buf);
1470}
1471#endif /* CONFIG_SILENT_CONSOLE */
1472
1473#if defined(CONFIG_BOOTM_NETBSD) || defined(CONFIG_BOOTM_PLAN9)
1474static void copy_args(char *dest, int argc, char * const argv[], char delim)
1475{
1476 int i;
1477
1478 for (i = 0; i < argc; i++) {
1479 if (i > 0)
1480 *dest++ = delim;
1481 strcpy(dest, argv[i]);
1482 dest += strlen(argv[i]);
1483 }
1484}
1485#endif
1486
1487/*******************************************************************/
1488/* OS booting routines */
1489/*******************************************************************/
1490
1491#ifdef CONFIG_BOOTM_NETBSD
1492static int do_bootm_netbsd(int flag, int argc, char * const argv[],
1493 bootm_headers_t *images)
1494{
1495 void (*loader)(bd_t *, image_header_t *, char *, char *);
1496 image_header_t *os_hdr, *hdr;
1497 ulong kernel_data, kernel_len;
1498 char *consdev;
1499 char *cmdline;
1500
1501 if (flag != BOOTM_STATE_OS_GO)
1502 return 0;
1503
1504#if defined(CONFIG_FIT)
1505 if (!images->legacy_hdr_valid) {
1506 fit_unsupported_reset("NetBSD");
1507 return 1;
1508 }
1509#endif
1510 hdr = images->legacy_hdr_os;
1511
1512 /*
1513 * Booting a (NetBSD) kernel image
1514 *
1515 * This process is pretty similar to a standalone application:
1516 * The (first part of an multi-) image must be a stage-2 loader,
1517 * which in turn is responsible for loading & invoking the actual
1518 * kernel. The only differences are the parameters being passed:
1519 * besides the board info strucure, the loader expects a command
1520 * line, the name of the console device, and (optionally) the
1521 * address of the original image header.
1522 */
1523 os_hdr = NULL;
1524 if (image_check_type(&images->legacy_hdr_os_copy, IH_TYPE_MULTI)) {
1525 image_multi_getimg(hdr, 1, &kernel_data, &kernel_len);
1526 if (kernel_len)
1527 os_hdr = hdr;
1528 }
1529
1530 consdev = "";
1531#if defined(CONFIG_8xx_CONS_SMC1)
1532 consdev = "smc1";
1533#elif defined(CONFIG_8xx_CONS_SMC2)
1534 consdev = "smc2";
1535#elif defined(CONFIG_8xx_CONS_SCC2)
1536 consdev = "scc2";
1537#elif defined(CONFIG_8xx_CONS_SCC3)
1538 consdev = "scc3";
1539#endif
1540
1541 if (argc > 0) {
1542 ulong len;
1543 int i;
1544
1545 for (i = 0, len = 0; i < argc; i += 1)
1546 len += strlen(argv[i]) + 1;
1547 cmdline = malloc(len);
1548 copy_args(cmdline, argc, argv, ' ');
1549 } else if ((cmdline = getenv("bootargs")) == NULL) {
1550 cmdline = "";
1551 }
1552
1553 loader = (void (*)(bd_t *, image_header_t *, char *, char *))images->ep;
1554
1555 printf("## Transferring control to NetBSD stage-2 loader "
1556 "(at address %08lx) ...\n",
1557 (ulong)loader);
1558
1559 bootstage_mark(BOOTSTAGE_ID_RUN_OS);
1560
1561 /*
1562 * NetBSD Stage-2 Loader Parameters:
1563 * arg[0]: pointer to board info data
1564 * arg[1]: image load address
1565 * arg[2]: char pointer to the console device to use
1566 * arg[3]: char pointer to the boot arguments
1567 */
1568 (*loader)(gd->bd, os_hdr, consdev, cmdline);
1569
1570 return 1;
1571}
1572#endif /* CONFIG_BOOTM_NETBSD*/
1573
1574#ifdef CONFIG_LYNXKDI
1575static int do_bootm_lynxkdi(int flag, int argc, char * const argv[],
1576 bootm_headers_t *images)
1577{
1578 image_header_t *hdr = &images->legacy_hdr_os_copy;
1579
1580 if (flag != BOOTM_STATE_OS_GO)
1581 return 0;
1582
1583#if defined(CONFIG_FIT)
1584 if (!images->legacy_hdr_valid) {
1585 fit_unsupported_reset("Lynx");
1586 return 1;
1587 }
1588#endif
1589
1590 lynxkdi_boot((image_header_t *)hdr);
1591
1592 return 1;
1593}
1594#endif /* CONFIG_LYNXKDI */
1595
1596#ifdef CONFIG_BOOTM_RTEMS
1597static int do_bootm_rtems(int flag, int argc, char * const argv[],
1598 bootm_headers_t *images)
1599{
1600 void (*entry_point)(bd_t *);
1601
1602 if (flag != BOOTM_STATE_OS_GO)
1603 return 0;
1604
1605#if defined(CONFIG_FIT)
1606 if (!images->legacy_hdr_valid) {
1607 fit_unsupported_reset("RTEMS");
1608 return 1;
1609 }
1610#endif
1611
1612 entry_point = (void (*)(bd_t *))images->ep;
1613
1614 printf("## Transferring control to RTEMS (at address %08lx) ...\n",
1615 (ulong)entry_point);
1616
1617 bootstage_mark(BOOTSTAGE_ID_RUN_OS);
1618
1619 /*
1620 * RTEMS Parameters:
1621 * r3: ptr to board info data
1622 */
1623 (*entry_point)(gd->bd);
1624
1625 return 1;
1626}
1627#endif /* CONFIG_BOOTM_RTEMS */
1628
1629#if defined(CONFIG_BOOTM_OSE)
1630static int do_bootm_ose(int flag, int argc, char * const argv[],
1631 bootm_headers_t *images)
1632{
1633 void (*entry_point)(void);
1634
1635 if (flag != BOOTM_STATE_OS_GO)
1636 return 0;
1637
1638#if defined(CONFIG_FIT)
1639 if (!images->legacy_hdr_valid) {
1640 fit_unsupported_reset("OSE");
1641 return 1;
1642 }
1643#endif
1644
1645 entry_point = (void (*)(void))images->ep;
1646
1647 printf("## Transferring control to OSE (at address %08lx) ...\n",
1648 (ulong)entry_point);
1649
1650 bootstage_mark(BOOTSTAGE_ID_RUN_OS);
1651
1652 /*
1653 * OSE Parameters:
1654 * None
1655 */
1656 (*entry_point)();
1657
1658 return 1;
1659}
1660#endif /* CONFIG_BOOTM_OSE */
1661
1662#if defined(CONFIG_BOOTM_PLAN9)
1663static int do_bootm_plan9(int flag, int argc, char * const argv[],
1664 bootm_headers_t *images)
1665{
1666 void (*entry_point)(void);
1667 char *s;
1668
1669 if (flag != BOOTM_STATE_OS_GO)
1670 return 0;
1671
1672#if defined(CONFIG_FIT)
1673 if (!images->legacy_hdr_valid) {
1674 fit_unsupported_reset("Plan 9");
1675 return 1;
1676 }
1677#endif
1678
1679 /* See README.plan9 */
1680 s = getenv("confaddr");
1681 if (s != NULL) {
1682 char *confaddr = (char *)simple_strtoul(s, NULL, 16);
1683
1684 if (argc > 0) {
1685 copy_args(confaddr, argc, argv, '\n');
1686 } else {
1687 s = getenv("bootargs");
1688 if (s != NULL)
1689 strcpy(confaddr, s);
1690 }
1691 }
1692
1693 entry_point = (void (*)(void))images->ep;
1694
1695 printf("## Transferring control to Plan 9 (at address %08lx) ...\n",
1696 (ulong)entry_point);
1697
1698 bootstage_mark(BOOTSTAGE_ID_RUN_OS);
1699
1700 /*
1701 * Plan 9 Parameters:
1702 * None
1703 */
1704 (*entry_point)();
1705
1706 return 1;
1707}
1708#endif /* CONFIG_BOOTM_PLAN9 */
1709
1710#if defined(CONFIG_BOOTM_VXWORKS) && \
1711 (defined(CONFIG_PPC) || defined(CONFIG_ARM))
1712
1713void do_bootvx_fdt(bootm_headers_t *images)
1714{
1715#if defined(CONFIG_OF_LIBFDT)
1716 int ret;
1717 char *bootline;
1718 ulong of_size = images->ft_len;
1719 char **of_flat_tree = &images->ft_addr;
1720 struct lmb *lmb = &images->lmb;
1721
1722 if (*of_flat_tree) {
1723 boot_fdt_add_mem_rsv_regions(lmb, *of_flat_tree);
1724
1725 ret = boot_relocate_fdt(lmb, of_flat_tree, &of_size);
1726 if (ret)
1727 return;
1728
1729 ret = fdt_add_subnode(*of_flat_tree, 0, "chosen");
1730 if ((ret >= 0 || ret == -FDT_ERR_EXISTS)) {
1731 bootline = getenv("bootargs");
1732 if (bootline) {
1733 ret = fdt_find_and_setprop(*of_flat_tree,
1734 "/chosen", "bootargs",
1735 bootline,
1736 strlen(bootline) + 1, 1);
1737 if (ret < 0) {
1738 printf("## ERROR: %s : %s\n", __func__,
1739 fdt_strerror(ret));
1740 return;
1741 }
1742 }
1743 } else {
1744 printf("## ERROR: %s : %s\n", __func__,
1745 fdt_strerror(ret));
1746 return;
1747 }
1748 }
1749#endif
1750
1751 boot_prep_vxworks(images);
1752
1753 bootstage_mark(BOOTSTAGE_ID_RUN_OS);
1754
1755#if defined(CONFIG_OF_LIBFDT)
1756 printf("## Starting vxWorks at 0x%08lx, device tree at 0x%08lx ...\n",
1757 (ulong)images->ep, (ulong)*of_flat_tree);
1758#else
1759 printf("## Starting vxWorks at 0x%08lx\n", (ulong)images->ep);
1760#endif
1761
1762 boot_jump_vxworks(images);
1763
1764 puts("## vxWorks terminated\n");
1765}
1766
1767static int do_bootm_vxworks(int flag, int argc, char * const argv[],
1768 bootm_headers_t *images)
1769{
1770 if (flag != BOOTM_STATE_OS_GO)
1771 return 0;
1772
1773#if defined(CONFIG_FIT)
1774 if (!images->legacy_hdr_valid) {
1775 fit_unsupported_reset("VxWorks");
1776 return 1;
1777 }
1778#endif
1779
1780 do_bootvx_fdt(images);
1781
1782 return 1;
1783}
1784#endif
1785
1786#if defined(CONFIG_CMD_ELF)
1787static int do_bootm_qnxelf(int flag, int argc, char * const argv[],
1788 bootm_headers_t *images)
1789{
1790 char *local_args[2];
1791 char str[16];
1792
1793 if (flag != BOOTM_STATE_OS_GO)
1794 return 0;
1795
1796#if defined(CONFIG_FIT)
1797 if (!images->legacy_hdr_valid) {
1798 fit_unsupported_reset("QNX");
1799 return 1;
1800 }
1801#endif
1802
1803 sprintf(str, "%lx", images->ep); /* write entry-point into string */
1804 local_args[0] = argv[0];
1805 local_args[1] = str; /* and provide it via the arguments */
1806 do_bootelf(NULL, 0, 2, local_args);
1807
1808 return 1;
1809}
1810#endif
1811
1812#ifdef CONFIG_INTEGRITY
1813static int do_bootm_integrity(int flag, int argc, char * const argv[],
1814 bootm_headers_t *images)
1815{
1816 void (*entry_point)(void);
1817
1818 if (flag != BOOTM_STATE_OS_GO)
1819 return 0;
1820
1821#if defined(CONFIG_FIT)
1822 if (!images->legacy_hdr_valid) {
1823 fit_unsupported_reset("INTEGRITY");
1824 return 1;
1825 }
1826#endif
1827
1828 entry_point = (void (*)(void))images->ep;
1829
1830 printf("## Transferring control to INTEGRITY (at address %08lx) ...\n",
1831 (ulong)entry_point);
1832
1833 bootstage_mark(BOOTSTAGE_ID_RUN_OS);
1834
1835 /*
1836 * INTEGRITY Parameters:
1837 * None
1838 */
1839 (*entry_point)();
1840
1841 return 1;
1842}
1843#endif
1844
1845#ifdef CONFIG_CMD_BOOTZ
1846
1847int __weak bootz_setup(ulong image, ulong *start, ulong *end)
1848{
1849 /* Please define bootz_setup() for your platform */
1850
1851 puts("Your platform's zImage format isn't supported yet!\n");
1852 return -1;
1853}
1854
1855/*
1856 * zImage booting support
1857 */
1858static int bootz_start(cmd_tbl_t *cmdtp, int flag, int argc,
1859 char * const argv[], bootm_headers_t *images)
1860{
1861 int ret;
1862 ulong zi_start, zi_end;
1863
1864 ret = do_bootm_states(cmdtp, flag, argc, argv, BOOTM_STATE_START,
1865 images, 1);
1866
1867 /* Setup Linux kernel zImage entry point */
1868 if (!argc) {
1869 images->ep = load_addr;
1870 debug("* kernel: default image load address = 0x%08lx\n",
1871 load_addr);
1872 } else {
1873 images->ep = simple_strtoul(argv[0], NULL, 16);
1874 debug("* kernel: cmdline image address = 0x%08lx\n",
1875 images->ep);
1876 }
1877
1878 ret = bootz_setup(images->ep, &zi_start, &zi_end);
1879 if (ret != 0)
1880 return 1;
1881
1882 lmb_reserve(&images->lmb, images->ep, zi_end - zi_start);
1883
1884 /*
1885 * Handle the BOOTM_STATE_FINDOTHER state ourselves as we do not
1886 * have a header that provide this informaiton.
1887 */
1888 if (bootm_find_ramdisk(flag, argc, argv))
1889 return 1;
1890
1891#if defined(CONFIG_OF_LIBFDT)
1892 if (bootm_find_fdt(flag, argc, argv))
1893 return 1;
1894#endif
1895
1896 return 0;
1897}
1898
1899int do_bootz(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
1900{
1901 int ret;
1902
1903 /* Consume 'bootz' */
1904 argc--; argv++;
1905
1906 if (bootz_start(cmdtp, flag, argc, argv, &images))
1907 return 1;
1908
1909 /*
1910 * We are doing the BOOTM_STATE_LOADOS state ourselves, so must
1911 * disable interrupts ourselves
1912 */
1913 bootm_disable_interrupts();
1914
1915 images.os.os = IH_OS_LINUX;
1916 ret = do_bootm_states(cmdtp, flag, argc, argv,
1917 BOOTM_STATE_OS_PREP | BOOTM_STATE_OS_FAKE_GO |
1918 BOOTM_STATE_OS_GO,
1919 &images, 1);
1920
1921 return ret;
1922}
1923
1924#ifdef CONFIG_SYS_LONGHELP
1925static char bootz_help_text[] =
1926 "[addr [initrd[:size]] [fdt]]\n"
1927 " - boot Linux zImage stored in memory\n"
1928 "\tThe argument 'initrd' is optional and specifies the address\n"
1929 "\tof the initrd in memory. The optional argument ':size' allows\n"
1930 "\tspecifying the size of RAW initrd.\n"
1931#if defined(CONFIG_OF_LIBFDT)
1932 "\tWhen booting a Linux kernel which requires a flat device-tree\n"
1933 "\ta third argument is required which is the address of the\n"
1934 "\tdevice-tree blob. To boot that kernel without an initrd image,\n"
1935 "\tuse a '-' for the second argument. If you do not pass a third\n"
1936 "\ta bd_info struct will be passed instead\n"
1937#endif
1938 "";
1939#endif
1940
1941U_BOOT_CMD(
1942 bootz, CONFIG_SYS_MAXARGS, 1, do_bootz,
1943 "boot Linux zImage image from memory", bootz_help_text
1944);
1945#endif /* CONFIG_CMD_BOOTZ */