1 // SPDX-License-Identifier: GPL-2.0+
3 * Copyright (c) 2013, Google Inc.
5 * (C) Copyright 2008 Semihalf
7 * (C) Copyright 2000-2006
8 * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
11 #define LOG_CATEGORY LOGC_BOOT
16 #include <linux/libfdt.h>
17 #include <u-boot/crc.h>
18 #include <linux/kconfig.h>
20 #include <linux/compiler.h>
21 #include <linux/sizes.h>
28 #include <asm/global_data.h>
31 #include <u-boot/hash.h>
33 DECLARE_GLOBAL_DATA_PTR
;
34 #endif /* !USE_HOSTCC*/
38 #include <bootstage.h>
40 #include <u-boot/crc.h>
42 /*****************************************************************************/
43 /* New uImage format routines */
44 /*****************************************************************************/
46 static int fit_parse_spec(const char *spec
, char sepc
, ulong addr_curr
,
47 ulong
*addr
, const char **name
)
54 sep
= strchr(spec
, sepc
);
57 *addr
= hextoul(spec
, NULL
);
67 * fit_parse_conf - parse FIT configuration spec
68 * @spec: input string, containing configuration spec
69 * @add_curr: current image address (to be used as a possible default)
70 * @addr: pointer to a ulong variable, will hold FIT image address of a given
72 * @conf_name double pointer to a char, will hold pointer to a configuration
75 * fit_parse_conf() expects configuration spec in the form of [<addr>]#<conf>,
76 * where <addr> is a FIT image address that contains configuration
77 * with a <conf> unit name.
79 * Address part is optional, and if omitted default add_curr will
83 * 1 if spec is a valid configuration string,
84 * addr and conf_name are set accordingly
87 int fit_parse_conf(const char *spec
, ulong addr_curr
,
88 ulong
*addr
, const char **conf_name
)
90 return fit_parse_spec(spec
, '#', addr_curr
, addr
, conf_name
);
94 * fit_parse_subimage - parse FIT subimage spec
95 * @spec: input string, containing subimage spec
96 * @add_curr: current image address (to be used as a possible default)
97 * @addr: pointer to a ulong variable, will hold FIT image address of a given
99 * @image_name: double pointer to a char, will hold pointer to a subimage name
101 * fit_parse_subimage() expects subimage spec in the form of
102 * [<addr>]:<subimage>, where <addr> is a FIT image address that contains
103 * subimage with a <subimg> unit name.
105 * Address part is optional, and if omitted default add_curr will
109 * 1 if spec is a valid subimage string,
110 * addr and image_name are set accordingly
113 int fit_parse_subimage(const char *spec
, ulong addr_curr
,
114 ulong
*addr
, const char **image_name
)
116 return fit_parse_spec(spec
, ':', addr_curr
, addr
, image_name
);
118 #endif /* !USE_HOSTCC */
121 /* Host tools use these implementations for Cipher and Signature support */
122 static void *host_blob
;
124 void image_set_host_blob(void *blob
)
129 void *image_get_host_blob(void)
133 #endif /* USE_HOSTCC */
135 static void fit_get_debug(const void *fit
, int noffset
,
136 char *prop_name
, int err
)
138 debug("Can't get '%s' property from FIT 0x%08lx, node: offset %d, name %s (%s)\n",
139 prop_name
, (ulong
)fit
, noffset
, fit_get_name(fit
, noffset
, NULL
),
144 * fit_get_subimage_count - get component (sub-image) count
145 * @fit: pointer to the FIT format image header
146 * @images_noffset: offset of images node
149 * number of image components
151 int fit_get_subimage_count(const void *fit
, int images_noffset
)
157 /* Process its subnodes, print out component images details */
158 for (ndepth
= 0, count
= 0,
159 noffset
= fdt_next_node(fit
, images_noffset
, &ndepth
);
160 (noffset
>= 0) && (ndepth
> 0);
161 noffset
= fdt_next_node(fit
, noffset
, &ndepth
)) {
171 * fit_image_print_data() - prints out the hash node details
172 * @fit: pointer to the FIT format image header
173 * @noffset: offset of the hash node
174 * @p: pointer to prefix string
175 * @type: Type of information to print ("hash" or "sign")
177 * fit_image_print_data() lists properties for the processed hash node
179 * This function avoid using puts() since it prints a newline on the host
180 * but does not in U-Boot.
183 * no returned results
185 static void fit_image_print_data(const void *fit
, int noffset
, const char *p
,
196 debug("%s %s node: '%s'\n", p
, type
,
197 fit_get_name(fit
, noffset
, NULL
));
198 printf("%s %s algo: ", p
, type
);
199 if (fit_image_hash_get_algo(fit
, noffset
, &algo
)) {
200 printf("invalid/unsupported\n");
204 keyname
= fdt_getprop(fit
, noffset
, FIT_KEY_HINT
, NULL
);
205 required
= fdt_getprop(fit
, noffset
, FIT_KEY_REQUIRED
, NULL
) != NULL
;
207 printf(":%s", keyname
);
209 printf(" (required)");
212 padding
= fdt_getprop(fit
, noffset
, "padding", NULL
);
214 printf("%s %s padding: %s\n", p
, type
, padding
);
216 ret
= fit_image_hash_get_value(fit
, noffset
, &value
,
218 printf("%s %s value: ", p
, type
);
220 printf("unavailable\n");
222 for (i
= 0; i
< value_len
; i
++)
223 printf("%02x", value
[i
]);
227 debug("%s %s len: %d\n", p
, type
, value_len
);
229 /* Signatures have a time stamp */
230 if (IMAGE_ENABLE_TIMESTAMP
&& keyname
) {
233 printf("%s Timestamp: ", p
);
234 if (fit_get_timestamp(fit
, noffset
, ×tamp
))
235 printf("unavailable\n");
237 genimg_print_time(timestamp
);
242 * fit_image_print_verification_data() - prints out the hash/signature details
243 * @fit: pointer to the FIT format image header
244 * @noffset: offset of the hash or signature node
245 * @p: pointer to prefix string
247 * This lists properties for the processed hash node
250 * no returned results
252 static void fit_image_print_verification_data(const void *fit
, int noffset
,
258 * Check subnode name, must be equal to "hash" or "signature".
259 * Multiple hash/signature nodes require unique unit node
260 * names, e.g. hash-1, hash-2, signature-1, signature-2, etc.
262 name
= fit_get_name(fit
, noffset
, NULL
);
263 if (!strncmp(name
, FIT_HASH_NODENAME
, strlen(FIT_HASH_NODENAME
))) {
264 fit_image_print_data(fit
, noffset
, p
, "Hash");
265 } else if (!strncmp(name
, FIT_SIG_NODENAME
,
266 strlen(FIT_SIG_NODENAME
))) {
267 fit_image_print_data(fit
, noffset
, p
, "Sign");
272 * fit_conf_print - prints out the FIT configuration details
273 * @fit: pointer to the FIT format image header
274 * @noffset: offset of the configuration node
275 * @p: pointer to prefix string
277 * fit_conf_print() lists all mandatory properties for the processed
278 * configuration node.
281 * no returned results
283 static void fit_conf_print(const void *fit
, int noffset
, const char *p
)
288 int fdt_index
, loadables_index
;
291 /* Mandatory properties */
292 ret
= fit_get_desc(fit
, noffset
, &desc
);
293 printf("%s Description: ", p
);
295 printf("unavailable\n");
297 printf("%s\n", desc
);
299 uname
= fdt_getprop(fit
, noffset
, FIT_KERNEL_PROP
, NULL
);
300 printf("%s Kernel: ", p
);
302 printf("unavailable\n");
304 printf("%s\n", uname
);
306 /* Optional properties */
307 uname
= fdt_getprop(fit
, noffset
, FIT_RAMDISK_PROP
, NULL
);
309 printf("%s Init Ramdisk: %s\n", p
, uname
);
311 uname
= fdt_getprop(fit
, noffset
, FIT_FIRMWARE_PROP
, NULL
);
313 printf("%s Firmware: %s\n", p
, uname
);
316 uname
= fdt_stringlist_get(fit
, noffset
, FIT_FDT_PROP
,
317 fdt_index
, NULL
), uname
;
320 printf("%s FDT: ", p
);
323 printf("%s\n", uname
);
326 uname
= fdt_getprop(fit
, noffset
, FIT_FPGA_PROP
, NULL
);
328 printf("%s FPGA: %s\n", p
, uname
);
330 /* Print out all of the specified loadables */
331 for (loadables_index
= 0;
332 uname
= fdt_stringlist_get(fit
, noffset
, FIT_LOADABLE_PROP
,
333 loadables_index
, NULL
), uname
;
335 if (loadables_index
== 0) {
336 printf("%s Loadables: ", p
);
340 printf("%s\n", uname
);
343 /* Process all hash subnodes of the component configuration node */
344 for (ndepth
= 0, noffset
= fdt_next_node(fit
, noffset
, &ndepth
);
345 (noffset
>= 0) && (ndepth
> 0);
346 noffset
= fdt_next_node(fit
, noffset
, &ndepth
)) {
348 /* Direct child node of the component configuration node */
349 fit_image_print_verification_data(fit
, noffset
, p
);
355 * fit_print_contents - prints out the contents of the FIT format image
356 * @fit: pointer to the FIT format image header
357 * @p: pointer to prefix string
359 * fit_print_contents() formats a multi line FIT image contents description.
360 * The routine prints out FIT image properties (root node level) followed by
361 * the details of each component image.
364 * no returned results
366 void fit_print_contents(const void *fit
)
379 if (!CONFIG_IS_ENABLED(FIT_PRINT
))
382 /* Indent string is defined in header image.h */
383 p
= IMAGE_INDENT_STRING
;
385 /* Root node properties */
386 ret
= fit_get_desc(fit
, 0, &desc
);
387 printf("%sFIT description: ", p
);
389 printf("unavailable\n");
391 printf("%s\n", desc
);
393 if (IMAGE_ENABLE_TIMESTAMP
) {
394 ret
= fit_get_timestamp(fit
, 0, ×tamp
);
395 printf("%sCreated: ", p
);
397 printf("unavailable\n");
399 genimg_print_time(timestamp
);
402 /* Find images parent node offset */
403 images_noffset
= fdt_path_offset(fit
, FIT_IMAGES_PATH
);
404 if (images_noffset
< 0) {
405 printf("Can't find images parent node '%s' (%s)\n",
406 FIT_IMAGES_PATH
, fdt_strerror(images_noffset
));
410 /* Process its subnodes, print out component images details */
411 for (ndepth
= 0, count
= 0,
412 noffset
= fdt_next_node(fit
, images_noffset
, &ndepth
);
413 (noffset
>= 0) && (ndepth
> 0);
414 noffset
= fdt_next_node(fit
, noffset
, &ndepth
)) {
417 * Direct child node of the images parent node,
418 * i.e. component image node.
420 printf("%s Image %u (%s)\n", p
, count
++,
421 fit_get_name(fit
, noffset
, NULL
));
423 fit_image_print(fit
, noffset
, p
);
427 /* Find configurations parent node offset */
428 confs_noffset
= fdt_path_offset(fit
, FIT_CONFS_PATH
);
429 if (confs_noffset
< 0) {
430 debug("Can't get configurations parent node '%s' (%s)\n",
431 FIT_CONFS_PATH
, fdt_strerror(confs_noffset
));
435 /* get default configuration unit name from default property */
436 uname
= (char *)fdt_getprop(fit
, noffset
, FIT_DEFAULT_PROP
, NULL
);
438 printf("%s Default Configuration: '%s'\n", p
, uname
);
440 /* Process its subnodes, print out configurations details */
441 for (ndepth
= 0, count
= 0,
442 noffset
= fdt_next_node(fit
, confs_noffset
, &ndepth
);
443 (noffset
>= 0) && (ndepth
> 0);
444 noffset
= fdt_next_node(fit
, noffset
, &ndepth
)) {
447 * Direct child node of the configurations parent node,
448 * i.e. configuration node.
450 printf("%s Configuration %u (%s)\n", p
, count
++,
451 fit_get_name(fit
, noffset
, NULL
));
453 fit_conf_print(fit
, noffset
, p
);
459 * fit_image_print - prints out the FIT component image details
460 * @fit: pointer to the FIT format image header
461 * @image_noffset: offset of the component image node
462 * @p: pointer to prefix string
464 * fit_image_print() lists all mandatory properties for the processed component
465 * image. If present, hash nodes are printed out as well. Load
466 * address for images of type firmware is also printed out. Since the load
467 * address is not mandatory for firmware images, it will be output as
468 * "unavailable" when not present.
471 * no returned results
473 void fit_image_print(const void *fit
, int image_noffset
, const char *p
)
476 uint8_t type
, arch
, os
, comp
= IH_COMP_NONE
;
484 if (!CONFIG_IS_ENABLED(FIT_PRINT
))
487 /* Mandatory properties */
488 ret
= fit_get_desc(fit
, image_noffset
, &desc
);
489 printf("%s Description: ", p
);
491 printf("unavailable\n");
493 printf("%s\n", desc
);
495 if (IMAGE_ENABLE_TIMESTAMP
) {
498 ret
= fit_get_timestamp(fit
, 0, ×tamp
);
499 printf("%s Created: ", p
);
501 printf("unavailable\n");
503 genimg_print_time(timestamp
);
506 fit_image_get_type(fit
, image_noffset
, &type
);
507 printf("%s Type: %s\n", p
, genimg_get_type_name(type
));
509 fit_image_get_comp(fit
, image_noffset
, &comp
);
510 printf("%s Compression: %s\n", p
, genimg_get_comp_name(comp
));
512 ret
= fit_image_get_data(fit
, image_noffset
, &data
, &size
);
514 if (!tools_build()) {
515 printf("%s Data Start: ", p
);
517 printf("unavailable\n");
519 void *vdata
= (void *)data
;
521 printf("0x%08lx\n", (ulong
)map_to_sysmem(vdata
));
525 printf("%s Data Size: ", p
);
527 printf("unavailable\n");
529 genimg_print_size(size
);
531 /* Remaining, type dependent properties */
532 if ((type
== IH_TYPE_KERNEL
) || (type
== IH_TYPE_STANDALONE
) ||
533 (type
== IH_TYPE_RAMDISK
) || (type
== IH_TYPE_FIRMWARE
) ||
534 (type
== IH_TYPE_FLATDT
)) {
535 fit_image_get_arch(fit
, image_noffset
, &arch
);
536 printf("%s Architecture: %s\n", p
, genimg_get_arch_name(arch
));
539 if ((type
== IH_TYPE_KERNEL
) || (type
== IH_TYPE_RAMDISK
) ||
540 (type
== IH_TYPE_FIRMWARE
)) {
541 fit_image_get_os(fit
, image_noffset
, &os
);
542 printf("%s OS: %s\n", p
, genimg_get_os_name(os
));
545 if ((type
== IH_TYPE_KERNEL
) || (type
== IH_TYPE_STANDALONE
) ||
546 (type
== IH_TYPE_FIRMWARE
) || (type
== IH_TYPE_RAMDISK
) ||
547 (type
== IH_TYPE_FPGA
)) {
548 ret
= fit_image_get_load(fit
, image_noffset
, &load
);
549 printf("%s Load Address: ", p
);
551 printf("unavailable\n");
553 printf("0x%08lx\n", load
);
556 /* optional load address for FDT */
557 if (type
== IH_TYPE_FLATDT
&& !fit_image_get_load(fit
, image_noffset
, &load
))
558 printf("%s Load Address: 0x%08lx\n", p
, load
);
560 if ((type
== IH_TYPE_KERNEL
) || (type
== IH_TYPE_STANDALONE
) ||
561 (type
== IH_TYPE_RAMDISK
)) {
562 ret
= fit_image_get_entry(fit
, image_noffset
, &entry
);
563 printf("%s Entry Point: ", p
);
565 printf("unavailable\n");
567 printf("0x%08lx\n", entry
);
570 /* Process all hash subnodes of the component image node */
571 for (ndepth
= 0, noffset
= fdt_next_node(fit
, image_noffset
, &ndepth
);
572 (noffset
>= 0) && (ndepth
> 0);
573 noffset
= fdt_next_node(fit
, noffset
, &ndepth
)) {
575 /* Direct child node of the component image node */
576 fit_image_print_verification_data(fit
, noffset
, p
);
582 * fit_get_desc - get node description property
583 * @fit: pointer to the FIT format image header
584 * @noffset: node offset
585 * @desc: double pointer to the char, will hold pointer to the description
587 * fit_get_desc() reads description property from a given node, if
588 * description is found pointer to it is returned in third call argument.
594 int fit_get_desc(const void *fit
, int noffset
, char **desc
)
598 *desc
= (char *)fdt_getprop(fit
, noffset
, FIT_DESC_PROP
, &len
);
600 fit_get_debug(fit
, noffset
, FIT_DESC_PROP
, len
);
608 * fit_get_timestamp - get node timestamp property
609 * @fit: pointer to the FIT format image header
610 * @noffset: node offset
611 * @timestamp: pointer to the time_t, will hold read timestamp
613 * fit_get_timestamp() reads timestamp property from given node, if timestamp
614 * is found and has a correct size its value is returned in third call
619 * -1, on property read failure
620 * -2, on wrong timestamp size
622 int fit_get_timestamp(const void *fit
, int noffset
, time_t *timestamp
)
627 data
= fdt_getprop(fit
, noffset
, FIT_TIMESTAMP_PROP
, &len
);
629 fit_get_debug(fit
, noffset
, FIT_TIMESTAMP_PROP
, len
);
632 if (len
!= sizeof(uint32_t)) {
633 debug("FIT timestamp with incorrect size of (%u)\n", len
);
637 *timestamp
= uimage_to_cpu(*((uint32_t *)data
));
642 * fit_image_get_node - get node offset for component image of a given unit name
643 * @fit: pointer to the FIT format image header
644 * @image_uname: component image node unit name
646 * fit_image_get_node() finds a component image (within the '/images'
647 * node) of a provided unit name. If image is found its node offset is
648 * returned to the caller.
651 * image node offset when found (>=0)
652 * negative number on failure (FDT_ERR_* code)
654 int fit_image_get_node(const void *fit
, const char *image_uname
)
656 int noffset
, images_noffset
;
658 images_noffset
= fdt_path_offset(fit
, FIT_IMAGES_PATH
);
659 if (images_noffset
< 0) {
660 debug("Can't find images parent node '%s' (%s)\n",
661 FIT_IMAGES_PATH
, fdt_strerror(images_noffset
));
662 return images_noffset
;
665 noffset
= fdt_subnode_offset(fit
, images_noffset
, image_uname
);
667 debug("Can't get node offset for image unit name: '%s' (%s)\n",
668 image_uname
, fdt_strerror(noffset
));
675 * fit_image_get_os - get os id for a given component image node
676 * @fit: pointer to the FIT format image header
677 * @noffset: component image node offset
678 * @os: pointer to the uint8_t, will hold os numeric id
680 * fit_image_get_os() finds os property in a given component image node.
681 * If the property is found, its (string) value is translated to the numeric
682 * id which is returned to the caller.
688 int fit_image_get_os(const void *fit
, int noffset
, uint8_t *os
)
693 /* Get OS name from property data */
694 data
= fdt_getprop(fit
, noffset
, FIT_OS_PROP
, &len
);
696 fit_get_debug(fit
, noffset
, FIT_OS_PROP
, len
);
701 /* Translate OS name to id */
702 *os
= genimg_get_os_id(data
);
707 * fit_image_get_arch - get arch id for a given component image node
708 * @fit: pointer to the FIT format image header
709 * @noffset: component image node offset
710 * @arch: pointer to the uint8_t, will hold arch numeric id
712 * fit_image_get_arch() finds arch property in a given component image node.
713 * If the property is found, its (string) value is translated to the numeric
714 * id which is returned to the caller.
720 int fit_image_get_arch(const void *fit
, int noffset
, uint8_t *arch
)
725 /* Get architecture name from property data */
726 data
= fdt_getprop(fit
, noffset
, FIT_ARCH_PROP
, &len
);
728 fit_get_debug(fit
, noffset
, FIT_ARCH_PROP
, len
);
733 /* Translate architecture name to id */
734 *arch
= genimg_get_arch_id(data
);
739 * fit_image_get_type - get type id for a given component image node
740 * @fit: pointer to the FIT format image header
741 * @noffset: component image node offset
742 * @type: pointer to the uint8_t, will hold type numeric id
744 * fit_image_get_type() finds type property in a given component image node.
745 * If the property is found, its (string) value is translated to the numeric
746 * id which is returned to the caller.
752 int fit_image_get_type(const void *fit
, int noffset
, uint8_t *type
)
757 /* Get image type name from property data */
758 data
= fdt_getprop(fit
, noffset
, FIT_TYPE_PROP
, &len
);
760 fit_get_debug(fit
, noffset
, FIT_TYPE_PROP
, len
);
765 /* Translate image type name to id */
766 *type
= genimg_get_type_id(data
);
771 * fit_image_get_comp - get comp id for a given component image node
772 * @fit: pointer to the FIT format image header
773 * @noffset: component image node offset
774 * @comp: pointer to the uint8_t, will hold comp numeric id
776 * fit_image_get_comp() finds comp property in a given component image node.
777 * If the property is found, its (string) value is translated to the numeric
778 * id which is returned to the caller.
784 int fit_image_get_comp(const void *fit
, int noffset
, uint8_t *comp
)
789 /* Get compression name from property data */
790 data
= fdt_getprop(fit
, noffset
, FIT_COMP_PROP
, &len
);
792 fit_get_debug(fit
, noffset
, FIT_COMP_PROP
, len
);
796 /* Translate compression name to id */
797 *comp
= genimg_get_comp_id(data
);
802 * fit_image_get_phase() - get the phase for a configuration node
803 * @fit: pointer to the FIT format image header
804 * @offset: configuration-node offset
805 * @phasep: returns the phase
807 * Finds the phase property in a given configuration node. If the property is
808 * found, its (string) value is translated to the numeric id which is returned
811 * Returns: 0 on success, -ENOENT if missing, -EINVAL for invalid value
813 int fit_image_get_phase(const void *fit
, int offset
, enum image_phase_t
*phasep
)
818 /* Get phase name from property data */
819 data
= fdt_getprop(fit
, offset
, FIT_PHASE_PROP
, &len
);
821 fit_get_debug(fit
, offset
, FIT_PHASE_PROP
, len
);
826 /* Translate phase name to id */
827 ret
= genimg_get_phase_id(data
);
835 static int fit_image_get_address(const void *fit
, int noffset
, char *name
,
842 cell
= fdt_getprop(fit
, noffset
, name
, &len
);
844 fit_get_debug(fit
, noffset
, name
, len
);
849 /* Use load64 to avoid compiling warning for 32-bit target */
851 load64
= (load64
<< 32) | uimage_to_cpu(*cell
);
855 if (len
> sizeof(ulong
) && (uint32_t)(load64
>> 32)) {
856 printf("Unsupported %s address size\n", name
);
860 *load
= (ulong
)load64
;
865 * fit_image_get_load() - get load addr property for given component image node
866 * @fit: pointer to the FIT format image header
867 * @noffset: component image node offset
868 * @load: pointer to the uint32_t, will hold load address
870 * fit_image_get_load() finds load address property in a given component
871 * image node. If the property is found, its value is returned to the caller.
877 int fit_image_get_load(const void *fit
, int noffset
, ulong
*load
)
879 return fit_image_get_address(fit
, noffset
, FIT_LOAD_PROP
, load
);
883 * fit_image_get_entry() - get entry point address property
884 * @fit: pointer to the FIT format image header
885 * @noffset: component image node offset
886 * @entry: pointer to the uint32_t, will hold entry point address
888 * This gets the entry point address property for a given component image
891 * fit_image_get_entry() finds entry point address property in a given
892 * component image node. If the property is found, its value is returned
899 int fit_image_get_entry(const void *fit
, int noffset
, ulong
*entry
)
901 return fit_image_get_address(fit
, noffset
, FIT_ENTRY_PROP
, entry
);
905 * fit_image_get_emb_data - get data property and its size for a given component image node
906 * @fit: pointer to the FIT format image header
907 * @noffset: component image node offset
908 * @data: double pointer to void, will hold data property's data address
909 * @size: pointer to size_t, will hold data property's data size
911 * fit_image_get_emb_data() finds data property in a given component image node.
912 * If the property is found its data start address and size are returned to
919 int fit_image_get_emb_data(const void *fit
, int noffset
, const void **data
,
924 *data
= fdt_getprop(fit
, noffset
, FIT_DATA_PROP
, &len
);
926 fit_get_debug(fit
, noffset
, FIT_DATA_PROP
, len
);
936 * Get 'data-offset' property from a given image node.
938 * @fit: pointer to the FIT image header
939 * @noffset: component image node offset
940 * @data_offset: holds the data-offset property
944 * -ENOENT if the property could not be found
946 int fit_image_get_data_offset(const void *fit
, int noffset
, int *data_offset
)
950 val
= fdt_getprop(fit
, noffset
, FIT_DATA_OFFSET_PROP
, NULL
);
954 *data_offset
= fdt32_to_cpu(*val
);
960 * Get 'data-position' property from a given image node.
962 * @fit: pointer to the FIT image header
963 * @noffset: component image node offset
964 * @data_position: holds the data-position property
968 * -ENOENT if the property could not be found
970 int fit_image_get_data_position(const void *fit
, int noffset
,
975 val
= fdt_getprop(fit
, noffset
, FIT_DATA_POSITION_PROP
, NULL
);
979 *data_position
= fdt32_to_cpu(*val
);
985 * Get 'data-size' property from a given image node.
987 * @fit: pointer to the FIT image header
988 * @noffset: component image node offset
989 * @data_size: holds the data-size property
993 * -ENOENT if the property could not be found
995 int fit_image_get_data_size(const void *fit
, int noffset
, int *data_size
)
999 val
= fdt_getprop(fit
, noffset
, FIT_DATA_SIZE_PROP
, NULL
);
1003 *data_size
= fdt32_to_cpu(*val
);
1009 * Get 'data-size-unciphered' property from a given image node.
1011 * @fit: pointer to the FIT image header
1012 * @noffset: component image node offset
1013 * @data_size: holds the data-size property
1017 * -ENOENT if the property could not be found
1019 int fit_image_get_data_size_unciphered(const void *fit
, int noffset
,
1024 val
= fdt_getprop(fit
, noffset
, "data-size-unciphered", NULL
);
1028 *data_size
= (size_t)fdt32_to_cpu(*val
);
1034 * fit_image_get_data - get data and its size including
1035 * both embedded and external data
1036 * @fit: pointer to the FIT format image header
1037 * @noffset: component image node offset
1038 * @data: double pointer to void, will hold data property's data address
1039 * @size: pointer to size_t, will hold data property's data size
1041 * fit_image_get_data() finds data and its size including
1042 * both embedded and external data. If the property is found
1043 * its data start address and size are returned to the caller.
1047 * otherwise, on failure
1049 int fit_image_get_data(const void *fit
, int noffset
, const void **data
,
1052 bool external_data
= false;
1057 if (!fit_image_get_data_position(fit
, noffset
, &offset
)) {
1058 external_data
= true;
1059 } else if (!fit_image_get_data_offset(fit
, noffset
, &offset
)) {
1060 external_data
= true;
1062 * For FIT with external data, figure out where
1063 * the external images start. This is the base
1064 * for the data-offset properties in each image.
1066 offset
+= ((fdt_totalsize(fit
) + 3) & ~3);
1069 if (external_data
) {
1070 debug("External Data\n");
1071 ret
= fit_image_get_data_size(fit
, noffset
, &len
);
1073 *data
= fit
+ offset
;
1077 ret
= fit_image_get_emb_data(fit
, noffset
, data
, size
);
1084 * fit_image_hash_get_algo - get hash algorithm name
1085 * @fit: pointer to the FIT format image header
1086 * @noffset: hash node offset
1087 * @algo: double pointer to char, will hold pointer to the algorithm name
1089 * fit_image_hash_get_algo() finds hash algorithm property in a given hash node.
1090 * If the property is found its data start address is returned to the caller.
1096 int fit_image_hash_get_algo(const void *fit
, int noffset
, const char **algo
)
1100 *algo
= (const char *)fdt_getprop(fit
, noffset
, FIT_ALGO_PROP
, &len
);
1101 if (*algo
== NULL
) {
1102 fit_get_debug(fit
, noffset
, FIT_ALGO_PROP
, len
);
1110 * fit_image_hash_get_value - get hash value and length
1111 * @fit: pointer to the FIT format image header
1112 * @noffset: hash node offset
1113 * @value: double pointer to uint8_t, will hold address of a hash value data
1114 * @value_len: pointer to an int, will hold hash data length
1116 * fit_image_hash_get_value() finds hash value property in a given hash node.
1117 * If the property is found its data start address and size are returned to
1124 int fit_image_hash_get_value(const void *fit
, int noffset
, uint8_t **value
,
1129 *value
= (uint8_t *)fdt_getprop(fit
, noffset
, FIT_VALUE_PROP
, &len
);
1130 if (*value
== NULL
) {
1131 fit_get_debug(fit
, noffset
, FIT_VALUE_PROP
, len
);
1141 * fit_image_hash_get_ignore - get hash ignore flag
1142 * @fit: pointer to the FIT format image header
1143 * @noffset: hash node offset
1144 * @ignore: pointer to an int, will hold hash ignore flag
1146 * fit_image_hash_get_ignore() finds hash ignore property in a given hash node.
1147 * If the property is found and non-zero, the hash algorithm is not verified by
1148 * u-boot automatically.
1151 * 0, on ignore not found
1152 * value, on ignore found
1154 static int fit_image_hash_get_ignore(const void *fit
, int noffset
, int *ignore
)
1159 value
= (int *)fdt_getprop(fit
, noffset
, FIT_IGNORE_PROP
, &len
);
1160 if (value
== NULL
|| len
!= sizeof(int))
1169 * fit_image_cipher_get_algo - get cipher algorithm name
1170 * @fit: pointer to the FIT format image header
1171 * @noffset: cipher node offset
1172 * @algo: double pointer to char, will hold pointer to the algorithm name
1174 * fit_image_cipher_get_algo() finds cipher algorithm property in a given
1175 * cipher node. If the property is found its data start address is returned
1182 int fit_image_cipher_get_algo(const void *fit
, int noffset
, char **algo
)
1186 *algo
= (char *)fdt_getprop(fit
, noffset
, FIT_ALGO_PROP
, &len
);
1188 fit_get_debug(fit
, noffset
, FIT_ALGO_PROP
, len
);
1195 ulong
fit_get_end(const void *fit
)
1197 return map_to_sysmem((void *)(fit
+ fdt_totalsize(fit
)));
1201 * fit_set_timestamp - set node timestamp property
1202 * @fit: pointer to the FIT format image header
1203 * @noffset: node offset
1204 * @timestamp: timestamp value to be set
1206 * fit_set_timestamp() attempts to set timestamp property in the requested
1207 * node and returns operation status to the caller.
1211 * -ENOSPC if no space in device tree, -1 for other error
1213 int fit_set_timestamp(void *fit
, int noffset
, time_t timestamp
)
1218 t
= cpu_to_uimage(timestamp
);
1219 ret
= fdt_setprop(fit
, noffset
, FIT_TIMESTAMP_PROP
, &t
,
1222 debug("Can't set '%s' property for '%s' node (%s)\n",
1223 FIT_TIMESTAMP_PROP
, fit_get_name(fit
, noffset
, NULL
),
1225 return ret
== -FDT_ERR_NOSPACE
? -ENOSPC
: -1;
1232 * calculate_hash - calculate and return hash for provided input data
1233 * @data: pointer to the input data
1234 * @data_len: data length
1235 * @name: requested hash algorithm name
1236 * @value: pointer to the char, will hold hash value data (caller must
1237 * allocate enough free space)
1238 * value_len: length of the calculated hash
1240 * calculate_hash() computes input data hash according to the requested
1242 * Resulting hash value is placed in caller provided 'value' buffer, length
1243 * of the calculated hash is returned via value_len pointer argument.
1247 * -1, when algo is unsupported
1249 int calculate_hash(const void *data
, int data_len
, const char *name
,
1250 uint8_t *value
, int *value_len
)
1252 #if !defined(USE_HOSTCC) && defined(CONFIG_DM_HASH)
1254 enum HASH_ALGO hash_algo
;
1255 struct udevice
*dev
;
1257 rc
= uclass_get_device(UCLASS_HASH
, 0, &dev
);
1259 debug("failed to get hash device, rc=%d\n", rc
);
1263 hash_algo
= hash_algo_lookup_by_name(name
);
1264 if (hash_algo
== HASH_ALGO_INVALID
) {
1265 debug("Unsupported hash algorithm\n");
1269 rc
= hash_digest_wd(dev
, hash_algo
, data
, data_len
, value
, CHUNKSZ
);
1271 debug("failed to get hash value, rc=%d\n", rc
);
1275 *value_len
= hash_algo_digest_size(hash_algo
);
1277 struct hash_algo
*algo
;
1280 ret
= hash_lookup_algo(name
, &algo
);
1282 debug("Unsupported hash alogrithm\n");
1286 algo
->hash_func_ws(data
, data_len
, value
, algo
->chunk_size
);
1287 *value_len
= algo
->digest_size
;
1293 static int fit_image_check_hash(const void *fit
, int noffset
, const void *data
,
1294 size_t size
, char **err_msgp
)
1296 ALLOC_CACHE_ALIGN_BUFFER(uint8_t, value
, FIT_MAX_HASH_LEN
);
1305 if (fit_image_hash_get_algo(fit
, noffset
, &algo
)) {
1306 *err_msgp
= "Can't get hash algo property";
1311 if (!tools_build()) {
1312 fit_image_hash_get_ignore(fit
, noffset
, &ignore
);
1314 printf("-skipped ");
1319 if (fit_image_hash_get_value(fit
, noffset
, &fit_value
,
1321 *err_msgp
= "Can't get hash value property";
1325 if (calculate_hash(data
, size
, algo
, value
, &value_len
)) {
1326 *err_msgp
= "Unsupported hash algorithm";
1330 if (value_len
!= fit_value_len
) {
1331 *err_msgp
= "Bad hash value len";
1333 } else if (memcmp(value
, fit_value
, value_len
) != 0) {
1334 *err_msgp
= "Bad hash value";
1341 int fit_image_verify_with_data(const void *fit
, int image_noffset
,
1342 const void *key_blob
, const void *data
,
1350 /* Verify all required signatures */
1351 if (FIT_IMAGE_ENABLE_VERIFY
&&
1352 fit_image_verify_required_sigs(fit
, image_noffset
, data
, size
,
1353 key_blob
, &verify_all
)) {
1354 err_msg
= "Unable to verify required signature";
1358 /* Process all hash subnodes of the component image node */
1359 fdt_for_each_subnode(noffset
, fit
, image_noffset
) {
1360 const char *name
= fit_get_name(fit
, noffset
, NULL
);
1363 * Check subnode name, must be equal to "hash".
1364 * Multiple hash nodes require unique unit node
1365 * names, e.g. hash-1, hash-2, etc.
1367 if (!strncmp(name
, FIT_HASH_NODENAME
,
1368 strlen(FIT_HASH_NODENAME
))) {
1369 if (fit_image_check_hash(fit
, noffset
, data
, size
,
1373 } else if (FIT_IMAGE_ENABLE_VERIFY
&& verify_all
&&
1374 !strncmp(name
, FIT_SIG_NODENAME
,
1375 strlen(FIT_SIG_NODENAME
))) {
1376 ret
= fit_image_check_sig(fit
, noffset
, data
, size
,
1377 gd_fdt_blob(), -1, &err_msg
);
1380 * Show an indication on failure, but do not return
1381 * an error. Only keys marked 'required' can cause
1382 * an image validation failure. See the call to
1383 * fit_image_verify_required_sigs() above.
1392 if (noffset
== -FDT_ERR_TRUNCATED
|| noffset
== -FDT_ERR_BADSTRUCTURE
) {
1393 err_msg
= "Corrupted or truncated tree";
1400 printf(" error!\n%s for '%s' hash node in '%s' image node\n",
1401 err_msg
, fit_get_name(fit
, noffset
, NULL
),
1402 fit_get_name(fit
, image_noffset
, NULL
));
1407 * fit_image_verify - verify data integrity
1408 * @fit: pointer to the FIT format image header
1409 * @image_noffset: component image node offset
1411 * fit_image_verify() goes over component image hash nodes,
1412 * re-calculates each data hash and compares with the value stored in hash
1416 * 1, if all hashes are valid
1417 * 0, otherwise (or on error)
1419 int fit_image_verify(const void *fit
, int image_noffset
)
1421 const char *name
= fit_get_name(fit
, image_noffset
, NULL
);
1426 if (IS_ENABLED(CONFIG_FIT_SIGNATURE
) && strchr(name
, '@')) {
1428 * We don't support this since libfdt considers names with the
1429 * name root but different @ suffix to be equal
1431 err_msg
= "Node name contains @";
1434 /* Get image data and data length */
1435 if (fit_image_get_data(fit
, image_noffset
, &data
, &size
)) {
1436 err_msg
= "Can't get image data/size";
1440 return fit_image_verify_with_data(fit
, image_noffset
, gd_fdt_blob(),
1444 printf("error!\n%s in '%s' image node\n", err_msg
,
1445 fit_get_name(fit
, image_noffset
, NULL
));
1450 * fit_all_image_verify - verify data integrity for all images
1451 * @fit: pointer to the FIT format image header
1453 * fit_all_image_verify() goes over all images in the FIT and
1454 * for every images checks if all it's hashes are valid.
1457 * 1, if all hashes of all images are valid
1458 * 0, otherwise (or on error)
1460 int fit_all_image_verify(const void *fit
)
1467 /* Find images parent node offset */
1468 images_noffset
= fdt_path_offset(fit
, FIT_IMAGES_PATH
);
1469 if (images_noffset
< 0) {
1470 printf("Can't find images parent node '%s' (%s)\n",
1471 FIT_IMAGES_PATH
, fdt_strerror(images_noffset
));
1475 /* Process all image subnodes, check hashes for each */
1476 printf("## Checking hash(es) for FIT Image at %08lx ...\n",
1478 for (ndepth
= 0, count
= 0,
1479 noffset
= fdt_next_node(fit
, images_noffset
, &ndepth
);
1480 (noffset
>= 0) && (ndepth
> 0);
1481 noffset
= fdt_next_node(fit
, noffset
, &ndepth
)) {
1484 * Direct child node of the images parent node,
1485 * i.e. component image node.
1487 printf(" Hash(es) for Image %u (%s): ", count
,
1488 fit_get_name(fit
, noffset
, NULL
));
1491 if (!fit_image_verify(fit
, noffset
))
1499 static int fit_image_uncipher(const void *fit
, int image_noffset
,
1500 void **data
, size_t *size
)
1502 int cipher_noffset
, ret
;
1506 cipher_noffset
= fdt_subnode_offset(fit
, image_noffset
,
1507 FIT_CIPHER_NODENAME
);
1508 if (cipher_noffset
< 0)
1511 ret
= fit_image_decrypt_data(fit
, image_noffset
, cipher_noffset
,
1512 *data
, *size
, &dst
, &size_dst
);
1524 * fit_image_check_os - check whether image node is of a given os type
1525 * @fit: pointer to the FIT format image header
1526 * @noffset: component image node offset
1527 * @os: requested image os
1529 * fit_image_check_os() reads image os property and compares its numeric
1530 * id with the requested os. Comparison result is returned to the caller.
1533 * 1 if image is of given os type
1534 * 0 otherwise (or on error)
1536 int fit_image_check_os(const void *fit
, int noffset
, uint8_t os
)
1540 if (fit_image_get_os(fit
, noffset
, &image_os
))
1542 return (os
== image_os
);
1546 * fit_image_check_arch - check whether image node is of a given arch
1547 * @fit: pointer to the FIT format image header
1548 * @noffset: component image node offset
1549 * @arch: requested imagearch
1551 * fit_image_check_arch() reads image arch property and compares its numeric
1552 * id with the requested arch. Comparison result is returned to the caller.
1555 * 1 if image is of given arch
1556 * 0 otherwise (or on error)
1558 int fit_image_check_arch(const void *fit
, int noffset
, uint8_t arch
)
1561 int aarch32_support
= 0;
1563 /* Let's assume that sandbox can load any architecture */
1564 if (IS_ENABLED(CONFIG_SANDBOX
))
1567 if (IS_ENABLED(CONFIG_ARM64_SUPPORT_AARCH32
))
1568 aarch32_support
= 1;
1570 if (fit_image_get_arch(fit
, noffset
, &image_arch
))
1572 return (arch
== image_arch
) ||
1573 (arch
== IH_ARCH_I386
&& image_arch
== IH_ARCH_X86_64
) ||
1574 (arch
== IH_ARCH_ARM64
&& image_arch
== IH_ARCH_ARM
&&
1579 * fit_image_check_type - check whether image node is of a given type
1580 * @fit: pointer to the FIT format image header
1581 * @noffset: component image node offset
1582 * @type: requested image type
1584 * fit_image_check_type() reads image type property and compares its numeric
1585 * id with the requested type. Comparison result is returned to the caller.
1588 * 1 if image is of given type
1589 * 0 otherwise (or on error)
1591 int fit_image_check_type(const void *fit
, int noffset
, uint8_t type
)
1595 if (fit_image_get_type(fit
, noffset
, &image_type
))
1597 return (type
== image_type
);
1601 * fit_image_check_comp - check whether image node uses given compression
1602 * @fit: pointer to the FIT format image header
1603 * @noffset: component image node offset
1604 * @comp: requested image compression type
1606 * fit_image_check_comp() reads image compression property and compares its
1607 * numeric id with the requested compression type. Comparison result is
1608 * returned to the caller.
1611 * 1 if image uses requested compression
1612 * 0 otherwise (or on error)
1614 int fit_image_check_comp(const void *fit
, int noffset
, uint8_t comp
)
1618 if (fit_image_get_comp(fit
, noffset
, &image_comp
))
1620 return (comp
== image_comp
);
1624 * fdt_check_no_at() - Check for nodes whose names contain '@'
1626 * This checks the parent node and all subnodes recursively
1628 * @fit: FIT to check
1629 * @parent: Parent node to check
1630 * Return: 0 if OK, -EADDRNOTAVAIL is a node has a name containing '@'
1632 static int fdt_check_no_at(const void *fit
, int parent
)
1638 name
= fdt_get_name(fit
, parent
, NULL
);
1639 if (!name
|| strchr(name
, '@'))
1640 return -EADDRNOTAVAIL
;
1642 fdt_for_each_subnode(node
, fit
, parent
) {
1643 ret
= fdt_check_no_at(fit
, node
);
1651 int fit_check_format(const void *fit
, ulong size
)
1655 /* A FIT image must be a valid FDT */
1656 ret
= fdt_check_header(fit
);
1658 log_debug("Wrong FIT format: not a flattened device tree (err=%d)\n",
1663 if (CONFIG_IS_ENABLED(FIT_FULL_CHECK
)) {
1665 * If we are not given the size, make do wtih calculating it.
1666 * This is not as secure, so we should consider a flag to
1669 if (size
== IMAGE_SIZE_INVAL
)
1670 size
= fdt_totalsize(fit
);
1671 ret
= fdt_check_full(fit
, size
);
1676 * U-Boot stopped using unit addressed in 2017. Since libfdt
1677 * can match nodes ignoring any unit address, signature
1678 * verification can see the wrong node if one is inserted with
1679 * the same name as a valid node but with a unit address
1680 * attached. Protect against this by disallowing unit addresses.
1682 if (!ret
&& CONFIG_IS_ENABLED(FIT_SIGNATURE
)) {
1683 ret
= fdt_check_no_at(fit
, 0);
1686 log_debug("FIT check error %d\n", ret
);
1691 log_debug("FIT check error %d\n", ret
);
1696 /* mandatory / node 'description' property */
1697 if (!fdt_getprop(fit
, 0, FIT_DESC_PROP
, NULL
)) {
1698 log_debug("Wrong FIT format: no description\n");
1702 if (IMAGE_ENABLE_TIMESTAMP
) {
1703 /* mandatory / node 'timestamp' property */
1704 if (!fdt_getprop(fit
, 0, FIT_TIMESTAMP_PROP
, NULL
)) {
1705 log_debug("Wrong FIT format: no timestamp\n");
1710 /* mandatory subimages parent '/images' node */
1711 if (fdt_path_offset(fit
, FIT_IMAGES_PATH
) < 0) {
1712 log_debug("Wrong FIT format: no images parent node\n");
1719 int fit_conf_find_compat(const void *fit
, const void *fdt
)
1722 int noffset
, confs_noffset
, images_noffset
;
1723 const void *fdt_compat
;
1725 int best_match_offset
= 0;
1726 int best_match_pos
= 0;
1728 confs_noffset
= fdt_path_offset(fit
, FIT_CONFS_PATH
);
1729 images_noffset
= fdt_path_offset(fit
, FIT_IMAGES_PATH
);
1730 if (confs_noffset
< 0 || images_noffset
< 0) {
1731 debug("Can't find configurations or images nodes.\n");
1735 fdt_compat
= fdt_getprop(fdt
, 0, "compatible", &fdt_compat_len
);
1737 debug("Fdt for comparison has no \"compatible\" property.\n");
1742 * Loop over the configurations in the FIT image.
1744 for (noffset
= fdt_next_node(fit
, confs_noffset
, &ndepth
);
1745 (noffset
>= 0) && (ndepth
> 0);
1746 noffset
= fdt_next_node(fit
, noffset
, &ndepth
)) {
1748 const char *kfdt_name
;
1749 int kfdt_noffset
, compat_noffset
;
1750 const char *cur_fdt_compat
;
1758 /* If there's a compat property in the config node, use that. */
1759 if (fdt_getprop(fit
, noffset
, "compatible", NULL
)) {
1760 fdt
= fit
; /* search in FIT image */
1761 compat_noffset
= noffset
; /* search under config node */
1762 } else { /* Otherwise extract it from the kernel FDT. */
1763 kfdt_name
= fdt_getprop(fit
, noffset
, "fdt", &len
);
1765 debug("No fdt property found.\n");
1768 kfdt_noffset
= fdt_subnode_offset(fit
, images_noffset
,
1770 if (kfdt_noffset
< 0) {
1771 debug("No image node named \"%s\" found.\n",
1776 if (!fit_image_check_comp(fit
, kfdt_noffset
,
1778 debug("Can't extract compat from \"%s\" "
1779 "(compressed)\n", kfdt_name
);
1783 /* search in this config's kernel FDT */
1784 if (fit_image_get_data(fit
, kfdt_noffset
, &fdt
, &sz
)) {
1785 debug("Failed to get fdt \"%s\".\n", kfdt_name
);
1789 compat_noffset
= 0; /* search kFDT under root node */
1792 len
= fdt_compat_len
;
1793 cur_fdt_compat
= fdt_compat
;
1795 * Look for a match for each U-Boot compatibility string in
1796 * turn in the compat string property.
1798 for (i
= 0; len
> 0 &&
1799 (!best_match_offset
|| best_match_pos
> i
); i
++) {
1800 int cur_len
= strlen(cur_fdt_compat
) + 1;
1802 if (!fdt_node_check_compatible(fdt
, compat_noffset
,
1804 best_match_offset
= noffset
;
1809 cur_fdt_compat
+= cur_len
;
1812 if (!best_match_offset
) {
1813 debug("No match found.\n");
1817 return best_match_offset
;
1820 int fit_conf_get_node(const void *fit
, const char *conf_uname
)
1822 int noffset
, confs_noffset
;
1825 char *conf_uname_copy
= NULL
;
1827 confs_noffset
= fdt_path_offset(fit
, FIT_CONFS_PATH
);
1828 if (confs_noffset
< 0) {
1829 debug("Can't find configurations parent node '%s' (%s)\n",
1830 FIT_CONFS_PATH
, fdt_strerror(confs_noffset
));
1831 return confs_noffset
;
1834 if (conf_uname
== NULL
) {
1835 /* get configuration unit name from the default property */
1836 debug("No configuration specified, trying default...\n");
1837 if (!tools_build() && IS_ENABLED(CONFIG_MULTI_DTB_FIT
)) {
1838 noffset
= fit_find_config_node(fit
);
1841 conf_uname
= fdt_get_name(fit
, noffset
, NULL
);
1843 conf_uname
= (char *)fdt_getprop(fit
, confs_noffset
,
1844 FIT_DEFAULT_PROP
, &len
);
1845 if (conf_uname
== NULL
) {
1846 fit_get_debug(fit
, confs_noffset
, FIT_DEFAULT_PROP
,
1851 debug("Found default configuration: '%s'\n", conf_uname
);
1854 s
= strchr(conf_uname
, '#');
1856 len
= s
- conf_uname
;
1857 conf_uname_copy
= malloc(len
+ 1);
1858 if (!conf_uname_copy
) {
1859 debug("Can't allocate uname copy: '%s'\n",
1863 memcpy(conf_uname_copy
, conf_uname
, len
);
1864 conf_uname_copy
[len
] = '\0';
1865 conf_uname
= conf_uname_copy
;
1868 noffset
= fdt_subnode_offset(fit
, confs_noffset
, conf_uname
);
1870 debug("Can't get node offset for configuration unit name: '%s' (%s)\n",
1871 conf_uname
, fdt_strerror(noffset
));
1874 free(conf_uname_copy
);
1879 int fit_conf_get_prop_node_count(const void *fit
, int noffset
,
1880 const char *prop_name
)
1882 return fdt_stringlist_count(fit
, noffset
, prop_name
);
1885 int fit_conf_get_prop_node_index(const void *fit
, int noffset
,
1886 const char *prop_name
, int index
)
1891 /* get kernel image unit name from configuration kernel property */
1892 uname
= fdt_stringlist_get(fit
, noffset
, prop_name
, index
, &len
);
1896 return fit_image_get_node(fit
, uname
);
1899 int fit_conf_get_prop_node(const void *fit
, int noffset
, const char *prop_name
,
1900 enum image_phase_t sel_phase
)
1904 if (sel_phase
== IH_PHASE_NONE
)
1905 return fit_conf_get_prop_node_index(fit
, noffset
, prop_name
, 0);
1907 count
= fit_conf_get_prop_node_count(fit
, noffset
, prop_name
);
1911 /* check each image in the list */
1912 for (i
= 0; i
< count
; i
++) {
1913 enum image_phase_t phase
;
1916 node
= fit_conf_get_prop_node_index(fit
, noffset
, prop_name
, i
);
1917 ret
= fit_image_get_phase(fit
, node
, &phase
);
1919 /* if the image is for any phase, let's use it */
1925 if (phase
== sel_phase
)
1932 static int fit_get_data_tail(const void *fit
, int noffset
,
1933 const void **data
, size_t *size
)
1940 if (!fit_image_verify(fit
, noffset
))
1943 if (fit_image_get_data(fit
, noffset
, data
, size
))
1946 if (!fit_get_desc(fit
, noffset
, &desc
))
1947 printf("%s\n", desc
);
1952 int fit_get_data_node(const void *fit
, const char *image_uname
,
1953 const void **data
, size_t *size
)
1955 int noffset
= fit_image_get_node(fit
, image_uname
);
1957 return fit_get_data_tail(fit
, noffset
, data
, size
);
1960 int fit_get_data_conf_prop(const void *fit
, const char *prop_name
,
1961 const void **data
, size_t *size
)
1963 int noffset
= fit_conf_get_node(fit
, NULL
);
1965 noffset
= fit_conf_get_prop_node(fit
, noffset
, prop_name
,
1967 return fit_get_data_tail(fit
, noffset
, data
, size
);
1970 static int fit_image_select(const void *fit
, int rd_noffset
, int verify
)
1972 fit_image_print(fit
, rd_noffset
, " ");
1975 puts(" Verifying Hash Integrity ... ");
1976 if (!fit_image_verify(fit
, rd_noffset
)) {
1977 puts("Bad Data Hash\n");
1986 int fit_get_node_from_config(struct bootm_headers
*images
,
1987 const char *prop_name
, ulong addr
)
1993 debug("* %s: using config '%s' from image at 0x%08lx\n",
1994 prop_name
, images
->fit_uname_cfg
, addr
);
1996 /* Check whether configuration has this property defined */
1997 fit_hdr
= map_sysmem(addr
, 0);
1998 cfg_noffset
= fit_conf_get_node(fit_hdr
, images
->fit_uname_cfg
);
1999 if (cfg_noffset
< 0) {
2000 debug("* %s: no such config\n", prop_name
);
2004 noffset
= fit_conf_get_prop_node(fit_hdr
, cfg_noffset
, prop_name
,
2007 debug("* %s: no '%s' in config\n", prop_name
, prop_name
);
2015 * fit_get_image_type_property() - get property name for IH_TYPE_...
2017 * Return: the properly name where we expect to find the image in the
2020 static const char *fit_get_image_type_property(int type
)
2023 * This is sort-of available in the uimage_type[] table in image.c
2024 * but we don't have access to the short name, and "fdt" is different
2025 * anyway. So let's just keep it here.
2028 case IH_TYPE_FLATDT
:
2029 return FIT_FDT_PROP
;
2030 case IH_TYPE_KERNEL
:
2031 return FIT_KERNEL_PROP
;
2032 case IH_TYPE_FIRMWARE
:
2033 return FIT_FIRMWARE_PROP
;
2034 case IH_TYPE_RAMDISK
:
2035 return FIT_RAMDISK_PROP
;
2036 case IH_TYPE_X86_SETUP
:
2037 return FIT_SETUP_PROP
;
2038 case IH_TYPE_LOADABLE
:
2039 return FIT_LOADABLE_PROP
;
2041 return FIT_FPGA_PROP
;
2042 case IH_TYPE_STANDALONE
:
2043 return FIT_STANDALONE_PROP
;
2049 int fit_image_load(struct bootm_headers
*images
, ulong addr
,
2050 const char **fit_unamep
, const char **fit_uname_configp
,
2051 int arch
, int ph_type
, int bootstage_id
,
2052 enum fit_load_op load_op
, ulong
*datap
, ulong
*lenp
)
2054 int image_type
= image_ph_type(ph_type
);
2055 int cfg_noffset
, noffset
;
2056 const char *fit_uname
;
2057 const char *fit_uname_config
;
2058 const char *fit_base_uname_config
;
2064 ulong load
, load_end
, data
, len
;
2066 const char *prop_name
;
2069 fit
= map_sysmem(addr
, 0);
2070 fit_uname
= fit_unamep
? *fit_unamep
: NULL
;
2071 fit_uname_config
= fit_uname_configp
? *fit_uname_configp
: NULL
;
2072 fit_base_uname_config
= NULL
;
2073 prop_name
= fit_get_image_type_property(image_type
);
2074 printf("## Loading %s from FIT Image at %08lx ...\n", prop_name
, addr
);
2076 bootstage_mark(bootstage_id
+ BOOTSTAGE_SUB_FORMAT
);
2077 ret
= fit_check_format(fit
, IMAGE_SIZE_INVAL
);
2079 printf("Bad FIT %s image format! (err=%d)\n", prop_name
, ret
);
2080 if (CONFIG_IS_ENABLED(FIT_SIGNATURE
) && ret
== -EADDRNOTAVAIL
)
2081 printf("Signature checking prevents use of unit addresses (@) in nodes\n");
2082 bootstage_error(bootstage_id
+ BOOTSTAGE_SUB_FORMAT
);
2085 bootstage_mark(bootstage_id
+ BOOTSTAGE_SUB_FORMAT_OK
);
2087 /* get FIT component image node offset */
2088 bootstage_mark(bootstage_id
+ BOOTSTAGE_SUB_UNIT_NAME
);
2089 noffset
= fit_image_get_node(fit
, fit_uname
);
2092 * no image node unit name, try to get config
2093 * node first. If config unit node name is NULL
2094 * fit_conf_get_node() will try to find default config node
2096 bootstage_mark(bootstage_id
+ BOOTSTAGE_SUB_NO_UNIT_NAME
);
2098 if (IS_ENABLED(CONFIG_FIT_BEST_MATCH
) && !fit_uname_config
)
2099 ret
= fit_conf_find_compat(fit
, gd_fdt_blob());
2100 if (ret
< 0 && ret
!= -EINVAL
)
2101 ret
= fit_conf_get_node(fit
, fit_uname_config
);
2103 puts("Could not find configuration node\n");
2104 bootstage_error(bootstage_id
+
2105 BOOTSTAGE_SUB_NO_UNIT_NAME
);
2110 fit_base_uname_config
= fdt_get_name(fit
, cfg_noffset
, NULL
);
2111 printf(" Using '%s' configuration\n", fit_base_uname_config
);
2112 /* Remember this config */
2113 if (image_type
== IH_TYPE_KERNEL
)
2114 images
->fit_uname_cfg
= fit_base_uname_config
;
2116 if (FIT_IMAGE_ENABLE_VERIFY
&& images
->verify
) {
2117 puts(" Verifying Hash Integrity ... ");
2118 if (fit_config_verify(fit
, cfg_noffset
)) {
2119 puts("Bad Data Hash\n");
2120 bootstage_error(bootstage_id
+
2121 BOOTSTAGE_SUB_HASH
);
2127 bootstage_mark(BOOTSTAGE_ID_FIT_CONFIG
);
2129 noffset
= fit_conf_get_prop_node(fit
, cfg_noffset
, prop_name
,
2130 image_ph_phase(ph_type
));
2131 fit_uname
= fit_get_name(fit
, noffset
, NULL
);
2134 printf("Could not find subimage node type '%s'\n", prop_name
);
2135 bootstage_error(bootstage_id
+ BOOTSTAGE_SUB_SUBNODE
);
2139 printf(" Trying '%s' %s subimage\n", fit_uname
, prop_name
);
2141 ret
= fit_image_select(fit
, noffset
, images
->verify
);
2143 bootstage_error(bootstage_id
+ BOOTSTAGE_SUB_HASH
);
2147 bootstage_mark(bootstage_id
+ BOOTSTAGE_SUB_CHECK_ARCH
);
2148 if (!tools_build() && IS_ENABLED(CONFIG_SANDBOX
)) {
2149 if (!fit_image_check_target_arch(fit
, noffset
)) {
2150 puts("Unsupported Architecture\n");
2151 bootstage_error(bootstage_id
+ BOOTSTAGE_SUB_CHECK_ARCH
);
2160 fit_image_get_arch(fit
, noffset
, &os_arch
);
2161 images
->os
.arch
= os_arch
;
2165 bootstage_mark(bootstage_id
+ BOOTSTAGE_SUB_CHECK_ALL
);
2166 type_ok
= fit_image_check_type(fit
, noffset
, image_type
) ||
2167 fit_image_check_type(fit
, noffset
, IH_TYPE_FIRMWARE
) ||
2168 fit_image_check_type(fit
, noffset
, IH_TYPE_TEE
) ||
2169 (image_type
== IH_TYPE_KERNEL
&&
2170 fit_image_check_type(fit
, noffset
, IH_TYPE_KERNEL_NOLOAD
));
2172 os_ok
= image_type
== IH_TYPE_FLATDT
||
2173 image_type
== IH_TYPE_FPGA
||
2174 fit_image_check_os(fit
, noffset
, IH_OS_LINUX
) ||
2175 fit_image_check_os(fit
, noffset
, IH_OS_U_BOOT
) ||
2176 fit_image_check_os(fit
, noffset
, IH_OS_TEE
) ||
2177 fit_image_check_os(fit
, noffset
, IH_OS_OPENRTOS
) ||
2178 fit_image_check_os(fit
, noffset
, IH_OS_EFI
) ||
2179 fit_image_check_os(fit
, noffset
, IH_OS_VXWORKS
) ||
2180 fit_image_check_os(fit
, noffset
, IH_OS_ELF
);
2183 * If either of the checks fail, we should report an error, but
2184 * if the image type is coming from the "loadables" field, we
2185 * don't care what it is
2187 if ((!type_ok
|| !os_ok
) && image_type
!= IH_TYPE_LOADABLE
) {
2188 fit_image_get_os(fit
, noffset
, &os
);
2189 printf("No %s %s %s Image\n",
2190 genimg_get_os_name(os
),
2191 genimg_get_arch_name(arch
),
2192 genimg_get_type_name(image_type
));
2193 bootstage_error(bootstage_id
+ BOOTSTAGE_SUB_CHECK_ALL
);
2197 bootstage_mark(bootstage_id
+ BOOTSTAGE_SUB_CHECK_ALL_OK
);
2199 /* get image data address and length */
2200 if (fit_image_get_data(fit
, noffset
, (const void **)&buf
, &size
)) {
2201 printf("Could not find %s subimage data!\n", prop_name
);
2202 bootstage_error(bootstage_id
+ BOOTSTAGE_SUB_GET_DATA
);
2206 /* Decrypt data before uncompress/move */
2207 if (IS_ENABLED(CONFIG_FIT_CIPHER
) && IMAGE_ENABLE_DECRYPT
) {
2208 puts(" Decrypting Data ... ");
2209 if (fit_image_uncipher(fit
, noffset
, &buf
, &size
)) {
2216 /* perform any post-processing on the image data */
2217 if (!tools_build() && IS_ENABLED(CONFIG_FIT_IMAGE_POST_PROCESS
))
2218 board_fit_image_post_process(fit
, noffset
, &buf
, &size
);
2222 bootstage_mark(bootstage_id
+ BOOTSTAGE_SUB_GET_DATA_OK
);
2224 data
= map_to_sysmem(buf
);
2226 if (load_op
== FIT_LOAD_IGNORED
) {
2227 log_debug("load_op: not loading\n");
2229 } else if (fit_image_get_load(fit
, noffset
, &load
)) {
2230 if (load_op
== FIT_LOAD_REQUIRED
) {
2231 printf("Can't get %s subimage load address!\n",
2233 bootstage_error(bootstage_id
+ BOOTSTAGE_SUB_LOAD
);
2236 } else if (load_op
!= FIT_LOAD_OPTIONAL_NON_ZERO
|| load
) {
2237 ulong image_start
, image_end
;
2240 * move image data to the load address,
2241 * make sure we don't overwrite initial image
2244 image_end
= addr
+ fit_get_size(fit
);
2246 load_end
= load
+ len
;
2247 if (image_type
!= IH_TYPE_KERNEL
&&
2248 load
< image_end
&& load_end
> image_start
) {
2249 printf("Error: %s overwritten\n", prop_name
);
2253 printf(" Loading %s from 0x%08lx to 0x%08lx\n",
2254 prop_name
, data
, load
);
2256 load
= data
; /* No load address specified */
2259 comp
= IH_COMP_NONE
;
2261 /* Kernel images get decompressed later in bootm_load_os(). */
2262 if (!fit_image_get_comp(fit
, noffset
, &comp
) &&
2263 comp
!= IH_COMP_NONE
&&
2264 load_op
!= FIT_LOAD_IGNORED
&&
2265 !(image_type
== IH_TYPE_KERNEL
||
2266 image_type
== IH_TYPE_KERNEL_NOLOAD
||
2267 image_type
== IH_TYPE_RAMDISK
)) {
2268 ulong max_decomp_len
= len
* 20;
2270 log_debug("decompressing image\n");
2272 loadbuf
= malloc(max_decomp_len
);
2273 load
= map_to_sysmem(loadbuf
);
2275 loadbuf
= map_sysmem(load
, max_decomp_len
);
2277 if (image_decomp(comp
, load
, data
, image_type
,
2278 loadbuf
, buf
, len
, max_decomp_len
, &load_end
)) {
2279 printf("Error decompressing %s\n", prop_name
);
2283 len
= load_end
- load
;
2284 } else if (load
!= data
) {
2285 log_debug("copying\n");
2286 loadbuf
= map_sysmem(load
, len
);
2287 memcpy(loadbuf
, buf
, len
);
2290 if (image_type
== IH_TYPE_RAMDISK
&& comp
!= IH_COMP_NONE
)
2291 puts("WARNING: 'compression' nodes for ramdisks are deprecated,"
2292 " please fix your .its file!\n");
2294 /* verify that image data is a proper FDT blob */
2295 if (load_op
!= FIT_LOAD_IGNORED
&& image_type
== IH_TYPE_FLATDT
&&
2296 fdt_check_header(loadbuf
)) {
2297 puts("Subimage data is not a FDT\n");
2301 bootstage_mark(bootstage_id
+ BOOTSTAGE_SUB_LOAD
);
2303 upl_add_image(fit
, noffset
, load
, len
);
2308 *fit_unamep
= (char *)fit_uname
;
2309 if (fit_uname_configp
)
2310 *fit_uname_configp
= (char *)(fit_uname_config
? :
2311 fit_base_uname_config
);
2316 int boot_get_setup_fit(struct bootm_headers
*images
, uint8_t arch
,
2317 ulong
*setup_start
, ulong
*setup_len
)
2324 addr
= map_to_sysmem(images
->fit_hdr_os
);
2325 noffset
= fit_get_node_from_config(images
, FIT_SETUP_PROP
, addr
);
2329 ret
= fit_image_load(images
, addr
, NULL
, NULL
, arch
,
2330 IH_TYPE_X86_SETUP
, BOOTSTAGE_ID_FIT_SETUP_START
,
2331 FIT_LOAD_REQUIRED
, setup_start
, &len
);
2337 int boot_get_fdt_fit(struct bootm_headers
*images
, ulong addr
,
2338 const char **fit_unamep
, const char **fit_uname_configp
,
2339 int arch
, ulong
*datap
, ulong
*lenp
)
2341 int fdt_noffset
, cfg_noffset
, count
;
2343 const char *fit_uname
= NULL
;
2344 const char *fit_uname_config
= NULL
;
2345 char *fit_uname_config_copy
= NULL
;
2346 char *next_config
= NULL
;
2348 #ifdef CONFIG_OF_LIBFDT_OVERLAY
2349 ulong image_start
, image_end
;
2350 ulong ovload
, ovlen
, ovcopylen
;
2351 const char *uconfig
;
2353 void *base
, *ov
, *ovcopy
= NULL
;
2354 int i
, err
, noffset
, ov_noffset
;
2357 fit_uname
= fit_unamep
? *fit_unamep
: NULL
;
2359 if (fit_uname_configp
&& *fit_uname_configp
) {
2360 fit_uname_config_copy
= strdup(*fit_uname_configp
);
2361 if (!fit_uname_config_copy
)
2364 next_config
= strchr(fit_uname_config_copy
, '#');
2366 *next_config
++ = '\0';
2367 if (next_config
- 1 > fit_uname_config_copy
)
2368 fit_uname_config
= fit_uname_config_copy
;
2371 fdt_noffset
= fit_image_load(images
,
2372 addr
, &fit_uname
, &fit_uname_config
,
2373 arch
, IH_TYPE_FLATDT
,
2374 BOOTSTAGE_ID_FIT_FDT_START
,
2375 FIT_LOAD_OPTIONAL
, &load
, &len
);
2377 if (fdt_noffset
< 0)
2380 debug("fit_uname=%s, fit_uname_config=%s\n",
2381 fit_uname
? fit_uname
: "<NULL>",
2382 fit_uname_config
? fit_uname_config
: "<NULL>");
2384 fit
= map_sysmem(addr
, 0);
2386 cfg_noffset
= fit_conf_get_node(fit
, fit_uname_config
);
2388 /* single blob, or error just return as well */
2389 count
= fit_conf_get_prop_node_count(fit
, cfg_noffset
, FIT_FDT_PROP
);
2390 if (count
<= 1 && !next_config
)
2393 /* we need to apply overlays */
2395 #ifdef CONFIG_OF_LIBFDT_OVERLAY
2397 image_end
= addr
+ fit_get_size(fit
);
2398 /* verify that relocation took place by load address not being in fit */
2399 if (load
>= image_start
&& load
< image_end
) {
2400 /* check is simplified; fit load checks for overlaps */
2401 printf("Overlayed FDT requires relocation\n");
2402 fdt_noffset
= -EBADF
;
2406 base
= map_sysmem(load
, len
);
2408 /* apply extra configs in FIT first, followed by args */
2409 for (i
= 1; ; i
++) {
2411 noffset
= fit_conf_get_prop_node_index(fit
, cfg_noffset
,
2413 uname
= fit_get_name(fit
, noffset
, NULL
);
2418 uconfig
= next_config
;
2419 next_config
= strchr(next_config
, '#');
2421 *next_config
++ = '\0';
2425 * fit_image_load() would load the first FDT from the
2426 * extra config only when uconfig is specified.
2427 * Check if the extra config contains multiple FDTs and
2430 cfg_noffset
= fit_conf_get_node(fit
, uconfig
);
2433 count
= fit_conf_get_prop_node_count(fit
, cfg_noffset
,
2437 debug("%d: using uname=%s uconfig=%s\n", i
, uname
, uconfig
);
2439 ov_noffset
= fit_image_load(images
,
2440 addr
, &uname
, &uconfig
,
2441 arch
, IH_TYPE_FLATDT
,
2442 BOOTSTAGE_ID_FIT_FDT_START
,
2443 FIT_LOAD_IGNORED
, &ovload
, &ovlen
);
2444 if (ov_noffset
< 0) {
2445 printf("load of %s failed\n", uname
);
2448 debug("%s loaded at 0x%08lx len=0x%08lx\n",
2449 uname
, ovload
, ovlen
);
2450 ov
= map_sysmem(ovload
, ovlen
);
2452 ovcopylen
= ALIGN(fdt_totalsize(ov
), SZ_4K
);
2453 ovcopy
= malloc(ovcopylen
);
2455 printf("failed to duplicate DTO before application\n");
2456 fdt_noffset
= -ENOMEM
;
2460 err
= fdt_open_into(ov
, ovcopy
, ovcopylen
);
2462 printf("failed on fdt_open_into for DTO\n");
2467 base
= map_sysmem(load
, len
+ ovlen
);
2468 err
= fdt_open_into(base
, base
, len
+ ovlen
);
2470 printf("failed on fdt_open_into\n");
2475 /* the verbose method prints out messages on error */
2476 err
= fdt_overlay_apply_verbose(base
, ovcopy
);
2482 len
= fdt_totalsize(base
);
2485 printf("config with overlays but CONFIG_OF_LIBFDT_OVERLAY not set\n");
2486 fdt_noffset
= -EBADF
;
2495 *fit_unamep
= fit_uname
;
2496 if (fit_uname_configp
)
2497 *fit_uname_configp
= fit_uname_config
;
2499 #ifdef CONFIG_OF_LIBFDT_OVERLAY
2502 free(fit_uname_config_copy
);