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