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