1
2
3
4
5
6
7
8
9
10
11#ifdef USE_HOSTCC
12#include "mkimage.h"
13#include <time.h>
14#include <u-boot/crc.h>
15#else
16#include <linux/compiler.h>
17#include <linux/kconfig.h>
18#include <common.h>
19#include <errno.h>
20#include <mapmem.h>
21#include <asm/io.h>
22#include <malloc.h>
23DECLARE_GLOBAL_DATA_PTR;
24#endif
25
26#include <bootm.h>
27#include <image.h>
28#include <bootstage.h>
29#include <u-boot/crc.h>
30#include <u-boot/md5.h>
31#include <u-boot/sha1.h>
32#include <u-boot/sha256.h>
33
34
35
36
37#ifndef USE_HOSTCC
38static int fit_parse_spec(const char *spec, char sepc, ulong addr_curr,
39 ulong *addr, const char **name)
40{
41 const char *sep;
42
43 *addr = addr_curr;
44 *name = NULL;
45
46 sep = strchr(spec, sepc);
47 if (sep) {
48 if (sep - spec > 0)
49 *addr = simple_strtoul(spec, NULL, 16);
50
51 *name = sep + 1;
52 return 1;
53 }
54
55 return 0;
56}
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79int fit_parse_conf(const char *spec, ulong addr_curr,
80 ulong *addr, const char **conf_name)
81{
82 return fit_parse_spec(spec, '#', addr_curr, addr, conf_name);
83}
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105int fit_parse_subimage(const char *spec, ulong addr_curr,
106 ulong *addr, const char **image_name)
107{
108 return fit_parse_spec(spec, ':', addr_curr, addr, image_name);
109}
110#endif
111
112static void fit_get_debug(const void *fit, int noffset,
113 char *prop_name, int err)
114{
115 debug("Can't get '%s' property from FIT 0x%08lx, node: offset %d, name %s (%s)\n",
116 prop_name, (ulong)fit, noffset, fit_get_name(fit, noffset, NULL),
117 fdt_strerror(err));
118}
119
120
121
122
123
124
125
126
127
128int fit_get_subimage_count(const void *fit, int images_noffset)
129{
130 int noffset;
131 int ndepth;
132 int count = 0;
133
134
135 for (ndepth = 0, count = 0,
136 noffset = fdt_next_node(fit, images_noffset, &ndepth);
137 (noffset >= 0) && (ndepth > 0);
138 noffset = fdt_next_node(fit, noffset, &ndepth)) {
139 if (ndepth == 1) {
140 count++;
141 }
142 }
143
144 return count;
145}
146
147#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_FIT_PRINT)
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163static void fit_image_print_data(const void *fit, int noffset, const char *p,
164 const char *type)
165{
166 const char *keyname;
167 uint8_t *value;
168 int value_len;
169 char *algo;
170 const char *padding;
171 bool required;
172 int ret, i;
173
174 debug("%s %s node: '%s'\n", p, type,
175 fit_get_name(fit, noffset, NULL));
176 printf("%s %s algo: ", p, type);
177 if (fit_image_hash_get_algo(fit, noffset, &algo)) {
178 printf("invalid/unsupported\n");
179 return;
180 }
181 printf("%s", algo);
182 keyname = fdt_getprop(fit, noffset, FIT_KEY_HINT, NULL);
183 required = fdt_getprop(fit, noffset, FIT_KEY_REQUIRED, NULL) != NULL;
184 if (keyname)
185 printf(":%s", keyname);
186 if (required)
187 printf(" (required)");
188 printf("\n");
189
190 padding = fdt_getprop(fit, noffset, "padding", NULL);
191 if (padding)
192 printf("%s %s padding: %s\n", p, type, padding);
193
194 ret = fit_image_hash_get_value(fit, noffset, &value,
195 &value_len);
196 printf("%s %s value: ", p, type);
197 if (ret) {
198 printf("unavailable\n");
199 } else {
200 for (i = 0; i < value_len; i++)
201 printf("%02x", value[i]);
202 printf("\n");
203 }
204
205 debug("%s %s len: %d\n", p, type, value_len);
206
207
208 if (IMAGE_ENABLE_TIMESTAMP && keyname) {
209 time_t timestamp;
210
211 printf("%s Timestamp: ", p);
212 if (fit_get_timestamp(fit, noffset, ×tamp))
213 printf("unavailable\n");
214 else
215 genimg_print_time(timestamp);
216 }
217}
218
219
220
221
222
223
224
225
226
227
228
229
230static void fit_image_print_verification_data(const void *fit, int noffset,
231 const char *p)
232{
233 const char *name;
234
235
236
237
238
239
240 name = fit_get_name(fit, noffset, NULL);
241 if (!strncmp(name, FIT_HASH_NODENAME, strlen(FIT_HASH_NODENAME))) {
242 fit_image_print_data(fit, noffset, p, "Hash");
243 } else if (!strncmp(name, FIT_SIG_NODENAME,
244 strlen(FIT_SIG_NODENAME))) {
245 fit_image_print_data(fit, noffset, p, "Sign");
246 }
247}
248
249
250
251
252
253
254
255
256
257
258
259
260
261static void fit_conf_print(const void *fit, int noffset, const char *p)
262{
263 char *desc;
264 const char *uname;
265 int ret;
266 int fdt_index, loadables_index;
267 int ndepth;
268
269
270 ret = fit_get_desc(fit, noffset, &desc);
271 printf("%s Description: ", p);
272 if (ret)
273 printf("unavailable\n");
274 else
275 printf("%s\n", desc);
276
277 uname = fdt_getprop(fit, noffset, FIT_KERNEL_PROP, NULL);
278 printf("%s Kernel: ", p);
279 if (!uname)
280 printf("unavailable\n");
281 else
282 printf("%s\n", uname);
283
284
285 uname = fdt_getprop(fit, noffset, FIT_RAMDISK_PROP, NULL);
286 if (uname)
287 printf("%s Init Ramdisk: %s\n", p, uname);
288
289 uname = fdt_getprop(fit, noffset, FIT_FIRMWARE_PROP, NULL);
290 if (uname)
291 printf("%s Firmware: %s\n", p, uname);
292
293 for (fdt_index = 0;
294 uname = fdt_stringlist_get(fit, noffset, FIT_FDT_PROP,
295 fdt_index, NULL), uname;
296 fdt_index++) {
297 if (fdt_index == 0)
298 printf("%s FDT: ", p);
299 else
300 printf("%s ", p);
301 printf("%s\n", uname);
302 }
303
304 uname = fdt_getprop(fit, noffset, FIT_FPGA_PROP, NULL);
305 if (uname)
306 printf("%s FPGA: %s\n", p, uname);
307
308
309 for (loadables_index = 0;
310 uname = fdt_stringlist_get(fit, noffset, FIT_LOADABLE_PROP,
311 loadables_index, NULL), uname;
312 loadables_index++) {
313 if (loadables_index == 0) {
314 printf("%s Loadables: ", p);
315 } else {
316 printf("%s ", p);
317 }
318 printf("%s\n", uname);
319 }
320
321
322 for (ndepth = 0, noffset = fdt_next_node(fit, noffset, &ndepth);
323 (noffset >= 0) && (ndepth > 0);
324 noffset = fdt_next_node(fit, noffset, &ndepth)) {
325 if (ndepth == 1) {
326
327 fit_image_print_verification_data(fit, noffset, p);
328 }
329 }
330}
331
332
333
334
335
336
337
338
339
340
341
342
343
344void fit_print_contents(const void *fit)
345{
346 char *desc;
347 char *uname;
348 int images_noffset;
349 int confs_noffset;
350 int noffset;
351 int ndepth;
352 int count = 0;
353 int ret;
354 const char *p;
355 time_t timestamp;
356
357
358 p = IMAGE_INDENT_STRING;
359
360
361 ret = fit_get_desc(fit, 0, &desc);
362 printf("%sFIT description: ", p);
363 if (ret)
364 printf("unavailable\n");
365 else
366 printf("%s\n", desc);
367
368 if (IMAGE_ENABLE_TIMESTAMP) {
369 ret = fit_get_timestamp(fit, 0, ×tamp);
370 printf("%sCreated: ", p);
371 if (ret)
372 printf("unavailable\n");
373 else
374 genimg_print_time(timestamp);
375 }
376
377
378 images_noffset = fdt_path_offset(fit, FIT_IMAGES_PATH);
379 if (images_noffset < 0) {
380 printf("Can't find images parent node '%s' (%s)\n",
381 FIT_IMAGES_PATH, fdt_strerror(images_noffset));
382 return;
383 }
384
385
386 for (ndepth = 0, count = 0,
387 noffset = fdt_next_node(fit, images_noffset, &ndepth);
388 (noffset >= 0) && (ndepth > 0);
389 noffset = fdt_next_node(fit, noffset, &ndepth)) {
390 if (ndepth == 1) {
391
392
393
394
395 printf("%s Image %u (%s)\n", p, count++,
396 fit_get_name(fit, noffset, NULL));
397
398 fit_image_print(fit, noffset, p);
399 }
400 }
401
402
403 confs_noffset = fdt_path_offset(fit, FIT_CONFS_PATH);
404 if (confs_noffset < 0) {
405 debug("Can't get configurations parent node '%s' (%s)\n",
406 FIT_CONFS_PATH, fdt_strerror(confs_noffset));
407 return;
408 }
409
410
411 uname = (char *)fdt_getprop(fit, noffset, FIT_DEFAULT_PROP, NULL);
412 if (uname)
413 printf("%s Default Configuration: '%s'\n", p, uname);
414
415
416 for (ndepth = 0, count = 0,
417 noffset = fdt_next_node(fit, confs_noffset, &ndepth);
418 (noffset >= 0) && (ndepth > 0);
419 noffset = fdt_next_node(fit, noffset, &ndepth)) {
420 if (ndepth == 1) {
421
422
423
424
425 printf("%s Configuration %u (%s)\n", p, count++,
426 fit_get_name(fit, noffset, NULL));
427
428 fit_conf_print(fit, noffset, p);
429 }
430 }
431}
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448void fit_image_print(const void *fit, int image_noffset, const char *p)
449{
450 char *desc;
451 uint8_t type, arch, os, comp;
452 size_t size;
453 ulong load, entry;
454 const void *data;
455 int noffset;
456 int ndepth;
457 int ret;
458
459
460 ret = fit_get_desc(fit, image_noffset, &desc);
461 printf("%s Description: ", p);
462 if (ret)
463 printf("unavailable\n");
464 else
465 printf("%s\n", desc);
466
467 if (IMAGE_ENABLE_TIMESTAMP) {
468 time_t timestamp;
469
470 ret = fit_get_timestamp(fit, 0, ×tamp);
471 printf("%s Created: ", p);
472 if (ret)
473 printf("unavailable\n");
474 else
475 genimg_print_time(timestamp);
476 }
477
478 fit_image_get_type(fit, image_noffset, &type);
479 printf("%s Type: %s\n", p, genimg_get_type_name(type));
480
481 fit_image_get_comp(fit, image_noffset, &comp);
482 printf("%s Compression: %s\n", p, genimg_get_comp_name(comp));
483
484 ret = fit_image_get_data_and_size(fit, image_noffset, &data, &size);
485
486#ifndef USE_HOSTCC
487 printf("%s Data Start: ", p);
488 if (ret) {
489 printf("unavailable\n");
490 } else {
491 void *vdata = (void *)data;
492
493 printf("0x%08lx\n", (ulong)map_to_sysmem(vdata));
494 }
495#endif
496
497 printf("%s Data Size: ", p);
498 if (ret)
499 printf("unavailable\n");
500 else
501 genimg_print_size(size);
502
503
504 if ((type == IH_TYPE_KERNEL) || (type == IH_TYPE_STANDALONE) ||
505 (type == IH_TYPE_RAMDISK) || (type == IH_TYPE_FIRMWARE) ||
506 (type == IH_TYPE_FLATDT)) {
507 fit_image_get_arch(fit, image_noffset, &arch);
508 printf("%s Architecture: %s\n", p, genimg_get_arch_name(arch));
509 }
510
511 if ((type == IH_TYPE_KERNEL) || (type == IH_TYPE_RAMDISK) ||
512 (type == IH_TYPE_FIRMWARE)) {
513 fit_image_get_os(fit, image_noffset, &os);
514 printf("%s OS: %s\n", p, genimg_get_os_name(os));
515 }
516
517 if ((type == IH_TYPE_KERNEL) || (type == IH_TYPE_STANDALONE) ||
518 (type == IH_TYPE_FIRMWARE) || (type == IH_TYPE_RAMDISK) ||
519 (type == IH_TYPE_FPGA)) {
520 ret = fit_image_get_load(fit, image_noffset, &load);
521 printf("%s Load Address: ", p);
522 if (ret)
523 printf("unavailable\n");
524 else
525 printf("0x%08lx\n", load);
526 }
527
528
529 if (type == IH_TYPE_FLATDT && !fit_image_get_load(fit, image_noffset, &load))
530 printf("%s Load Address: 0x%08lx\n", p, load);
531
532 if ((type == IH_TYPE_KERNEL) || (type == IH_TYPE_STANDALONE) ||
533 (type == IH_TYPE_RAMDISK)) {
534 ret = fit_image_get_entry(fit, image_noffset, &entry);
535 printf("%s Entry Point: ", p);
536 if (ret)
537 printf("unavailable\n");
538 else
539 printf("0x%08lx\n", entry);
540 }
541
542
543 for (ndepth = 0, noffset = fdt_next_node(fit, image_noffset, &ndepth);
544 (noffset >= 0) && (ndepth > 0);
545 noffset = fdt_next_node(fit, noffset, &ndepth)) {
546 if (ndepth == 1) {
547
548 fit_image_print_verification_data(fit, noffset, p);
549 }
550 }
551}
552#else
553void fit_print_contents(const void *fit) { }
554void fit_image_print(const void *fit, int image_noffset, const char *p) { }
555#endif
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570int fit_get_desc(const void *fit, int noffset, char **desc)
571{
572 int len;
573
574 *desc = (char *)fdt_getprop(fit, noffset, FIT_DESC_PROP, &len);
575 if (*desc == NULL) {
576 fit_get_debug(fit, noffset, FIT_DESC_PROP, len);
577 return -1;
578 }
579
580 return 0;
581}
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598int fit_get_timestamp(const void *fit, int noffset, time_t *timestamp)
599{
600 int len;
601 const void *data;
602
603 data = fdt_getprop(fit, noffset, FIT_TIMESTAMP_PROP, &len);
604 if (data == NULL) {
605 fit_get_debug(fit, noffset, FIT_TIMESTAMP_PROP, len);
606 return -1;
607 }
608 if (len != sizeof(uint32_t)) {
609 debug("FIT timestamp with incorrect size of (%u)\n", len);
610 return -2;
611 }
612
613 *timestamp = uimage_to_cpu(*((uint32_t *)data));
614 return 0;
615}
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630int fit_image_get_node(const void *fit, const char *image_uname)
631{
632 int noffset, images_noffset;
633
634 images_noffset = fdt_path_offset(fit, FIT_IMAGES_PATH);
635 if (images_noffset < 0) {
636 debug("Can't find images parent node '%s' (%s)\n",
637 FIT_IMAGES_PATH, fdt_strerror(images_noffset));
638 return images_noffset;
639 }
640
641 noffset = fdt_subnode_offset(fit, images_noffset, image_uname);
642 if (noffset < 0) {
643 debug("Can't get node offset for image unit name: '%s' (%s)\n",
644 image_uname, fdt_strerror(noffset));
645 }
646
647 return noffset;
648}
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664int fit_image_get_os(const void *fit, int noffset, uint8_t *os)
665{
666 int len;
667 const void *data;
668
669
670 data = fdt_getprop(fit, noffset, FIT_OS_PROP, &len);
671 if (data == NULL) {
672 fit_get_debug(fit, noffset, FIT_OS_PROP, len);
673 *os = -1;
674 return -1;
675 }
676
677
678 *os = genimg_get_os_id(data);
679 return 0;
680}
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696int fit_image_get_arch(const void *fit, int noffset, uint8_t *arch)
697{
698 int len;
699 const void *data;
700
701
702 data = fdt_getprop(fit, noffset, FIT_ARCH_PROP, &len);
703 if (data == NULL) {
704 fit_get_debug(fit, noffset, FIT_ARCH_PROP, len);
705 *arch = -1;
706 return -1;
707 }
708
709
710 *arch = genimg_get_arch_id(data);
711 return 0;
712}
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728int fit_image_get_type(const void *fit, int noffset, uint8_t *type)
729{
730 int len;
731 const void *data;
732
733
734 data = fdt_getprop(fit, noffset, FIT_TYPE_PROP, &len);
735 if (data == NULL) {
736 fit_get_debug(fit, noffset, FIT_TYPE_PROP, len);
737 *type = -1;
738 return -1;
739 }
740
741
742 *type = genimg_get_type_id(data);
743 return 0;
744}
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760int fit_image_get_comp(const void *fit, int noffset, uint8_t *comp)
761{
762 int len;
763 const void *data;
764
765
766 data = fdt_getprop(fit, noffset, FIT_COMP_PROP, &len);
767 if (data == NULL) {
768 fit_get_debug(fit, noffset, FIT_COMP_PROP, len);
769 *comp = -1;
770 return -1;
771 }
772
773
774 *comp = genimg_get_comp_id(data);
775 return 0;
776}
777
778static int fit_image_get_address(const void *fit, int noffset, char *name,
779 ulong *load)
780{
781 int len, cell_len;
782 const fdt32_t *cell;
783 uint64_t load64 = 0;
784
785 cell = fdt_getprop(fit, noffset, name, &len);
786 if (cell == NULL) {
787 fit_get_debug(fit, noffset, name, len);
788 return -1;
789 }
790
791 if (len > sizeof(ulong)) {
792 printf("Unsupported %s address size\n", name);
793 return -1;
794 }
795
796 cell_len = len >> 2;
797
798 while (cell_len--) {
799 load64 = (load64 << 32) | uimage_to_cpu(*cell);
800 cell++;
801 }
802 *load = (ulong)load64;
803
804 return 0;
805}
806
807
808
809
810
811
812
813
814
815
816
817
818
819int fit_image_get_load(const void *fit, int noffset, ulong *load)
820{
821 return fit_image_get_address(fit, noffset, FIT_LOAD_PROP, load);
822}
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841int fit_image_get_entry(const void *fit, int noffset, ulong *entry)
842{
843 return fit_image_get_address(fit, noffset, FIT_ENTRY_PROP, entry);
844}
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861int fit_image_get_data(const void *fit, int noffset,
862 const void **data, size_t *size)
863{
864 int len;
865
866 *data = fdt_getprop(fit, noffset, FIT_DATA_PROP, &len);
867 if (*data == NULL) {
868 fit_get_debug(fit, noffset, FIT_DATA_PROP, len);
869 *size = 0;
870 return -1;
871 }
872
873 *size = len;
874 return 0;
875}
876
877
878
879
880
881
882
883
884
885
886
887
888int fit_image_get_data_offset(const void *fit, int noffset, int *data_offset)
889{
890 const fdt32_t *val;
891
892 val = fdt_getprop(fit, noffset, FIT_DATA_OFFSET_PROP, NULL);
893 if (!val)
894 return -ENOENT;
895
896 *data_offset = fdt32_to_cpu(*val);
897
898 return 0;
899}
900
901
902
903
904
905
906
907
908
909
910
911
912int fit_image_get_data_position(const void *fit, int noffset,
913 int *data_position)
914{
915 const fdt32_t *val;
916
917 val = fdt_getprop(fit, noffset, FIT_DATA_POSITION_PROP, NULL);
918 if (!val)
919 return -ENOENT;
920
921 *data_position = fdt32_to_cpu(*val);
922
923 return 0;
924}
925
926
927
928
929
930
931
932
933
934
935
936
937int fit_image_get_data_size(const void *fit, int noffset, int *data_size)
938{
939 const fdt32_t *val;
940
941 val = fdt_getprop(fit, noffset, FIT_DATA_SIZE_PROP, NULL);
942 if (!val)
943 return -ENOENT;
944
945 *data_size = fdt32_to_cpu(*val);
946
947 return 0;
948}
949
950
951
952
953
954
955
956
957
958
959
960
961int fit_image_get_data_size_unciphered(const void *fit, int noffset,
962 size_t *data_size)
963{
964 const fdt32_t *val;
965
966 val = fdt_getprop(fit, noffset, "data-size-unciphered", NULL);
967 if (!val)
968 return -ENOENT;
969
970 *data_size = (size_t)fdt32_to_cpu(*val);
971
972 return 0;
973}
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991int fit_image_get_data_and_size(const void *fit, int noffset,
992 const void **data, size_t *size)
993{
994 bool external_data = false;
995 int offset;
996 int len;
997 int ret;
998
999 if (!fit_image_get_data_position(fit, noffset, &offset)) {
1000 external_data = true;
1001 } else if (!fit_image_get_data_offset(fit, noffset, &offset)) {
1002 external_data = true;
1003
1004
1005
1006
1007
1008 offset += ((fdt_totalsize(fit) + 3) & ~3);
1009 }
1010
1011 if (external_data) {
1012 debug("External Data\n");
1013 ret = fit_image_get_data_size(fit, noffset, &len);
1014 if (!ret) {
1015 *data = fit + offset;
1016 *size = len;
1017 }
1018 } else {
1019 ret = fit_image_get_data(fit, noffset, data, size);
1020 }
1021
1022 return ret;
1023}
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038int fit_image_hash_get_algo(const void *fit, int noffset, char **algo)
1039{
1040 int len;
1041
1042 *algo = (char *)fdt_getprop(fit, noffset, FIT_ALGO_PROP, &len);
1043 if (*algo == NULL) {
1044 fit_get_debug(fit, noffset, FIT_ALGO_PROP, len);
1045 return -1;
1046 }
1047
1048 return 0;
1049}
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066int fit_image_hash_get_value(const void *fit, int noffset, uint8_t **value,
1067 int *value_len)
1068{
1069 int len;
1070
1071 *value = (uint8_t *)fdt_getprop(fit, noffset, FIT_VALUE_PROP, &len);
1072 if (*value == NULL) {
1073 fit_get_debug(fit, noffset, FIT_VALUE_PROP, len);
1074 *value_len = 0;
1075 return -1;
1076 }
1077
1078 *value_len = len;
1079 return 0;
1080}
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096static int fit_image_hash_get_ignore(const void *fit, int noffset, int *ignore)
1097{
1098 int len;
1099 int *value;
1100
1101 value = (int *)fdt_getprop(fit, noffset, FIT_IGNORE_PROP, &len);
1102 if (value == NULL || len != sizeof(int))
1103 *ignore = 0;
1104 else
1105 *ignore = *value;
1106
1107 return 0;
1108}
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124int fit_image_cipher_get_algo(const void *fit, int noffset, char **algo)
1125{
1126 int len;
1127
1128 *algo = (char *)fdt_getprop(fit, noffset, FIT_ALGO_PROP, &len);
1129 if (!*algo) {
1130 fit_get_debug(fit, noffset, FIT_ALGO_PROP, len);
1131 return -1;
1132 }
1133
1134 return 0;
1135}
1136
1137ulong fit_get_end(const void *fit)
1138{
1139 return map_to_sysmem((void *)(fit + fdt_totalsize(fit)));
1140}
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155int fit_set_timestamp(void *fit, int noffset, time_t timestamp)
1156{
1157 uint32_t t;
1158 int ret;
1159
1160 t = cpu_to_uimage(timestamp);
1161 ret = fdt_setprop(fit, noffset, FIT_TIMESTAMP_PROP, &t,
1162 sizeof(uint32_t));
1163 if (ret) {
1164 debug("Can't set '%s' property for '%s' node (%s)\n",
1165 FIT_TIMESTAMP_PROP, fit_get_name(fit, noffset, NULL),
1166 fdt_strerror(ret));
1167 return ret == -FDT_ERR_NOSPACE ? -ENOSPC : -1;
1168 }
1169
1170 return 0;
1171}
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191int calculate_hash(const void *data, int data_len, const char *algo,
1192 uint8_t *value, int *value_len)
1193{
1194 if (IMAGE_ENABLE_CRC32 && strcmp(algo, "crc32") == 0) {
1195 *((uint32_t *)value) = crc32_wd(0, data, data_len,
1196 CHUNKSZ_CRC32);
1197 *((uint32_t *)value) = cpu_to_uimage(*((uint32_t *)value));
1198 *value_len = 4;
1199 } else if (IMAGE_ENABLE_SHA1 && strcmp(algo, "sha1") == 0) {
1200 sha1_csum_wd((unsigned char *)data, data_len,
1201 (unsigned char *)value, CHUNKSZ_SHA1);
1202 *value_len = 20;
1203 } else if (IMAGE_ENABLE_SHA256 && strcmp(algo, "sha256") == 0) {
1204 sha256_csum_wd((unsigned char *)data, data_len,
1205 (unsigned char *)value, CHUNKSZ_SHA256);
1206 *value_len = SHA256_SUM_LEN;
1207 } else if (IMAGE_ENABLE_MD5 && strcmp(algo, "md5") == 0) {
1208 md5_wd((unsigned char *)data, data_len, value, CHUNKSZ_MD5);
1209 *value_len = 16;
1210 } else {
1211 debug("Unsupported hash alogrithm\n");
1212 return -1;
1213 }
1214 return 0;
1215}
1216
1217static int fit_image_check_hash(const void *fit, int noffset, const void *data,
1218 size_t size, char **err_msgp)
1219{
1220 uint8_t value[FIT_MAX_HASH_LEN];
1221 int value_len;
1222 char *algo;
1223 uint8_t *fit_value;
1224 int fit_value_len;
1225 int ignore;
1226
1227 *err_msgp = NULL;
1228
1229 if (fit_image_hash_get_algo(fit, noffset, &algo)) {
1230 *err_msgp = "Can't get hash algo property";
1231 return -1;
1232 }
1233 printf("%s", algo);
1234
1235 if (IMAGE_ENABLE_IGNORE) {
1236 fit_image_hash_get_ignore(fit, noffset, &ignore);
1237 if (ignore) {
1238 printf("-skipped ");
1239 return 0;
1240 }
1241 }
1242
1243 if (fit_image_hash_get_value(fit, noffset, &fit_value,
1244 &fit_value_len)) {
1245 *err_msgp = "Can't get hash value property";
1246 return -1;
1247 }
1248
1249 if (calculate_hash(data, size, algo, value, &value_len)) {
1250 *err_msgp = "Unsupported hash algorithm";
1251 return -1;
1252 }
1253
1254 if (value_len != fit_value_len) {
1255 *err_msgp = "Bad hash value len";
1256 return -1;
1257 } else if (memcmp(value, fit_value, value_len) != 0) {
1258 *err_msgp = "Bad hash value";
1259 return -1;
1260 }
1261
1262 return 0;
1263}
1264
1265int fit_image_verify_with_data(const void *fit, int image_noffset,
1266 const void *data, size_t size)
1267{
1268 int noffset = 0;
1269 char *err_msg = "";
1270 int verify_all = 1;
1271 int ret;
1272
1273
1274 if (IMAGE_ENABLE_VERIFY &&
1275 fit_image_verify_required_sigs(fit, image_noffset, data, size,
1276 gd_fdt_blob(), &verify_all)) {
1277 err_msg = "Unable to verify required signature";
1278 goto error;
1279 }
1280
1281
1282 fdt_for_each_subnode(noffset, fit, image_noffset) {
1283 const char *name = fit_get_name(fit, noffset, NULL);
1284
1285
1286
1287
1288
1289
1290 if (!strncmp(name, FIT_HASH_NODENAME,
1291 strlen(FIT_HASH_NODENAME))) {
1292 if (fit_image_check_hash(fit, noffset, data, size,
1293 &err_msg))
1294 goto error;
1295 puts("+ ");
1296 } else if (IMAGE_ENABLE_VERIFY && verify_all &&
1297 !strncmp(name, FIT_SIG_NODENAME,
1298 strlen(FIT_SIG_NODENAME))) {
1299 ret = fit_image_check_sig(fit, noffset, data,
1300 size, -1, &err_msg);
1301
1302
1303
1304
1305
1306
1307
1308 if (ret)
1309 puts("- ");
1310 else
1311 puts("+ ");
1312 }
1313 }
1314
1315 if (noffset == -FDT_ERR_TRUNCATED || noffset == -FDT_ERR_BADSTRUCTURE) {
1316 err_msg = "Corrupted or truncated tree";
1317 goto error;
1318 }
1319
1320 return 1;
1321
1322error:
1323 printf(" error!\n%s for '%s' hash node in '%s' image node\n",
1324 err_msg, fit_get_name(fit, noffset, NULL),
1325 fit_get_name(fit, image_noffset, NULL));
1326 return 0;
1327}
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342int fit_image_verify(const void *fit, int image_noffset)
1343{
1344 const void *data;
1345 size_t size;
1346 int noffset = 0;
1347 char *err_msg = "";
1348
1349
1350 if (fit_image_get_data_and_size(fit, image_noffset, &data, &size)) {
1351 err_msg = "Can't get image data/size";
1352 printf("error!\n%s for '%s' hash node in '%s' image node\n",
1353 err_msg, fit_get_name(fit, noffset, NULL),
1354 fit_get_name(fit, image_noffset, NULL));
1355 return 0;
1356 }
1357
1358 return fit_image_verify_with_data(fit, image_noffset, data, size);
1359}
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372int fit_all_image_verify(const void *fit)
1373{
1374 int images_noffset;
1375 int noffset;
1376 int ndepth;
1377 int count;
1378
1379
1380 images_noffset = fdt_path_offset(fit, FIT_IMAGES_PATH);
1381 if (images_noffset < 0) {
1382 printf("Can't find images parent node '%s' (%s)\n",
1383 FIT_IMAGES_PATH, fdt_strerror(images_noffset));
1384 return 0;
1385 }
1386
1387
1388 printf("## Checking hash(es) for FIT Image at %08lx ...\n",
1389 (ulong)fit);
1390 for (ndepth = 0, count = 0,
1391 noffset = fdt_next_node(fit, images_noffset, &ndepth);
1392 (noffset >= 0) && (ndepth > 0);
1393 noffset = fdt_next_node(fit, noffset, &ndepth)) {
1394 if (ndepth == 1) {
1395
1396
1397
1398
1399 printf(" Hash(es) for Image %u (%s): ", count,
1400 fit_get_name(fit, noffset, NULL));
1401 count++;
1402
1403 if (!fit_image_verify(fit, noffset))
1404 return 0;
1405 printf("\n");
1406 }
1407 }
1408 return 1;
1409}
1410
1411#ifdef CONFIG_FIT_CIPHER
1412static int fit_image_uncipher(const void *fit, int image_noffset,
1413 void **data, size_t *size)
1414{
1415 int cipher_noffset, ret;
1416 void *dst;
1417 size_t size_dst;
1418
1419 cipher_noffset = fdt_subnode_offset(fit, image_noffset,
1420 FIT_CIPHER_NODENAME);
1421 if (cipher_noffset < 0)
1422 return 0;
1423
1424 ret = fit_image_decrypt_data(fit, image_noffset, cipher_noffset,
1425 *data, *size, &dst, &size_dst);
1426 if (ret)
1427 goto out;
1428
1429 *data = dst;
1430 *size = size_dst;
1431
1432 out:
1433 return ret;
1434}
1435#endif
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450int fit_image_check_os(const void *fit, int noffset, uint8_t os)
1451{
1452 uint8_t image_os;
1453
1454 if (fit_image_get_os(fit, noffset, &image_os))
1455 return 0;
1456 return (os == image_os);
1457}
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472int fit_image_check_arch(const void *fit, int noffset, uint8_t arch)
1473{
1474 uint8_t image_arch;
1475 int aarch32_support = 0;
1476
1477#ifdef CONFIG_ARM64_SUPPORT_AARCH32
1478 aarch32_support = 1;
1479#endif
1480
1481 if (fit_image_get_arch(fit, noffset, &image_arch))
1482 return 0;
1483 return (arch == image_arch) ||
1484 (arch == IH_ARCH_I386 && image_arch == IH_ARCH_X86_64) ||
1485 (arch == IH_ARCH_ARM64 && image_arch == IH_ARCH_ARM &&
1486 aarch32_support);
1487}
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502int fit_image_check_type(const void *fit, int noffset, uint8_t type)
1503{
1504 uint8_t image_type;
1505
1506 if (fit_image_get_type(fit, noffset, &image_type))
1507 return 0;
1508 return (type == image_type);
1509}
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525int fit_image_check_comp(const void *fit, int noffset, uint8_t comp)
1526{
1527 uint8_t image_comp;
1528
1529 if (fit_image_get_comp(fit, noffset, &image_comp))
1530 return 0;
1531 return (comp == image_comp);
1532}
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545int fit_check_format(const void *fit)
1546{
1547
1548 if (fdt_getprop(fit, 0, FIT_DESC_PROP, NULL) == NULL) {
1549 debug("Wrong FIT format: no description\n");
1550 return 0;
1551 }
1552
1553 if (IMAGE_ENABLE_TIMESTAMP) {
1554
1555 if (fdt_getprop(fit, 0, FIT_TIMESTAMP_PROP, NULL) == NULL) {
1556 debug("Wrong FIT format: no timestamp\n");
1557 return 0;
1558 }
1559 }
1560
1561
1562 if (fdt_path_offset(fit, FIT_IMAGES_PATH) < 0) {
1563 debug("Wrong FIT format: no images parent node\n");
1564 return 0;
1565 }
1566
1567 return 1;
1568}
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614int fit_conf_find_compat(const void *fit, const void *fdt)
1615{
1616 int ndepth = 0;
1617 int noffset, confs_noffset, images_noffset;
1618 const void *fdt_compat;
1619 int fdt_compat_len;
1620 int best_match_offset = 0;
1621 int best_match_pos = 0;
1622
1623 confs_noffset = fdt_path_offset(fit, FIT_CONFS_PATH);
1624 images_noffset = fdt_path_offset(fit, FIT_IMAGES_PATH);
1625 if (confs_noffset < 0 || images_noffset < 0) {
1626 debug("Can't find configurations or images nodes.\n");
1627 return -1;
1628 }
1629
1630 fdt_compat = fdt_getprop(fdt, 0, "compatible", &fdt_compat_len);
1631 if (!fdt_compat) {
1632 debug("Fdt for comparison has no \"compatible\" property.\n");
1633 return -1;
1634 }
1635
1636
1637
1638
1639 for (noffset = fdt_next_node(fit, confs_noffset, &ndepth);
1640 (noffset >= 0) && (ndepth > 0);
1641 noffset = fdt_next_node(fit, noffset, &ndepth)) {
1642 const void *fdt;
1643 const char *kfdt_name;
1644 int kfdt_noffset, compat_noffset;
1645 const char *cur_fdt_compat;
1646 int len;
1647 size_t sz;
1648 int i;
1649
1650 if (ndepth > 1)
1651 continue;
1652
1653
1654 if (fdt_getprop(fit, noffset, "compatible", NULL)) {
1655 fdt = fit;
1656 compat_noffset = noffset;
1657 } else {
1658 kfdt_name = fdt_getprop(fit, noffset, "fdt", &len);
1659 if (!kfdt_name) {
1660 debug("No fdt property found.\n");
1661 continue;
1662 }
1663 kfdt_noffset = fdt_subnode_offset(fit, images_noffset,
1664 kfdt_name);
1665 if (kfdt_noffset < 0) {
1666 debug("No image node named \"%s\" found.\n",
1667 kfdt_name);
1668 continue;
1669 }
1670
1671 if (!fit_image_check_comp(fit, kfdt_noffset,
1672 IH_COMP_NONE)) {
1673 debug("Can't extract compat from \"%s\" "
1674 "(compressed)\n", kfdt_name);
1675 continue;
1676 }
1677
1678
1679 if (fit_image_get_data(fit, kfdt_noffset, &fdt, &sz)) {
1680 debug("Failed to get fdt \"%s\".\n", kfdt_name);
1681 continue;
1682 }
1683
1684 compat_noffset = 0;
1685 }
1686
1687 len = fdt_compat_len;
1688 cur_fdt_compat = fdt_compat;
1689
1690
1691
1692
1693 for (i = 0; len > 0 &&
1694 (!best_match_offset || best_match_pos > i); i++) {
1695 int cur_len = strlen(cur_fdt_compat) + 1;
1696
1697 if (!fdt_node_check_compatible(fdt, compat_noffset,
1698 cur_fdt_compat)) {
1699 best_match_offset = noffset;
1700 best_match_pos = i;
1701 break;
1702 }
1703 len -= cur_len;
1704 cur_fdt_compat += cur_len;
1705 }
1706 }
1707 if (!best_match_offset) {
1708 debug("No match found.\n");
1709 return -1;
1710 }
1711
1712 return best_match_offset;
1713}
1714
1715int fit_conf_get_node(const void *fit, const char *conf_uname)
1716{
1717 int noffset, confs_noffset;
1718 int len;
1719 const char *s;
1720 char *conf_uname_copy = NULL;
1721
1722 confs_noffset = fdt_path_offset(fit, FIT_CONFS_PATH);
1723 if (confs_noffset < 0) {
1724 debug("Can't find configurations parent node '%s' (%s)\n",
1725 FIT_CONFS_PATH, fdt_strerror(confs_noffset));
1726 return confs_noffset;
1727 }
1728
1729 if (conf_uname == NULL) {
1730
1731 debug("No configuration specified, trying default...\n");
1732 conf_uname = (char *)fdt_getprop(fit, confs_noffset,
1733 FIT_DEFAULT_PROP, &len);
1734 if (conf_uname == NULL) {
1735 fit_get_debug(fit, confs_noffset, FIT_DEFAULT_PROP,
1736 len);
1737 return len;
1738 }
1739 debug("Found default configuration: '%s'\n", conf_uname);
1740 }
1741
1742 s = strchr(conf_uname, '#');
1743 if (s) {
1744 len = s - conf_uname;
1745 conf_uname_copy = malloc(len + 1);
1746 if (!conf_uname_copy) {
1747 debug("Can't allocate uname copy: '%s'\n",
1748 conf_uname);
1749 return -ENOMEM;
1750 }
1751 memcpy(conf_uname_copy, conf_uname, len);
1752 conf_uname_copy[len] = '\0';
1753 conf_uname = conf_uname_copy;
1754 }
1755
1756 noffset = fdt_subnode_offset(fit, confs_noffset, conf_uname);
1757 if (noffset < 0) {
1758 debug("Can't get node offset for configuration unit name: '%s' (%s)\n",
1759 conf_uname, fdt_strerror(noffset));
1760 }
1761
1762 if (conf_uname_copy)
1763 free(conf_uname_copy);
1764
1765 return noffset;
1766}
1767
1768int fit_conf_get_prop_node_count(const void *fit, int noffset,
1769 const char *prop_name)
1770{
1771 return fdt_stringlist_count(fit, noffset, prop_name);
1772}
1773
1774int fit_conf_get_prop_node_index(const void *fit, int noffset,
1775 const char *prop_name, int index)
1776{
1777 const char *uname;
1778 int len;
1779
1780
1781 uname = fdt_stringlist_get(fit, noffset, prop_name, index, &len);
1782 if (uname == NULL)
1783 return len;
1784
1785 return fit_image_get_node(fit, uname);
1786}
1787
1788int fit_conf_get_prop_node(const void *fit, int noffset,
1789 const char *prop_name)
1790{
1791 return fit_conf_get_prop_node_index(fit, noffset, prop_name, 0);
1792}
1793
1794static int fit_image_select(const void *fit, int rd_noffset, int verify)
1795{
1796 fit_image_print(fit, rd_noffset, " ");
1797
1798 if (verify) {
1799 puts(" Verifying Hash Integrity ... ");
1800 if (!fit_image_verify(fit, rd_noffset)) {
1801 puts("Bad Data Hash\n");
1802 return -EACCES;
1803 }
1804 puts("OK\n");
1805 }
1806
1807 return 0;
1808}
1809
1810int fit_get_node_from_config(bootm_headers_t *images, const char *prop_name,
1811 ulong addr)
1812{
1813 int cfg_noffset;
1814 void *fit_hdr;
1815 int noffset;
1816
1817 debug("* %s: using config '%s' from image at 0x%08lx\n",
1818 prop_name, images->fit_uname_cfg, addr);
1819
1820
1821 fit_hdr = map_sysmem(addr, 0);
1822 cfg_noffset = fit_conf_get_node(fit_hdr, images->fit_uname_cfg);
1823 if (cfg_noffset < 0) {
1824 debug("* %s: no such config\n", prop_name);
1825 return -EINVAL;
1826 }
1827
1828 noffset = fit_conf_get_prop_node(fit_hdr, cfg_noffset, prop_name);
1829 if (noffset < 0) {
1830 debug("* %s: no '%s' in config\n", prop_name, prop_name);
1831 return -ENOENT;
1832 }
1833
1834 return noffset;
1835}
1836
1837
1838
1839
1840
1841
1842
1843static const char *fit_get_image_type_property(int type)
1844{
1845
1846
1847
1848
1849
1850 switch (type) {
1851 case IH_TYPE_FLATDT:
1852 return FIT_FDT_PROP;
1853 case IH_TYPE_KERNEL:
1854 return FIT_KERNEL_PROP;
1855 case IH_TYPE_RAMDISK:
1856 return FIT_RAMDISK_PROP;
1857 case IH_TYPE_X86_SETUP:
1858 return FIT_SETUP_PROP;
1859 case IH_TYPE_LOADABLE:
1860 return FIT_LOADABLE_PROP;
1861 case IH_TYPE_FPGA:
1862 return FIT_FPGA_PROP;
1863 case IH_TYPE_STANDALONE:
1864 return FIT_STANDALONE_PROP;
1865 }
1866
1867 return "unknown";
1868}
1869
1870int fit_image_load(bootm_headers_t *images, ulong addr,
1871 const char **fit_unamep, const char **fit_uname_configp,
1872 int arch, int image_type, int bootstage_id,
1873 enum fit_load_op load_op, ulong *datap, ulong *lenp)
1874{
1875 int cfg_noffset, noffset;
1876 const char *fit_uname;
1877 const char *fit_uname_config;
1878 const char *fit_base_uname_config;
1879 const void *fit;
1880 void *buf;
1881 void *loadbuf;
1882 size_t size;
1883 int type_ok, os_ok;
1884 ulong load, load_end, data, len;
1885 uint8_t os, comp;
1886#ifndef USE_HOSTCC
1887 uint8_t os_arch;
1888#endif
1889 const char *prop_name;
1890 int ret;
1891
1892 fit = map_sysmem(addr, 0);
1893 fit_uname = fit_unamep ? *fit_unamep : NULL;
1894 fit_uname_config = fit_uname_configp ? *fit_uname_configp : NULL;
1895 fit_base_uname_config = NULL;
1896 prop_name = fit_get_image_type_property(image_type);
1897 printf("## Loading %s from FIT Image at %08lx ...\n", prop_name, addr);
1898
1899 bootstage_mark(bootstage_id + BOOTSTAGE_SUB_FORMAT);
1900 if (!fit_check_format(fit)) {
1901 printf("Bad FIT %s image format!\n", prop_name);
1902 bootstage_error(bootstage_id + BOOTSTAGE_SUB_FORMAT);
1903 return -ENOEXEC;
1904 }
1905 bootstage_mark(bootstage_id + BOOTSTAGE_SUB_FORMAT_OK);
1906 if (fit_uname) {
1907
1908 bootstage_mark(bootstage_id + BOOTSTAGE_SUB_UNIT_NAME);
1909 noffset = fit_image_get_node(fit, fit_uname);
1910 } else {
1911
1912
1913
1914
1915
1916 bootstage_mark(bootstage_id + BOOTSTAGE_SUB_NO_UNIT_NAME);
1917 if (IMAGE_ENABLE_BEST_MATCH && !fit_uname_config) {
1918 cfg_noffset = fit_conf_find_compat(fit, gd_fdt_blob());
1919 } else {
1920 cfg_noffset = fit_conf_get_node(fit,
1921 fit_uname_config);
1922 }
1923 if (cfg_noffset < 0) {
1924 puts("Could not find configuration node\n");
1925 bootstage_error(bootstage_id +
1926 BOOTSTAGE_SUB_NO_UNIT_NAME);
1927 return -ENOENT;
1928 }
1929
1930 fit_base_uname_config = fdt_get_name(fit, cfg_noffset, NULL);
1931 printf(" Using '%s' configuration\n", fit_base_uname_config);
1932
1933 if (image_type == IH_TYPE_KERNEL)
1934 images->fit_uname_cfg = fit_base_uname_config;
1935
1936 if (IMAGE_ENABLE_VERIFY && images->verify) {
1937 puts(" Verifying Hash Integrity ... ");
1938 if (fit_config_verify(fit, cfg_noffset)) {
1939 puts("Bad Data Hash\n");
1940 bootstage_error(bootstage_id +
1941 BOOTSTAGE_SUB_HASH);
1942 return -EACCES;
1943 }
1944 puts("OK\n");
1945 }
1946
1947 bootstage_mark(BOOTSTAGE_ID_FIT_CONFIG);
1948
1949 noffset = fit_conf_get_prop_node(fit, cfg_noffset,
1950 prop_name);
1951 fit_uname = fit_get_name(fit, noffset, NULL);
1952 }
1953 if (noffset < 0) {
1954 printf("Could not find subimage node type '%s'\n", prop_name);
1955 bootstage_error(bootstage_id + BOOTSTAGE_SUB_SUBNODE);
1956 return -ENOENT;
1957 }
1958
1959 printf(" Trying '%s' %s subimage\n", fit_uname, prop_name);
1960
1961 ret = fit_image_select(fit, noffset, images->verify);
1962 if (ret) {
1963 bootstage_error(bootstage_id + BOOTSTAGE_SUB_HASH);
1964 return ret;
1965 }
1966
1967 bootstage_mark(bootstage_id + BOOTSTAGE_SUB_CHECK_ARCH);
1968#if !defined(USE_HOSTCC) && !defined(CONFIG_SANDBOX)
1969 if (!fit_image_check_target_arch(fit, noffset)) {
1970 puts("Unsupported Architecture\n");
1971 bootstage_error(bootstage_id + BOOTSTAGE_SUB_CHECK_ARCH);
1972 return -ENOEXEC;
1973 }
1974#endif
1975
1976#ifndef USE_HOSTCC
1977 fit_image_get_arch(fit, noffset, &os_arch);
1978 images->os.arch = os_arch;
1979#endif
1980
1981 bootstage_mark(bootstage_id + BOOTSTAGE_SUB_CHECK_ALL);
1982 type_ok = fit_image_check_type(fit, noffset, image_type) ||
1983 fit_image_check_type(fit, noffset, IH_TYPE_FIRMWARE) ||
1984 (image_type == IH_TYPE_KERNEL &&
1985 fit_image_check_type(fit, noffset, IH_TYPE_KERNEL_NOLOAD));
1986
1987 os_ok = image_type == IH_TYPE_FLATDT ||
1988 image_type == IH_TYPE_FPGA ||
1989 fit_image_check_os(fit, noffset, IH_OS_LINUX) ||
1990 fit_image_check_os(fit, noffset, IH_OS_U_BOOT) ||
1991 fit_image_check_os(fit, noffset, IH_OS_OPENRTOS) ||
1992 fit_image_check_os(fit, noffset, IH_OS_EFI) ||
1993 fit_image_check_os(fit, noffset, IH_OS_VXWORKS);
1994
1995
1996
1997
1998
1999
2000 if ((!type_ok || !os_ok) && image_type != IH_TYPE_LOADABLE) {
2001 fit_image_get_os(fit, noffset, &os);
2002 printf("No %s %s %s Image\n",
2003 genimg_get_os_name(os),
2004 genimg_get_arch_name(arch),
2005 genimg_get_type_name(image_type));
2006 bootstage_error(bootstage_id + BOOTSTAGE_SUB_CHECK_ALL);
2007 return -EIO;
2008 }
2009
2010 bootstage_mark(bootstage_id + BOOTSTAGE_SUB_CHECK_ALL_OK);
2011
2012
2013 if (fit_image_get_data_and_size(fit, noffset,
2014 (const void **)&buf, &size)) {
2015 printf("Could not find %s subimage data!\n", prop_name);
2016 bootstage_error(bootstage_id + BOOTSTAGE_SUB_GET_DATA);
2017 return -ENOENT;
2018 }
2019
2020#ifdef CONFIG_FIT_CIPHER
2021
2022 if (IMAGE_ENABLE_DECRYPT) {
2023 puts(" Decrypting Data ... ");
2024 if (fit_image_uncipher(fit, noffset, &buf, &size)) {
2025 puts("Error\n");
2026 return -EACCES;
2027 }
2028 puts("OK\n");
2029 }
2030#endif
2031
2032#if !defined(USE_HOSTCC) && defined(CONFIG_FIT_IMAGE_POST_PROCESS)
2033
2034 board_fit_image_post_process(&buf, &size);
2035#endif
2036
2037 len = (ulong)size;
2038
2039 bootstage_mark(bootstage_id + BOOTSTAGE_SUB_GET_DATA_OK);
2040
2041 data = map_to_sysmem(buf);
2042 load = data;
2043 if (load_op == FIT_LOAD_IGNORED) {
2044
2045 } else if (fit_image_get_load(fit, noffset, &load)) {
2046 if (load_op == FIT_LOAD_REQUIRED) {
2047 printf("Can't get %s subimage load address!\n",
2048 prop_name);
2049 bootstage_error(bootstage_id + BOOTSTAGE_SUB_LOAD);
2050 return -EBADF;
2051 }
2052 } else if (load_op != FIT_LOAD_OPTIONAL_NON_ZERO || load) {
2053 ulong image_start, image_end;
2054
2055
2056
2057
2058
2059 image_start = addr;
2060 image_end = addr + fit_get_size(fit);
2061
2062 load_end = load + len;
2063 if (image_type != IH_TYPE_KERNEL &&
2064 load < image_end && load_end > image_start) {
2065 printf("Error: %s overwritten\n", prop_name);
2066 return -EXDEV;
2067 }
2068
2069 printf(" Loading %s from 0x%08lx to 0x%08lx\n",
2070 prop_name, data, load);
2071 } else {
2072 load = data;
2073 }
2074
2075 comp = IH_COMP_NONE;
2076 loadbuf = buf;
2077
2078 if (!fit_image_get_comp(fit, noffset, &comp) &&
2079 comp != IH_COMP_NONE &&
2080 !(image_type == IH_TYPE_KERNEL ||
2081 image_type == IH_TYPE_KERNEL_NOLOAD ||
2082 image_type == IH_TYPE_RAMDISK)) {
2083 ulong max_decomp_len = len * 20;
2084 if (load == data) {
2085 loadbuf = malloc(max_decomp_len);
2086 load = map_to_sysmem(loadbuf);
2087 } else {
2088 loadbuf = map_sysmem(load, max_decomp_len);
2089 }
2090 if (image_decomp(comp, load, data, image_type,
2091 loadbuf, buf, len, max_decomp_len, &load_end)) {
2092 printf("Error decompressing %s\n", prop_name);
2093
2094 return -ENOEXEC;
2095 }
2096 len = load_end - load;
2097 } else if (load != data) {
2098 loadbuf = map_sysmem(load, len);
2099 memcpy(loadbuf, buf, len);
2100 }
2101
2102 if (image_type == IH_TYPE_RAMDISK && comp != IH_COMP_NONE)
2103 puts("WARNING: 'compression' nodes for ramdisks are deprecated,"
2104 " please fix your .its file!\n");
2105
2106
2107 if (image_type == IH_TYPE_FLATDT && fdt_check_header(loadbuf)) {
2108 puts("Subimage data is not a FDT");
2109 return -ENOEXEC;
2110 }
2111
2112 bootstage_mark(bootstage_id + BOOTSTAGE_SUB_LOAD);
2113
2114 *datap = load;
2115 *lenp = len;
2116 if (fit_unamep)
2117 *fit_unamep = (char *)fit_uname;
2118 if (fit_uname_configp)
2119 *fit_uname_configp = (char *)(fit_uname_config ? :
2120 fit_base_uname_config);
2121
2122 return noffset;
2123}
2124
2125int boot_get_setup_fit(bootm_headers_t *images, uint8_t arch,
2126 ulong *setup_start, ulong *setup_len)
2127{
2128 int noffset;
2129 ulong addr;
2130 ulong len;
2131 int ret;
2132
2133 addr = map_to_sysmem(images->fit_hdr_os);
2134 noffset = fit_get_node_from_config(images, FIT_SETUP_PROP, addr);
2135 if (noffset < 0)
2136 return noffset;
2137
2138 ret = fit_image_load(images, addr, NULL, NULL, arch,
2139 IH_TYPE_X86_SETUP, BOOTSTAGE_ID_FIT_SETUP_START,
2140 FIT_LOAD_REQUIRED, setup_start, &len);
2141
2142 return ret;
2143}
2144
2145#ifndef USE_HOSTCC
2146int boot_get_fdt_fit(bootm_headers_t *images, ulong addr,
2147 const char **fit_unamep, const char **fit_uname_configp,
2148 int arch, ulong *datap, ulong *lenp)
2149{
2150 int fdt_noffset, cfg_noffset, count;
2151 const void *fit;
2152 const char *fit_uname = NULL;
2153 const char *fit_uname_config = NULL;
2154 char *fit_uname_config_copy = NULL;
2155 char *next_config = NULL;
2156 ulong load, len;
2157#ifdef CONFIG_OF_LIBFDT_OVERLAY
2158 ulong image_start, image_end;
2159 ulong ovload, ovlen;
2160 const char *uconfig;
2161 const char *uname;
2162 void *base, *ov;
2163 int i, err, noffset, ov_noffset;
2164#endif
2165
2166 fit_uname = fit_unamep ? *fit_unamep : NULL;
2167
2168 if (fit_uname_configp && *fit_uname_configp) {
2169 fit_uname_config_copy = strdup(*fit_uname_configp);
2170 if (!fit_uname_config_copy)
2171 return -ENOMEM;
2172
2173 next_config = strchr(fit_uname_config_copy, '#');
2174 if (next_config)
2175 *next_config++ = '\0';
2176 if (next_config - 1 > fit_uname_config_copy)
2177 fit_uname_config = fit_uname_config_copy;
2178 }
2179
2180 fdt_noffset = fit_image_load(images,
2181 addr, &fit_uname, &fit_uname_config,
2182 arch, IH_TYPE_FLATDT,
2183 BOOTSTAGE_ID_FIT_FDT_START,
2184 FIT_LOAD_OPTIONAL, &load, &len);
2185
2186 if (fdt_noffset < 0)
2187 goto out;
2188
2189 debug("fit_uname=%s, fit_uname_config=%s\n",
2190 fit_uname ? fit_uname : "<NULL>",
2191 fit_uname_config ? fit_uname_config : "<NULL>");
2192
2193 fit = map_sysmem(addr, 0);
2194
2195 cfg_noffset = fit_conf_get_node(fit, fit_uname_config);
2196
2197
2198 count = fit_conf_get_prop_node_count(fit, cfg_noffset, FIT_FDT_PROP);
2199 if (count <= 1 && !next_config)
2200 goto out;
2201
2202
2203
2204#ifdef CONFIG_OF_LIBFDT_OVERLAY
2205 image_start = addr;
2206 image_end = addr + fit_get_size(fit);
2207
2208 if (load >= image_start && load < image_end) {
2209
2210 printf("Overlayed FDT requires relocation\n");
2211 fdt_noffset = -EBADF;
2212 goto out;
2213 }
2214
2215 base = map_sysmem(load, len);
2216
2217
2218 for (i = 1; ; i++) {
2219 if (i < count) {
2220 noffset = fit_conf_get_prop_node_index(fit, cfg_noffset,
2221 FIT_FDT_PROP, i);
2222 uname = fit_get_name(fit, noffset, NULL);
2223 uconfig = NULL;
2224 } else {
2225 if (!next_config)
2226 break;
2227 uconfig = next_config;
2228 next_config = strchr(next_config, '#');
2229 if (next_config)
2230 *next_config++ = '\0';
2231 uname = NULL;
2232
2233
2234
2235
2236
2237
2238
2239 cfg_noffset = fit_conf_get_node(fit, uconfig);
2240
2241 i = 0;
2242 count = fit_conf_get_prop_node_count(fit, cfg_noffset,
2243 FIT_FDT_PROP);
2244 }
2245
2246 debug("%d: using uname=%s uconfig=%s\n", i, uname, uconfig);
2247
2248 ov_noffset = fit_image_load(images,
2249 addr, &uname, &uconfig,
2250 arch, IH_TYPE_FLATDT,
2251 BOOTSTAGE_ID_FIT_FDT_START,
2252 FIT_LOAD_REQUIRED, &ovload, &ovlen);
2253 if (ov_noffset < 0) {
2254 printf("load of %s failed\n", uname);
2255 continue;
2256 }
2257 debug("%s loaded at 0x%08lx len=0x%08lx\n",
2258 uname, ovload, ovlen);
2259 ov = map_sysmem(ovload, ovlen);
2260
2261 base = map_sysmem(load, len + ovlen);
2262 err = fdt_open_into(base, base, len + ovlen);
2263 if (err < 0) {
2264 printf("failed on fdt_open_into\n");
2265 fdt_noffset = err;
2266 goto out;
2267 }
2268
2269 err = fdt_overlay_apply_verbose(base, ov);
2270 if (err < 0) {
2271 fdt_noffset = err;
2272 goto out;
2273 }
2274 fdt_pack(base);
2275 len = fdt_totalsize(base);
2276 }
2277#else
2278 printf("config with overlays but CONFIG_OF_LIBFDT_OVERLAY not set\n");
2279 fdt_noffset = -EBADF;
2280#endif
2281
2282out:
2283 if (datap)
2284 *datap = load;
2285 if (lenp)
2286 *lenp = len;
2287 if (fit_unamep)
2288 *fit_unamep = fit_uname;
2289 if (fit_uname_configp)
2290 *fit_uname_configp = fit_uname_config;
2291
2292 if (fit_uname_config_copy)
2293 free(fit_uname_config_copy);
2294 return fdt_noffset;
2295}
2296#endif
2297