]> Git Repo - u-boot.git/blame - boot/bootm.c
bootm: Move arm64-image processing later
[u-boot.git] / boot / bootm.c
CommitLineData
83d290c5 1// SPDX-License-Identifier: GPL-2.0+
b6396403
SG
2/*
3 * (C) Copyright 2000-2009
4 * Wolfgang Denk, DENX Software Engineering, [email protected].
b6396403
SG
5 */
6
ea51a628 7#ifndef USE_HOSTCC
b6396403 8#include <common.h>
ea51a628 9#include <bootstage.h>
51bb3384 10#include <cli.h>
be595146 11#include <command.h>
1eb69ae4 12#include <cpu_func.h>
c7694dd4 13#include <env.h>
90268b87 14#include <errno.h>
b6396403 15#include <fdt_support.h>
36bf446b 16#include <irq_func.h>
b6396403 17#include <lmb.h>
f7ae49fc 18#include <log.h>
b6396403 19#include <malloc.h>
0eb25b61 20#include <mapmem.h>
90526e9f
SG
21#include <net.h>
22#include <asm/cache.h>
401d1c4f 23#include <asm/global_data.h>
b6396403 24#include <asm/io.h>
b6386f38 25#include <linux/sizes.h>
dec166d6 26#include <tpm-v2.h>
b6396403
SG
27#if defined(CONFIG_CMD_USB)
28#include <usb.h>
29#endif
ea51a628
SG
30#else
31#include "mkimage.h"
32#endif
b6396403 33
ea51a628
SG
34#include <bootm.h>
35#include <image.h>
b6396403 36
b6386f38
SG
37#define MAX_CMDLINE_SIZE SZ_4K
38
b6396403
SG
39#define IH_INITRD_ARCH IH_ARCH_DEFAULT
40
ea51a628
SG
41#ifndef USE_HOSTCC
42
43DECLARE_GLOBAL_DATA_PTR;
44
d9d7c20b 45struct bootm_headers images; /* pointers to os/initrd/fdt images */
5db28905 46
09140113 47static const void *boot_get_kernel(struct cmd_tbl *cmdtp, int flag, int argc,
d9d7c20b 48 char *const argv[], struct bootm_headers *images,
b6396403
SG
49 ulong *os_data, ulong *os_len);
50
329da485
SG
51__weak void board_quiesce_devices(void)
52{
53}
54
b6396403 55#ifdef CONFIG_LMB
d9d7c20b 56static void boot_start_lmb(struct bootm_headers *images)
b6396403
SG
57{
58 ulong mem_start;
59 phys_size_t mem_size;
60
723806cc
SG
61 mem_start = env_get_bootm_low();
62 mem_size = env_get_bootm_size();
b6396403 63
9cc2323f
SG
64 lmb_init_and_reserve_range(&images->lmb, (phys_addr_t)mem_start,
65 mem_size, NULL);
b6396403
SG
66}
67#else
68#define lmb_reserve(lmb, base, size)
d9d7c20b 69static inline void boot_start_lmb(struct bootm_headers *images) { }
b6396403
SG
70#endif
71
09140113
SG
72static int bootm_start(struct cmd_tbl *cmdtp, int flag, int argc,
73 char *const argv[])
b6396403
SG
74{
75 memset((void *)&images, 0, sizeof(images));
bfebc8c9 76 images.verify = env_get_yesno("verify");
b6396403
SG
77
78 boot_start_lmb(&images);
79
80 bootstage_mark_name(BOOTSTAGE_ID_BOOTM_START, "bootm_start");
81 images.state = BOOTM_STATE_START;
82
83 return 0;
84}
85
9d46e63d
PR
86static ulong bootm_data_addr(int argc, char *const argv[])
87{
88 ulong addr;
89
90 if (argc > 0)
91 addr = simple_strtoul(argv[0], NULL, 16);
92 else
93 addr = image_load_addr;
94
95 return addr;
96}
97
98static int bootm_pre_load(struct cmd_tbl *cmdtp, int flag, int argc,
99 char *const argv[])
100{
101 ulong data_addr = bootm_data_addr(argc, argv);
102 int ret = 0;
103
494bcf1a 104 if (IS_ENABLED(CONFIG_CMD_BOOTM_PRE_LOAD))
9d46e63d
PR
105 ret = image_pre_load(data_addr);
106
107 if (ret)
108 ret = CMD_RET_FAILURE;
109
110 return ret;
111}
112
09140113
SG
113static int bootm_find_os(struct cmd_tbl *cmdtp, int flag, int argc,
114 char *const argv[])
b6396403
SG
115{
116 const void *os_hdr;
636da203
SO
117#ifdef CONFIG_ANDROID_BOOT_IMAGE
118 const void *vendor_boot_img;
119 const void *boot_img;
120#endif
b6396403 121 bool ep_found = false;
90268b87 122 int ret;
b6396403
SG
123
124 /* get kernel image header, start address and length */
125 os_hdr = boot_get_kernel(cmdtp, flag, argc, argv,
126 &images, &images.os.image_start, &images.os.image_len);
127 if (images.os.image_len == 0) {
128 puts("ERROR: can't get kernel image!\n");
129 return 1;
130 }
131
132 /* get image parameters */
133 switch (genimg_get_format(os_hdr)) {
c76c93a3 134#if CONFIG_IS_ENABLED(LEGACY_IMAGE_FORMAT)
b6396403
SG
135 case IMAGE_FORMAT_LEGACY:
136 images.os.type = image_get_type(os_hdr);
137 images.os.comp = image_get_comp(os_hdr);
138 images.os.os = image_get_os(os_hdr);
139
140 images.os.end = image_get_image_end(os_hdr);
141 images.os.load = image_get_load(os_hdr);
90268b87 142 images.os.arch = image_get_arch(os_hdr);
b6396403
SG
143 break;
144#endif
bf371b4c 145#if CONFIG_IS_ENABLED(FIT)
b6396403
SG
146 case IMAGE_FORMAT_FIT:
147 if (fit_image_get_type(images.fit_hdr_os,
148 images.fit_noffset_os,
149 &images.os.type)) {
150 puts("Can't get image type!\n");
151 bootstage_error(BOOTSTAGE_ID_FIT_TYPE);
152 return 1;
153 }
154
155 if (fit_image_get_comp(images.fit_hdr_os,
156 images.fit_noffset_os,
157 &images.os.comp)) {
158 puts("Can't get image compression!\n");
159 bootstage_error(BOOTSTAGE_ID_FIT_COMPRESSION);
160 return 1;
161 }
162
163 if (fit_image_get_os(images.fit_hdr_os, images.fit_noffset_os,
164 &images.os.os)) {
165 puts("Can't get image OS!\n");
166 bootstage_error(BOOTSTAGE_ID_FIT_OS);
167 return 1;
168 }
169
90268b87
SG
170 if (fit_image_get_arch(images.fit_hdr_os,
171 images.fit_noffset_os,
172 &images.os.arch)) {
173 puts("Can't get image ARCH!\n");
174 return 1;
175 }
176
b6396403
SG
177 images.os.end = fit_get_end(images.fit_hdr_os);
178
179 if (fit_image_get_load(images.fit_hdr_os, images.fit_noffset_os,
180 &images.os.load)) {
181 puts("Can't get image load address!\n");
182 bootstage_error(BOOTSTAGE_ID_FIT_LOADADDR);
183 return 1;
184 }
185 break;
186#endif
187#ifdef CONFIG_ANDROID_BOOT_IMAGE
188 case IMAGE_FORMAT_ANDROID:
636da203
SO
189 boot_img = os_hdr;
190 vendor_boot_img = NULL;
191 if (IS_ENABLED(CONFIG_CMD_ABOOTIMG)) {
192 boot_img = map_sysmem(get_abootimg_addr(), 0);
193 vendor_boot_img = map_sysmem(get_avendor_bootimg_addr(), 0);
194 }
b6396403 195 images.os.type = IH_TYPE_KERNEL;
636da203 196 images.os.comp = android_image_get_kcomp(boot_img, vendor_boot_img);
b6396403 197 images.os.os = IH_OS_LINUX;
636da203
SO
198 images.os.end = android_image_get_end(boot_img, vendor_boot_img);
199 images.os.load = android_image_get_kload(boot_img, vendor_boot_img);
86f4695b
AD
200 images.ep = images.os.load;
201 ep_found = true;
636da203
SO
202 if (IS_ENABLED(CONFIG_CMD_ABOOTIMG)) {
203 unmap_sysmem(vendor_boot_img);
204 unmap_sysmem(boot_img);
205 }
b6396403
SG
206 break;
207#endif
208 default:
209 puts("ERROR: unknown image format type!\n");
210 return 1;
211 }
212
90268b87 213 /* If we have a valid setup.bin, we will use that for entry (x86) */
5bda35cf
SG
214 if (images.os.arch == IH_ARCH_I386 ||
215 images.os.arch == IH_ARCH_X86_64) {
90268b87
SG
216 ulong len;
217
218 ret = boot_get_setup(&images, IH_ARCH_I386, &images.ep, &len);
219 if (ret < 0 && ret != -ENOENT) {
220 puts("Could not find a valid setup.bin for x86\n");
221 return 1;
222 }
223 /* Kernel entry point is the setup.bin */
224 } else if (images.legacy_hdr_valid) {
b6396403 225 images.ep = image_get_ep(&images.legacy_hdr_os_copy);
bf371b4c 226#if CONFIG_IS_ENABLED(FIT)
b6396403
SG
227 } else if (images.fit_uname_os) {
228 int ret;
229
230 ret = fit_image_get_entry(images.fit_hdr_os,
231 images.fit_noffset_os, &images.ep);
232 if (ret) {
233 puts("Can't get entry point property!\n");
234 return 1;
235 }
236#endif
237 } else if (!ep_found) {
238 puts("Could not find kernel entry point!\n");
239 return 1;
240 }
241
242 if (images.os.type == IH_TYPE_KERNEL_NOLOAD) {
bb07cdb1
SG
243 images.os.load = images.os.image_start;
244 images.ep += images.os.image_start;
b6396403
SG
245 }
246
7a80de46 247 images.os.start = map_to_sysmem(os_hdr);
b6396403
SG
248
249 return 0;
250}
251
d52e8575
KA
252/**
253 * bootm_find_images - wrapper to find and locate various images
254 * @flag: Ignored Argument
255 * @argc: command argument count
256 * @argv: command argument list
fbde7589
TK
257 * @start: OS image start address
258 * @size: OS image size
d52e8575
KA
259 *
260 * boot_find_images() will attempt to load an available ramdisk,
261 * flattened device tree, as well as specifically marked
262 * "loadable" images (loadables are FIT only)
263 *
264 * Note: bootm_find_images will skip an image if it is not found
265 *
266 * @return:
267 * 0, if all existing images were loaded correctly
268 * 1, if an image is found but corrupted, or invalid
269 */
fbde7589
TK
270int bootm_find_images(int flag, int argc, char *const argv[], ulong start,
271 ulong size)
b6396403
SG
272{
273 int ret;
274
275 /* find ramdisk */
276 ret = boot_get_ramdisk(argc, argv, &images, IH_INITRD_ARCH,
277 &images.rd_start, &images.rd_end);
278 if (ret) {
279 puts("Ramdisk image is corrupt or invalid\n");
280 return 1;
281 }
282
fbde7589
TK
283 /* check if ramdisk overlaps OS image */
284 if (images.rd_start && (((ulong)images.rd_start >= start &&
ef4f4f1f
JC
285 (ulong)images.rd_start < start + size) ||
286 ((ulong)images.rd_end > start &&
287 (ulong)images.rd_end <= start + size) ||
288 ((ulong)images.rd_start < start &&
289 (ulong)images.rd_end >= start + size))) {
fbde7589
TK
290 printf("ERROR: RD image overlaps OS image (OS=0x%lx..0x%lx)\n",
291 start, start + size);
292 return 1;
293 }
294
0c303f9a 295#if CONFIG_IS_ENABLED(OF_LIBFDT)
b6396403
SG
296 /* find flattened device tree */
297 ret = boot_get_fdt(flag, argc, argv, IH_ARCH_DEFAULT, &images,
298 &images.ft_addr, &images.ft_len);
299 if (ret) {
300 puts("Could not find a valid device tree\n");
301 return 1;
302 }
fbde7589
TK
303
304 /* check if FDT overlaps OS image */
305 if (images.ft_addr &&
306 (((ulong)images.ft_addr >= start &&
5acfdfbd 307 (ulong)images.ft_addr < start + size) ||
fbde7589 308 ((ulong)images.ft_addr + images.ft_len >= start &&
5acfdfbd 309 (ulong)images.ft_addr + images.ft_len < start + size))) {
fbde7589
TK
310 printf("ERROR: FDT image overlaps OS image (OS=0x%lx..0x%lx)\n",
311 start, start + size);
312 return 1;
313 }
314
3a09f38d 315 if (IS_ENABLED(CONFIG_CMD_FDT))
596be5f3 316 set_working_fdt_addr(map_to_sysmem(images.ft_addr));
b6396403
SG
317#endif
318
bf371b4c 319#if CONFIG_IS_ENABLED(FIT)
4ed37abc
SG
320 if (IS_ENABLED(CONFIG_FPGA)) {
321 /* find bitstreams */
322 ret = boot_get_fpga(argc, argv, &images, IH_ARCH_DEFAULT,
323 NULL, NULL);
324 if (ret) {
325 printf("FPGA image is corrupted or invalid\n");
326 return 1;
327 }
62afc601 328 }
62afc601 329
84a07dbf
KA
330 /* find all of the loadables */
331 ret = boot_get_loadable(argc, argv, &images, IH_ARCH_DEFAULT,
332 NULL, NULL);
333 if (ret) {
334 printf("Loadable(s) is corrupt or invalid\n");
335 return 1;
336 }
84a07dbf
KA
337#endif
338
b6396403
SG
339 return 0;
340}
341
09140113
SG
342static int bootm_find_other(struct cmd_tbl *cmdtp, int flag, int argc,
343 char *const argv[])
b6396403
SG
344{
345 if (((images.os.type == IH_TYPE_KERNEL) ||
346 (images.os.type == IH_TYPE_KERNEL_NOLOAD) ||
347 (images.os.type == IH_TYPE_MULTI)) &&
348 (images.os.os == IH_OS_LINUX ||
349 images.os.os == IH_OS_VXWORKS))
fbde7589 350 return bootm_find_images(flag, argc, argv, 0, 0);
b6396403
SG
351
352 return 0;
353}
40e5975f
SG
354#endif /* USE_HOSTC */
355
2090854c 356#if !defined(USE_HOSTCC) || defined(CONFIG_FIT_SIGNATURE)
3086c055
SG
357/**
358 * handle_decomp_error() - display a decompression error
359 *
360 * This function tries to produce a useful message. In the case where the
361 * uncompressed size is the same as the available space, we can assume that
362 * the image is too large for the buffer.
363 *
364 * @comp_type: Compression type being used (IH_COMP_...)
365 * @uncomp_size: Number of bytes uncompressed
c45568cc 366 * @buf_size: Number of bytes the decompresion buffer was
2090854c 367 * @ret: errno error code received from compression library
185f812c 368 * Return: Appropriate BOOTM_ERR_ error code
3086c055 369 */
c45568cc
TR
370static int handle_decomp_error(int comp_type, size_t uncomp_size,
371 size_t buf_size, int ret)
40e5975f 372{
3086c055
SG
373 const char *name = genimg_get_comp_name(comp_type);
374
2090854c
JW
375 /* ENOSYS means unimplemented compression type, don't reset. */
376 if (ret == -ENOSYS)
377 return BOOTM_ERR_UNIMPLEMENTED;
378
c45568cc 379 if (uncomp_size >= buf_size)
3086c055 380 printf("Image too large: increase CONFIG_SYS_BOOTM_LEN\n");
40e5975f 381 else
3086c055
SG
382 printf("%s: uncompress error %d\n", name, ret);
383
384 /*
385 * The decompression routines are now safe, so will not write beyond
386 * their bounds. Probably it is not necessary to reset, but maintain
387 * the current behaviour for now.
388 */
389 printf("Must RESET board to recover\n");
40e5975f
SG
390#ifndef USE_HOSTCC
391 bootstage_error(BOOTSTAGE_ID_DECOMP_IMAGE);
392#endif
393
394 return BOOTM_ERR_RESET;
395}
2090854c 396#endif
2b164f1c 397
ce1400f6 398#ifndef USE_HOSTCC
d9d7c20b 399static int bootm_load_os(struct bootm_headers *images, int boot_progress)
2b164f1c 400{
da79b2f2 401 struct image_info os = images->os;
2b164f1c 402 ulong load = os.load;
cc955358 403 ulong load_end;
2b164f1c
SG
404 ulong blob_start = os.start;
405 ulong blob_end = os.end;
406 ulong image_start = os.image_start;
407 ulong image_len = os.image_len;
bbac9222 408 ulong flush_start = ALIGN_DOWN(load, ARCH_DMA_MINALIGN);
2b164f1c
SG
409 bool no_overlap;
410 void *load_buf, *image_buf;
411 int err;
412
413 load_buf = map_sysmem(load, 0);
414 image_buf = map_sysmem(os.image_start, image_len);
2090854c
JW
415 err = image_decomp(os.comp, load, os.image_start, os.type,
416 load_buf, image_buf, image_len,
417 CONFIG_SYS_BOOTM_LEN, &load_end);
2b164f1c 418 if (err) {
c45568cc
TR
419 err = handle_decomp_error(os.comp, load_end - load,
420 CONFIG_SYS_BOOTM_LEN, err);
2b164f1c
SG
421 bootstage_error(BOOTSTAGE_ID_DECOMP_IMAGE);
422 return err;
423 }
21d39468
HS
424 /* We need the decompressed image size in the next steps */
425 images->os.image_len = load_end - load;
bbac9222 426
b4353b37 427 flush_cache(flush_start, ALIGN(load_end, ARCH_DMA_MINALIGN) - flush_start);
b6396403 428
cc955358 429 debug(" kernel loaded at 0x%08lx, end = 0x%08lx\n", load, load_end);
b6396403
SG
430 bootstage_mark(BOOTSTAGE_ID_KERNEL_LOADED);
431
2b164f1c
SG
432 no_overlap = (os.comp == IH_COMP_NONE && load == image_start);
433
cc955358 434 if (!no_overlap && load < blob_end && load_end > blob_start) {
b6396403
SG
435 debug("images.os.start = 0x%lX, images.os.end = 0x%lx\n",
436 blob_start, blob_end);
437 debug("images.os.load = 0x%lx, load_end = 0x%lx\n", load,
cc955358 438 load_end);
b6396403
SG
439
440 /* Check what type of image this is. */
441 if (images->legacy_hdr_valid) {
442 if (image_get_type(&images->legacy_hdr_os_copy)
443 == IH_TYPE_MULTI)
444 puts("WARNING: legacy format multi component image overwritten\n");
445 return BOOTM_ERR_OVERLAP;
446 } else {
447 puts("ERROR: new format image overwritten - must RESET the board to recover\n");
448 bootstage_error(BOOTSTAGE_ID_OVERWRITTEN);
449 return BOOTM_ERR_RESET;
450 }
451 }
452
bb07cdb1
SG
453 if (IS_ENABLED(CONFIG_CMD_BOOTI) && images->os.arch == IH_ARCH_ARM64 &&
454 images->os.os == IH_OS_LINUX) {
455 ulong relocated_addr;
456 ulong image_size;
457 int ret;
458
459 ret = booti_setup(load, &relocated_addr, &image_size, false);
460 if (ret) {
461 printf("Failed to prep arm64 kernel (err=%d)\n", ret);
462 return BOOTM_ERR_RESET;
463 }
464
465 /* Handle BOOTM_STATE_LOADOS */
466 if (relocated_addr != load) {
467 printf("Moving Image from 0x%lx to 0x%lx, end=%lx\n",
468 load, relocated_addr,
469 relocated_addr + image_size);
470 memmove((void *)relocated_addr, load_buf, image_size);
471 }
472
473 images->ep = relocated_addr;
474 images->os.start = relocated_addr;
475 images->os.end = relocated_addr + image_size;
476 }
477
cc955358
TR
478 lmb_reserve(&images->lmb, images->os.load, (load_end -
479 images->os.load));
b6396403
SG
480 return 0;
481}
482
483/**
484 * bootm_disable_interrupts() - Disable interrupts in preparation for load/boot
485 *
185f812c 486 * Return: interrupt flag (0 if interrupts were disabled, non-zero if they were
b6396403
SG
487 * enabled)
488 */
489ulong bootm_disable_interrupts(void)
490{
491 ulong iflag;
492
493 /*
494 * We have reached the point of no return: we are going to
495 * overwrite all exception vector code, so we cannot easily
496 * recover from any failures any more...
497 */
498 iflag = disable_interrupts();
499#ifdef CONFIG_NETCONSOLE
500 /* Stop the ethernet stack if NetConsole could have left it up */
501 eth_halt();
b6396403
SG
502#endif
503
504#if defined(CONFIG_CMD_USB)
505 /*
506 * turn off USB to prevent the host controller from writing to the
507 * SDRAM while Linux is booting. This could happen (at least for OHCI
508 * controller), because the HCCA (Host Controller Communication Area)
509 * lies within the SDRAM and the host controller writes continously to
510 * this area (as busmaster!). The HccaFrameNumber is for example
511 * updated every 1 ms within the HCCA structure in SDRAM! For more
512 * details see the OpenHCI specification.
513 */
514 usb_stop();
515#endif
516 return iflag;
517}
518
6cd92b1a 519#define CONSOLE_ARG "console="
ba9aa40b
SA
520#define NULL_CONSOLE (CONSOLE_ARG "ttynull")
521#define CONSOLE_ARG_SIZE sizeof(NULL_CONSOLE)
b6396403 522
b6386f38
SG
523/**
524 * fixup_silent_linux() - Handle silencing the linux boot if required
525 *
526 * This uses the silent_linux envvar to control whether to add/set a "console="
527 * parameter to the command line
528 *
529 * @buf: Buffer containing the string to process
530 * @maxlen: Maximum length of buffer
185f812c 531 * Return: 0 if OK, -ENOSPC if @maxlen is too small
b6386f38
SG
532 */
533static int fixup_silent_linux(char *buf, int maxlen)
b6396403 534{
b6396403 535 int want_silent;
b6386f38
SG
536 char *cmdline;
537 int size;
b6396403 538
b6386f38
SG
539 /*
540 * Move the input string to the end of buffer. The output string will be
541 * built up at the start.
542 */
543 size = strlen(buf) + 1;
544 if (size * 2 > maxlen)
545 return -ENOSPC;
546 cmdline = buf + maxlen - size;
547 memmove(cmdline, buf, size);
b6396403
SG
548 /*
549 * Only fix cmdline when requested. The environment variable can be:
550 *
551 * no - we never fixup
552 * yes - we always fixup
553 * unset - we rely on the console silent flag
554 */
bfebc8c9 555 want_silent = env_get_yesno("silent_linux");
b6396403 556 if (want_silent == 0)
4ae42643 557 return 0;
b6396403 558 else if (want_silent == -1 && !(gd->flags & GD_FLG_SILENT))
4ae42643 559 return 0;
b6396403
SG
560
561 debug("before silent fix-up: %s\n", cmdline);
b6386f38 562 if (*cmdline) {
b6396403
SG
563 char *start = strstr(cmdline, CONSOLE_ARG);
564
b6386f38
SG
565 /* Check space for maximum possible new command line */
566 if (size + CONSOLE_ARG_SIZE > maxlen)
4ae42643 567 return -ENOSPC;
b6396403
SG
568
569 if (start) {
570 char *end = strchr(start, ' ');
6cd92b1a 571 int start_bytes;
b6396403 572
ba9aa40b 573 start_bytes = start - cmdline;
6cd92b1a 574 strncpy(buf, cmdline, start_bytes);
ba9aa40b 575 strncpy(buf + start_bytes, NULL_CONSOLE, CONSOLE_ARG_SIZE);
b6396403 576 if (end)
ba9aa40b 577 strcpy(buf + start_bytes + CONSOLE_ARG_SIZE - 1, end);
b6396403 578 else
ba9aa40b 579 buf[start_bytes + CONSOLE_ARG_SIZE] = '\0';
b6396403 580 } else {
ba9aa40b 581 sprintf(buf, "%s %s", cmdline, NULL_CONSOLE);
b6396403 582 }
b6386f38
SG
583 if (buf + strlen(buf) >= cmdline)
584 return -ENOSPC;
b6396403 585 } else {
ba9aa40b 586 if (maxlen < CONSOLE_ARG_SIZE)
b6386f38 587 return -ENOSPC;
ba9aa40b 588 strcpy(buf, NULL_CONSOLE);
b6396403 589 }
b6386f38
SG
590 debug("after silent fix-up: %s\n", buf);
591
592 return 0;
593}
594
51bb3384
SG
595/**
596 * process_subst() - Handle substitution of ${...} fields in the environment
597 *
598 * Handle variable substitution in the provided buffer
599 *
600 * @buf: Buffer containing the string to process
601 * @maxlen: Maximum length of buffer
185f812c 602 * Return: 0 if OK, -ENOSPC if @maxlen is too small
51bb3384
SG
603 */
604static int process_subst(char *buf, int maxlen)
605{
606 char *cmdline;
607 int size;
608 int ret;
609
610 /* Move to end of buffer */
611 size = strlen(buf) + 1;
612 cmdline = buf + maxlen - size;
613 if (buf + size > cmdline)
614 return -ENOSPC;
615 memmove(cmdline, buf, size);
616
617 ret = cli_simple_process_macros(cmdline, buf, cmdline - buf);
618
619 return ret;
620}
621
4448fe8e
SG
622int bootm_process_cmdline(char *buf, int maxlen, int flags)
623{
624 int ret;
625
626 /* Check config first to enable compiler to eliminate code */
627 if (IS_ENABLED(CONFIG_SILENT_CONSOLE) &&
628 !IS_ENABLED(CONFIG_SILENT_U_BOOT_ONLY) &&
629 (flags & BOOTM_CL_SILENT)) {
630 ret = fixup_silent_linux(buf, maxlen);
631 if (ret)
632 return log_msg_ret("silent", ret);
633 }
a8d69627
SG
634 if (IS_ENABLED(CONFIG_BOOTARGS_SUBST) && IS_ENABLED(CONFIG_CMDLINE) &&
635 (flags & BOOTM_CL_SUBST)) {
51bb3384
SG
636 ret = process_subst(buf, maxlen);
637 if (ret)
185756ec 638 return log_msg_ret("subst", ret);
51bb3384 639 }
4448fe8e
SG
640
641 return 0;
642}
643
b3c01678 644int bootm_process_cmdline_env(int flags)
b6386f38
SG
645{
646 const int maxlen = MAX_CMDLINE_SIZE;
b3c01678 647 bool do_silent;
b6386f38
SG
648 const char *env;
649 char *buf;
650 int ret;
b6396403 651
b6386f38
SG
652 /* First check if any action is needed */
653 do_silent = IS_ENABLED(CONFIG_SILENT_CONSOLE) &&
b3c01678 654 !IS_ENABLED(CONFIG_SILENT_U_BOOT_ONLY) && (flags & BOOTM_CL_SILENT);
51bb3384 655 if (!do_silent && !IS_ENABLED(CONFIG_BOOTARGS_SUBST))
b6386f38
SG
656 return 0;
657
658 env = env_get("bootargs");
659 if (env && strlen(env) >= maxlen)
660 return -E2BIG;
661 buf = malloc(maxlen);
662 if (!buf)
663 return -ENOMEM;
664 if (env)
665 strcpy(buf, env);
666 else
667 *buf = '\0';
4448fe8e 668 ret = bootm_process_cmdline(buf, maxlen, flags);
b6386f38
SG
669 if (!ret) {
670 ret = env_set("bootargs", buf);
671
672 /*
673 * If buf is "" and bootargs does not exist, this will produce
674 * an error trying to delete bootargs. Ignore it
675 */
676 if (ret == -ENOENT)
677 ret = 0;
678 }
b6396403 679 free(buf);
b6386f38
SG
680 if (ret)
681 return log_msg_ret("env", ret);
4ae42643
SG
682
683 return 0;
b6396403 684}
b6396403 685
dec166d6
EJ
686int bootm_measure(struct bootm_headers *images)
687{
688 int ret = 0;
689
690 /* Skip measurement if EFI is going to do it */
691 if (images->os.os == IH_OS_EFI &&
692 IS_ENABLED(CONFIG_EFI_TCG2_PROTOCOL) &&
693 IS_ENABLED(CONFIG_BOOTM_EFI))
694 return ret;
695
696 if (IS_ENABLED(CONFIG_MEASURED_BOOT)) {
697 struct tcg2_event_log elog;
698 struct udevice *dev;
699 void *initrd_buf;
700 void *image_buf;
701 const char *s;
702 u32 rd_len;
703 bool ign;
704
705 elog.log_size = 0;
706 ign = IS_ENABLED(CONFIG_MEASURE_IGNORE_LOG);
707 ret = tcg2_measurement_init(&dev, &elog, ign);
708 if (ret)
709 return ret;
710
711 image_buf = map_sysmem(images->os.image_start,
712 images->os.image_len);
713 ret = tcg2_measure_data(dev, &elog, 8, images->os.image_len,
714 image_buf, EV_COMPACT_HASH,
715 strlen("linux") + 1, (u8 *)"linux");
716 if (ret)
717 goto unmap_image;
718
719 rd_len = images->rd_end - images->rd_start;
720 initrd_buf = map_sysmem(images->rd_start, rd_len);
721 ret = tcg2_measure_data(dev, &elog, 9, rd_len, initrd_buf,
722 EV_COMPACT_HASH, strlen("initrd") + 1,
723 (u8 *)"initrd");
724 if (ret)
725 goto unmap_initrd;
726
727 if (IS_ENABLED(CONFIG_MEASURE_DEVICETREE)) {
728 ret = tcg2_measure_data(dev, &elog, 0, images->ft_len,
729 (u8 *)images->ft_addr,
730 EV_TABLE_OF_DEVICES,
731 strlen("dts") + 1,
732 (u8 *)"dts");
733 if (ret)
734 goto unmap_initrd;
735 }
736
737 s = env_get("bootargs");
738 if (!s)
739 s = "";
740 ret = tcg2_measure_data(dev, &elog, 1, strlen(s) + 1, (u8 *)s,
741 EV_PLATFORM_CONFIG_FLAGS,
742 strlen(s) + 1, (u8 *)s);
743
744unmap_initrd:
745 unmap_sysmem(initrd_buf);
746
747unmap_image:
748 unmap_sysmem(image_buf);
749 tcg2_measurement_term(dev, &elog, ret != 0);
750 }
751
752 return ret;
753}
754
b6396403
SG
755/**
756 * Execute selected states of the bootm command.
757 *
758 * Note the arguments to this state must be the first argument, Any 'bootm'
759 * or sub-command arguments must have already been taken.
760 *
761 * Note that if states contains more than one flag it MUST contain
762 * BOOTM_STATE_START, since this handles and consumes the command line args.
763 *
764 * Also note that aside from boot_os_fn functions and bootm_load_os no other
765 * functions we store the return value of in 'ret' may use a negative return
766 * value, without special handling.
767 *
768 * @param cmdtp Pointer to bootm command table entry
769 * @param flag Command flags (CMD_FLAG_...)
770 * @param argc Number of subcommand arguments (0 = no arguments)
771 * @param argv Arguments
772 * @param states Mask containing states to run (BOOTM_STATE_...)
773 * @param images Image header information
774 * @param boot_progress 1 to show boot progress, 0 to not do this
185f812c 775 * Return: 0 if ok, something else on error. Some errors will cause this
b6396403
SG
776 * function to perform a reboot! If states contains BOOTM_STATE_OS_GO
777 * then the intent is to boot an OS, so this function will not return
778 * unless the image type is standalone.
779 */
09140113 780int do_bootm_states(struct cmd_tbl *cmdtp, int flag, int argc,
d9d7c20b 781 char *const argv[], int states, struct bootm_headers *images,
09140113 782 int boot_progress)
b6396403
SG
783{
784 boot_os_fn *boot_fn;
785 ulong iflag = 0;
786 int ret = 0, need_boot_fn;
787
788 images->state |= states;
789
790 /*
791 * Work through the states and see how far we get. We stop on
792 * any error.
793 */
794 if (states & BOOTM_STATE_START)
795 ret = bootm_start(cmdtp, flag, argc, argv);
796
9d46e63d
PR
797 if (!ret && (states & BOOTM_STATE_PRE_LOAD))
798 ret = bootm_pre_load(cmdtp, flag, argc, argv);
799
b6396403
SG
800 if (!ret && (states & BOOTM_STATE_FINDOS))
801 ret = bootm_find_os(cmdtp, flag, argc, argv);
802
ba079840 803 if (!ret && (states & BOOTM_STATE_FINDOTHER))
b6396403 804 ret = bootm_find_other(cmdtp, flag, argc, argv);
b6396403 805
dec166d6
EJ
806 if (IS_ENABLED(CONFIG_MEASURED_BOOT) && !ret &&
807 (states & BOOTM_STATE_MEASURE))
808 bootm_measure(images);
809
b6396403
SG
810 /* Load the OS */
811 if (!ret && (states & BOOTM_STATE_LOADOS)) {
b6396403 812 iflag = bootm_disable_interrupts();
cc955358
TR
813 ret = bootm_load_os(images, 0);
814 if (ret && ret != BOOTM_ERR_OVERLAP)
b6396403
SG
815 goto err;
816 else if (ret == BOOTM_ERR_OVERLAP)
817 ret = 0;
b6396403
SG
818 }
819
820 /* Relocate the ramdisk */
821#ifdef CONFIG_SYS_BOOT_RAMDISK_HIGH
822 if (!ret && (states & BOOTM_STATE_RAMDISK)) {
823 ulong rd_len = images->rd_end - images->rd_start;
824
825 ret = boot_ramdisk_high(&images->lmb, images->rd_start,
826 rd_len, &images->initrd_start, &images->initrd_end);
827 if (!ret) {
018f5303
SG
828 env_set_hex("initrd_start", images->initrd_start);
829 env_set_hex("initrd_end", images->initrd_end);
b6396403
SG
830 }
831 }
832#endif
0c303f9a 833#if CONFIG_IS_ENABLED(OF_LIBFDT) && defined(CONFIG_LMB)
b6396403
SG
834 if (!ret && (states & BOOTM_STATE_FDT)) {
835 boot_fdt_add_mem_rsv_regions(&images->lmb, images->ft_addr);
836 ret = boot_relocate_fdt(&images->lmb, &images->ft_addr,
837 &images->ft_len);
838 }
839#endif
840
841 /* From now on, we need the OS boot function */
842 if (ret)
843 return ret;
844 boot_fn = bootm_os_get_boot_func(images->os.os);
845 need_boot_fn = states & (BOOTM_STATE_OS_CMDLINE |
846 BOOTM_STATE_OS_BD_T | BOOTM_STATE_OS_PREP |
847 BOOTM_STATE_OS_FAKE_GO | BOOTM_STATE_OS_GO);
848 if (boot_fn == NULL && need_boot_fn) {
849 if (iflag)
850 enable_interrupts();
851 printf("ERROR: booting os '%s' (%d) is not supported\n",
852 genimg_get_os_name(images->os.os), images->os.os);
853 bootstage_error(BOOTSTAGE_ID_CHECK_BOOT_OS);
854 return 1;
855 }
856
19e8649e 857
b6396403
SG
858 /* Call various other states that are not generally used */
859 if (!ret && (states & BOOTM_STATE_OS_CMDLINE))
860 ret = boot_fn(BOOTM_STATE_OS_CMDLINE, argc, argv, images);
861 if (!ret && (states & BOOTM_STATE_OS_BD_T))
862 ret = boot_fn(BOOTM_STATE_OS_BD_T, argc, argv, images);
19e8649e 863 if (!ret && (states & BOOTM_STATE_OS_PREP)) {
51bb3384 864 ret = bootm_process_cmdline_env(images->os.os == IH_OS_LINUX);
d9477a0a
SG
865 if (ret) {
866 printf("Cmdline setup failed (err=%d)\n", ret);
867 ret = CMD_RET_FAILURE;
868 goto err;
4ae42643 869 }
b6396403 870 ret = boot_fn(BOOTM_STATE_OS_PREP, argc, argv, images);
19e8649e 871 }
b6396403
SG
872
873#ifdef CONFIG_TRACE
874 /* Pretend to run the OS, then run a user command */
875 if (!ret && (states & BOOTM_STATE_OS_FAKE_GO)) {
00caae6d 876 char *cmd_list = env_get("fakegocmd");
b6396403
SG
877
878 ret = boot_selected_os(argc, argv, BOOTM_STATE_OS_FAKE_GO,
879 images, boot_fn);
880 if (!ret && cmd_list)
881 ret = run_command_list(cmd_list, -1, flag);
882 }
883#endif
884
885 /* Check for unsupported subcommand. */
886 if (ret) {
13819f07 887 printf("subcommand failed (err=%d)\n", ret);
b6396403
SG
888 return ret;
889 }
890
891 /* Now run the OS! We hope this doesn't return */
892 if (!ret && (states & BOOTM_STATE_OS_GO))
893 ret = boot_selected_os(argc, argv, BOOTM_STATE_OS_GO,
894 images, boot_fn);
895
896 /* Deal with any fallout */
897err:
898 if (iflag)
899 enable_interrupts();
900
901 if (ret == BOOTM_ERR_UNIMPLEMENTED)
902 bootstage_error(BOOTSTAGE_ID_DECOMP_UNIMPL);
903 else if (ret == BOOTM_ERR_RESET)
904 do_reset(cmdtp, flag, argc, argv);
905
906 return ret;
907}
908
daffb0be
SG
909int bootm_boot_start(ulong addr, const char *cmdline)
910{
911 static struct cmd_tbl cmd = {"bootm"};
912 char addr_str[30];
913 char *argv[] = {addr_str, NULL};
914 int states;
915 int ret;
916
917 /*
918 * TODO([email protected]): This uses the command-line interface, but
919 * should not. To clean this up, the various bootm states need to be
920 * passed an info structure instead of cmdline flags. Then this can
921 * set up the required info and move through the states without needing
922 * the command line.
923 */
924 states = BOOTM_STATE_START | BOOTM_STATE_FINDOS | BOOTM_STATE_PRE_LOAD |
925 BOOTM_STATE_FINDOTHER | BOOTM_STATE_LOADOS |
926 BOOTM_STATE_OS_PREP | BOOTM_STATE_OS_FAKE_GO |
927 BOOTM_STATE_OS_GO;
928 if (IS_ENABLED(CONFIG_SYS_BOOT_RAMDISK_HIGH))
929 states |= BOOTM_STATE_RAMDISK;
930 if (IS_ENABLED(CONFIG_PPC) || IS_ENABLED(CONFIG_MIPS))
931 states |= BOOTM_STATE_OS_CMDLINE;
932 images.state |= states;
933
934 snprintf(addr_str, sizeof(addr_str), "%lx", addr);
935
936 ret = env_set("bootargs", cmdline);
937 if (ret) {
938 printf("Failed to set cmdline\n");
939 return ret;
940 }
941 ret = do_bootm_states(&cmd, 0, 1, argv, states, &images, 1);
942
943 return ret;
944}
945
c76c93a3 946#if CONFIG_IS_ENABLED(LEGACY_IMAGE_FORMAT)
b6396403
SG
947/**
948 * image_get_kernel - verify legacy format kernel image
949 * @img_addr: in RAM address of the legacy format image to be verified
950 * @verify: data CRC verification flag
951 *
952 * image_get_kernel() verifies legacy image integrity and returns pointer to
953 * legacy image header if image verification was completed successfully.
954 *
955 * returns:
956 * pointer to a legacy image header if valid image was found
957 * otherwise return NULL
958 */
f3543e69 959static struct legacy_img_hdr *image_get_kernel(ulong img_addr, int verify)
b6396403 960{
f3543e69 961 struct legacy_img_hdr *hdr = (struct legacy_img_hdr *)img_addr;
b6396403
SG
962
963 if (!image_check_magic(hdr)) {
964 puts("Bad Magic Number\n");
965 bootstage_error(BOOTSTAGE_ID_CHECK_MAGIC);
966 return NULL;
967 }
968 bootstage_mark(BOOTSTAGE_ID_CHECK_HEADER);
969
970 if (!image_check_hcrc(hdr)) {
971 puts("Bad Header Checksum\n");
972 bootstage_error(BOOTSTAGE_ID_CHECK_HEADER);
973 return NULL;
974 }
975
976 bootstage_mark(BOOTSTAGE_ID_CHECK_CHECKSUM);
977 image_print_contents(hdr);
978
979 if (verify) {
980 puts(" Verifying Checksum ... ");
981 if (!image_check_dcrc(hdr)) {
982 printf("Bad Data CRC\n");
983 bootstage_error(BOOTSTAGE_ID_CHECK_CHECKSUM);
984 return NULL;
985 }
986 puts("OK\n");
987 }
988 bootstage_mark(BOOTSTAGE_ID_CHECK_ARCH);
989
990 if (!image_check_target_arch(hdr)) {
991 printf("Unsupported Architecture 0x%x\n", image_get_arch(hdr));
992 bootstage_error(BOOTSTAGE_ID_CHECK_ARCH);
993 return NULL;
994 }
995 return hdr;
996}
997#endif
998
999/**
1000 * boot_get_kernel - find kernel image
1001 * @os_data: pointer to a ulong variable, will hold os data start address
1002 * @os_len: pointer to a ulong variable, will hold os data length
1003 *
1004 * boot_get_kernel() tries to find a kernel image, verifies its integrity
1005 * and locates kernel data.
1006 *
1007 * returns:
1008 * pointer to image header if valid image was found, plus kernel start
1009 * address and length, otherwise NULL
1010 */
09140113 1011static const void *boot_get_kernel(struct cmd_tbl *cmdtp, int flag, int argc,
d9d7c20b 1012 char *const argv[], struct bootm_headers *images,
b6396403
SG
1013 ulong *os_data, ulong *os_len)
1014{
c76c93a3 1015#if CONFIG_IS_ENABLED(LEGACY_IMAGE_FORMAT)
f3543e69 1016 struct legacy_img_hdr *hdr;
b6396403
SG
1017#endif
1018 ulong img_addr;
1019 const void *buf;
b6396403
SG
1020 const char *fit_uname_config = NULL;
1021 const char *fit_uname_kernel = NULL;
bf371b4c 1022#if CONFIG_IS_ENABLED(FIT)
b6396403
SG
1023 int os_noffset;
1024#endif
1025
636da203
SO
1026#ifdef CONFIG_ANDROID_BOOT_IMAGE
1027 const void *boot_img;
1028 const void *vendor_boot_img;
1029#endif
e6c88a6b
BW
1030 img_addr = genimg_get_kernel_addr_fit(argc < 1 ? NULL : argv[0],
1031 &fit_uname_config,
1032 &fit_uname_kernel);
b6396403 1033
494bcf1a 1034 if (IS_ENABLED(CONFIG_CMD_BOOTM_PRE_LOAD))
9d46e63d
PR
1035 img_addr += image_load_offset;
1036
b6396403
SG
1037 bootstage_mark(BOOTSTAGE_ID_CHECK_MAGIC);
1038
b6396403
SG
1039 /* check image type, for FIT images get FIT kernel node */
1040 *os_data = *os_len = 0;
1041 buf = map_sysmem(img_addr, 0);
1042 switch (genimg_get_format(buf)) {
c76c93a3 1043#if CONFIG_IS_ENABLED(LEGACY_IMAGE_FORMAT)
b6396403
SG
1044 case IMAGE_FORMAT_LEGACY:
1045 printf("## Booting kernel from Legacy Image at %08lx ...\n",
1046 img_addr);
1047 hdr = image_get_kernel(img_addr, images->verify);
1048 if (!hdr)
1049 return NULL;
1050 bootstage_mark(BOOTSTAGE_ID_CHECK_IMAGETYPE);
1051
1052 /* get os_data and os_len */
1053 switch (image_get_type(hdr)) {
1054 case IH_TYPE_KERNEL:
1055 case IH_TYPE_KERNEL_NOLOAD:
1056 *os_data = image_get_data(hdr);
1057 *os_len = image_get_data_size(hdr);
1058 break;
1059 case IH_TYPE_MULTI:
1060 image_multi_getimg(hdr, 0, os_data, os_len);
1061 break;
1062 case IH_TYPE_STANDALONE:
1063 *os_data = image_get_data(hdr);
1064 *os_len = image_get_data_size(hdr);
1065 break;
1066 default:
1067 printf("Wrong Image Type for %s command\n",
1068 cmdtp->name);
1069 bootstage_error(BOOTSTAGE_ID_CHECK_IMAGETYPE);
1070 return NULL;
1071 }
1072
1073 /*
1074 * copy image header to allow for image overwrites during
1075 * kernel decompression.
1076 */
1077 memmove(&images->legacy_hdr_os_copy, hdr,
f3543e69 1078 sizeof(struct legacy_img_hdr));
b6396403
SG
1079
1080 /* save pointer to image header */
1081 images->legacy_hdr_os = hdr;
1082
1083 images->legacy_hdr_valid = 1;
1084 bootstage_mark(BOOTSTAGE_ID_DECOMP_IMAGE);
1085 break;
1086#endif
bf371b4c 1087#if CONFIG_IS_ENABLED(FIT)
b6396403 1088 case IMAGE_FORMAT_FIT:
126cc864 1089 os_noffset = fit_image_load(images, img_addr,
b6396403
SG
1090 &fit_uname_kernel, &fit_uname_config,
1091 IH_ARCH_DEFAULT, IH_TYPE_KERNEL,
1092 BOOTSTAGE_ID_FIT_KERNEL_START,
1093 FIT_LOAD_IGNORED, os_data, os_len);
1094 if (os_noffset < 0)
1095 return NULL;
1096
1097 images->fit_hdr_os = map_sysmem(img_addr, 0);
1098 images->fit_uname_os = fit_uname_kernel;
1099 images->fit_uname_cfg = fit_uname_config;
1100 images->fit_noffset_os = os_noffset;
1101 break;
1102#endif
1103#ifdef CONFIG_ANDROID_BOOT_IMAGE
1104 case IMAGE_FORMAT_ANDROID:
636da203
SO
1105 boot_img = buf;
1106 vendor_boot_img = NULL;
1107 if (IS_ENABLED(CONFIG_CMD_ABOOTIMG)) {
1108 boot_img = map_sysmem(get_abootimg_addr(), 0);
1109 vendor_boot_img = map_sysmem(get_avendor_bootimg_addr(), 0);
1110 }
b6396403 1111 printf("## Booting Android Image at 0x%08lx ...\n", img_addr);
636da203 1112 if (android_image_get_kernel(boot_img, vendor_boot_img, images->verify,
b6396403
SG
1113 os_data, os_len))
1114 return NULL;
636da203
SO
1115 if (IS_ENABLED(CONFIG_CMD_ABOOTIMG)) {
1116 unmap_sysmem(vendor_boot_img);
1117 unmap_sysmem(boot_img);
1118 }
b6396403
SG
1119 break;
1120#endif
1121 default:
1122 printf("Wrong Image Format for %s command\n", cmdtp->name);
1123 bootstage_error(BOOTSTAGE_ID_FIT_KERNEL_INFO);
1124 return NULL;
1125 }
1126
1127 debug(" kernel data at 0x%08lx, len = 0x%08lx (%ld)\n",
1128 *os_data, *os_len, *os_len);
1129
1130 return buf;
1131}
f6c6df7e
HS
1132
1133/**
1134 * switch_to_non_secure_mode() - switch to non-secure mode
1135 *
1136 * This routine is overridden by architectures requiring this feature.
1137 */
1138void __weak switch_to_non_secure_mode(void)
1139{
1140}
1141
ce1400f6
SG
1142#else /* USE_HOSTCC */
1143
93e07880 1144#if defined(CONFIG_FIT_SIGNATURE)
8a9d0373
SG
1145static int bootm_host_load_image(const void *fit, int req_image_type,
1146 int cfg_noffset)
ce1400f6
SG
1147{
1148 const char *fit_uname_config = NULL;
1149 ulong data, len;
d9d7c20b 1150 struct bootm_headers images;
ce1400f6 1151 int noffset;
c45568cc 1152 ulong load_end, buf_size;
ce1400f6 1153 uint8_t image_type;
0cd57f29 1154 uint8_t image_comp;
ce1400f6
SG
1155 void *load_buf;
1156 int ret;
1157
8a9d0373 1158 fit_uname_config = fdt_get_name(fit, cfg_noffset, NULL);
ce1400f6
SG
1159 memset(&images, '\0', sizeof(images));
1160 images.verify = 1;
1161 noffset = fit_image_load(&images, (ulong)fit,
1162 NULL, &fit_uname_config,
1163 IH_ARCH_DEFAULT, req_image_type, -1,
1164 FIT_LOAD_IGNORED, &data, &len);
1165 if (noffset < 0)
1166 return noffset;
1167 if (fit_image_get_type(fit, noffset, &image_type)) {
1168 puts("Can't get image type!\n");
1169 return -EINVAL;
1170 }
1171
88de6c51
DG
1172 if (fit_image_get_comp(fit, noffset, &image_comp))
1173 image_comp = IH_COMP_NONE;
ce1400f6
SG
1174
1175 /* Allow the image to expand by a factor of 4, should be safe */
c45568cc
TR
1176 buf_size = (1 << 20) + len * 4;
1177 load_buf = malloc(buf_size);
0cd57f29 1178 ret = image_decomp(image_comp, 0, data, image_type, load_buf,
c45568cc 1179 (void *)data, len, buf_size, &load_end);
ce1400f6 1180 free(load_buf);
081cc197 1181
2090854c 1182 if (ret) {
0cd57f29 1183 ret = handle_decomp_error(image_comp, load_end - 0, buf_size, ret);
2090854c
JW
1184 if (ret != BOOTM_ERR_UNIMPLEMENTED)
1185 return ret;
1186 }
ce1400f6
SG
1187
1188 return 0;
1189}
1190
1191int bootm_host_load_images(const void *fit, int cfg_noffset)
1192{
1193 static uint8_t image_types[] = {
1194 IH_TYPE_KERNEL,
1195 IH_TYPE_FLATDT,
1196 IH_TYPE_RAMDISK,
1197 };
1198 int err = 0;
1199 int i;
1200
1201 for (i = 0; i < ARRAY_SIZE(image_types); i++) {
1202 int ret;
1203
8a9d0373 1204 ret = bootm_host_load_image(fit, image_types[i], cfg_noffset);
ce1400f6
SG
1205 if (!err && ret && ret != -ENOENT)
1206 err = ret;
1207 }
1208
1209 /* Return the first error we found */
1210 return err;
1211}
93e07880 1212#endif
ea51a628
SG
1213
1214#endif /* ndef USE_HOSTCC */
This page took 0.426521 seconds and 4 git commands to generate.