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