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