summaryrefslogtreecommitdiff
path: root/recovery/check/dtbcheck.cpp (plain)
blob: 9d13beee52c1754393b97821a8e6cd133143dd76
1#include <errno.h>
2#include <ctype.h>
3#include <stdio.h>
4#include <stdlib.h>
5#include <fcntl.h>
6#include <unistd.h>
7#include <string.h>
8#include <sys/stat.h>
9#include <sys/types.h>
10#include <ziparchive/zip_archive.h>
11#include "dtbcheck.h"
12
13
14extern "C" {
15#include "fdt/libfdt.h"
16}
17
18
19
20#define MAX_LEVEL 32 /* how deeply nested we will go */
21#define CONFIG_CMD_FDT_MAX_DUMP 64
22
23#define DT_HEADER_MAGIC 0xedfe0dd0 /*header of dtb file*/
24#define AML_DT_HEADER_MAGIC 0x5f4c4d41 /*"AML_", multi dtbs supported*/
25
26#define AML_DT_ID_VARI_TOTAL 3 //Total 3 strings
27/*Latest version: v2*/
28#define AML_DT_VERSION_OFFSET 4
29#define AML_DT_TOTAL_DTB_OFFSET 8
30#define AML_DT_FIRST_DTB_OFFSET 12
31
32#define AML_DT_DTB_DT_INFO_OFFSET 0
33
34#define ENV_DTB "aml_dt"
35#define CMDLINE "/proc/cmdline"
36#define STORE_DEVICE "/sys/class/aml_store/store_device"
37#define DEVICE_NAND 2
38#define DEVICE_EMMC 1
39
40extern int IsPlatformEncrypted(void);
41
42extern int DtbImgEncrypted(
43 const char *imageName,
44 const unsigned char *imageBuffer,
45 const int imageSize,
46 const char *flag,
47 unsigned char *encryptedbuf);
48
49struct fdt_header *working_fdt;
50
51static Dtb_Partition_S dtb_zip[24];
52static Dtb_Partition_S dtb_dev[24];
53
54unsigned int recovery_size1 = 32*1024*1024; //default value 32M
55
56static int isEncrypted = 0;
57
58struct Dtb_header {
59 unsigned int dt_magic;
60 unsigned int dt_tool_version;
61 unsigned int dt_total;
62 char data[0];
63};
64
65
66/****************************************************************************/
67
68
69unsigned int
70STRTOU32(unsigned char* p){
71 return (p[3]<<24)|(p[2]<<16)|(p[1]<<8)|p[0];
72}
73
74int GetDeviceType()
75{
76 FILE *p = NULL;
77 int len = 0;
78 char buffer[32] = {0};
79 int type = 0;
80
81 p = fopen(STORE_DEVICE, "r");
82 if (p == NULL) {
83 printf("open failed!\n");
84 return -1;
85 }
86
87 len = fread(buffer, 1, 32, p);
88 if (len <= 0) {
89 printf("fread failed!\n");
90 fclose(p);
91 return -1;
92 }
93 fclose(p);
94
95 printf("buffer:%s\n",buffer);
96
97 type = atoi(buffer);
98 printf("type=%d\n",type);
99 return type;
100}
101
102signed int
103GetDtbId(char *pdt){
104 FILE *p = NULL;
105 int len = 0;
106 char buffer[1024] = {0};
107
108 if (pdt == NULL) {
109 printf("param error!\n");
110 return -1;
111 }
112
113 p = fopen(CMDLINE, "r");
114 if (p == NULL) {
115 printf("open failed!\n");
116 return -1;
117 }
118
119 len = fread(buffer, 1, 1023, p);
120 if (len <= 0) {
121 printf("fread failed!\n");
122 fclose(p);
123 return -1;
124 }
125 fclose(p);
126
127 char *paddr=strstr(buffer, ENV_DTB);
128 if (paddr == NULL) {
129 printf("not find env:aml_dt !\n");
130 return -1;
131 }
132
133 paddr = strtok(paddr, " ");
134
135 paddr = paddr+strlen(ENV_DTB)+1;
136 //printf("cmdline, aml_dt=%s\n", paddr);
137
138 strcpy(pdt, paddr);
139 return 0;
140}
141
142
143/*
144 * Heuristic to guess if this is a string or concatenated strings.
145 */
146
147static int
148is_printable_string(const void *data, int len){
149 const char *s = (char *)data;
150
151 /* zero length is not */
152 if (len == 0)
153 return 0;
154
155 /* must terminate with zero or '\n' */
156 if (s[len - 1] != '\0' && s[len - 1] != '\n')
157 return 0;
158
159 /* printable or a null byte (concatenated strings) */
160 while (((*s == '\0') || isprint(*s) || isspace(*s)) && (len > 0)) {
161 /*
162 * If we see a null, there are three possibilities:
163 * 1) If len == 1, it is the end of the string, printable
164 * 2) Next character also a null, not printable.
165 * 3) Next character not a null, continue to check.
166 */
167 if (s[0] == '\0') {
168 if (len == 1)
169 return 1;
170 if (s[1] == '\0')
171 return 0;
172 }
173 s++;
174 len--;
175 }
176
177 /* Not the null termination, or not done yet: not printable */
178 if (*s != '\0' || (len != 0))
179 return 0;
180
181 return 1;
182}
183
184
185
186/*
187 * Print the property in the best format, a heuristic guess. Print as
188 * a string, concatenated strings, a byte, word, double word, or (if all
189 * else fails) it is printed as a stream of bytes.
190 */
191static void print_data(const void *data, int len, int *index, int flag)
192{
193 int j;
194
195 char *pd = (char *)data;
196
197 /* no data, don't print */
198 if (len == 0)
199 return;
200
201 /*
202 * It is a string, but it may have multiple strings (embedded '\0's).
203 */
204 if (is_printable_string(pd, len)) {
205 j = 0;
206 while (j < len) {
207 if (flag == 0) {
208 strcpy(dtb_zip[*index].partition_name, pd);
209 } else {
210 strcpy(dtb_dev[*index].partition_name, pd);
211 }
212 j += strlen(pd) + 1;
213 pd += strlen(pd) + 1;
214 }
215 return;
216 }
217
218 if ((len %4) == 0) {
219 if (len > CONFIG_CMD_FDT_MAX_DUMP)
220 ;
221 else if (len == 8){
222 const __be32 *p;
223 p = (__be32 *)pd;
224 if (flag == 0)
225 {
226 dtb_zip[*index].partition_size = fdt32_to_cpu(p[1]) - fdt32_to_cpu(p[0]);
227 }
228 else
229 {
230 dtb_dev[*index].partition_size = fdt32_to_cpu(p[1]) - fdt32_to_cpu(p[0]);
231 }
232 (*index)++;
233 }
234 } else { /* anything else... hexdump */
235 if (len > CONFIG_CMD_FDT_MAX_DUMP)
236 ;
237 else {
238 const unsigned char *s;
239 }
240 }
241}
242
243
244int
245GetPartitionFromDtb(const char *pathp, int depth, int *partition_num, int flag){
246 static char tabs[MAX_LEVEL+1] =
247 "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t"
248 "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t";
249 const void *nodep; /* property node pointer */
250 int nodeoffset; /* node offset from libfdt */
251 int index = 0;
252 int nextoffset; /* next node offset from libfdt */
253 uint32_t tag; /* tag */
254 int len; /* length of the property */
255 int level = 0; /* keep track of nesting level */
256 const struct fdt_property *fdt_prop;
257
258 nodeoffset = fdt_path_offset (working_fdt, pathp);
259 if (nodeoffset < 0) {
260 /*
261 * Not found or something else bad happened.
262 */
263 printf ("libfdt fdt_path_offset() returned %s\n",
264 fdt_strerror(nodeoffset));
265 return 1;
266 }
267
268
269 /*
270 * The user passed in a node path and no property,
271 * print the node and all subnodes.
272 */
273 while (level >= 0) {
274 tag = fdt_next_tag(working_fdt, nodeoffset, &nextoffset);
275 switch (tag) {
276 case FDT_BEGIN_NODE:
277 pathp = fdt_get_name(working_fdt, nodeoffset, NULL);
278 if (level <= depth) {
279 if (pathp == NULL)
280 pathp = "/* NULL pointer error */";
281 if (*pathp == '\0')
282 pathp = "/"; /* root is nameless */
283 }
284 level++;
285 if (level >= MAX_LEVEL) {
286 printf("Nested too deep, aborting.\n");
287 return 1;
288 }
289 break;
290 case FDT_END_NODE:
291 level--;
292 if (level <= depth)
293 ;
294 if (level == 0) {
295 level = -1; /* exit the loop */
296 }
297 break;
298 case FDT_PROP:
299 fdt_prop = (struct fdt_property *)fdt_offset_ptr(working_fdt, nodeoffset,
300 sizeof(*fdt_prop));
301 pathp = fdt_string(working_fdt,
302 fdt32_to_cpu(fdt_prop->nameoff));
303 len = fdt32_to_cpu(fdt_prop->len);
304 nodep = fdt_prop->data;
305 if (len < 0) {
306 printf ("libfdt fdt_getprop(): %s\n",
307 fdt_strerror(len));
308 return 1;
309 } else if (len == 0) {
310 /* the property has no value */
311 if (level <= depth)
312 ;
313 } else {
314 if (level <= depth) {
315 print_data (nodep, len, &index, flag);
316 }
317 }
318 break;
319 case FDT_NOP:
320 printf("%s/* NOP */\n", &tabs[MAX_LEVEL - level]);
321 break;
322 case FDT_END:
323 return 1;
324 default:
325 if (level <= depth)
326 printf("Unknown tag 0x%08X\n", tag);
327 return 1;
328 }
329 nodeoffset = nextoffset;
330 }
331
332 *partition_num = index;
333 return 0;
334}
335
336unsigned char *
337GetMultiDtbEntry(unsigned char *fdt_addr, int *plen){
338 unsigned int dt_magic = STRTOU32(fdt_addr);
339 signed int dt_total = 0;
340 unsigned int dt_tool_version = 0;
341
342 //printf(" Amlogic multi-dtb tool\n");
343 if (dt_magic == DT_HEADER_MAGIC) {/*normal dtb*/
344 printf(" Single dtb detected\n");
345 return fdt_addr;
346 }
347 else if (dt_magic == AML_DT_HEADER_MAGIC) {/*multi dtb*/
348 printf(" Multi dtb detected\n");
349 /* check and set aml_dt */
350 int i = 0;
351 char *aml_dt_buf;
352 aml_dt_buf = (char *)malloc(sizeof(char)*64);
353 memset(aml_dt_buf, 0, sizeof(aml_dt_buf));
354
355 GetDtbId(aml_dt_buf);
356 //printf("aml_dt_buf:%s\n", aml_dt_buf);
357
358 unsigned int aml_dt_len = aml_dt_buf ? strlen(aml_dt_buf) : 0;
359 if (aml_dt_len <= 0) {
360 printf("Get env aml_dt failed!Ignore dtb check !\n");
361 *plen = 0;
362 return fdt_addr;
363 }
364
365 /*version control, compatible with v1*/
366 dt_tool_version = STRTOU32(fdt_addr + AML_DT_VERSION_OFFSET);
367 unsigned int aml_each_id_length=0;
368 unsigned int aml_dtb_offset_offset;
369 unsigned int aml_dtb_header_size;
370
371 if (dt_tool_version == 1)
372 aml_each_id_length = 4;
373 else if(dt_tool_version == 2)
374 aml_each_id_length = 16;
375
376 aml_dtb_offset_offset = aml_each_id_length * AML_DT_ID_VARI_TOTAL;
377 aml_dtb_header_size = 8+(aml_each_id_length * AML_DT_ID_VARI_TOTAL);
378 //printf(" Multi dtb tool version: v%d .\n", dt_tool_version);
379
380 /*fdt_addr + 0x8: num of dtbs*/
381 dt_total = STRTOU32(fdt_addr + AML_DT_TOTAL_DTB_OFFSET);
382 //printf(" Support %d dtbs.\n", dt_total);
383
384 /* split aml_dt to 3 strings */
385 char *tokens[3] = {NULL, NULL, NULL};
386 for (i = 0; i < AML_DT_ID_VARI_TOTAL; i++) {
387 tokens[i] = strsep(&aml_dt_buf, "_");
388 }
389
390 if (aml_dt_buf)
391 free(aml_dt_buf);
392 //printf(" aml_dt soc: %s platform: %s variant: %s\n", tokens[0], tokens[1], tokens[2]);
393
394 /*match and print result*/
395 char **dt_info;
396 dt_info = (char **)malloc(sizeof(char *)*AML_DT_ID_VARI_TOTAL);
397 for (i = 0; i < AML_DT_ID_VARI_TOTAL; i++)
398 dt_info[i] = (char *)malloc(sizeof(char)*aml_each_id_length);
399
400 unsigned int dtb_match_num = 0xffff;
401 unsigned int x = 0, y = 0, z = 0; //loop counter
402 unsigned int read_data;
403 for (i = 0; i < dt_total; i++) {
404 for (x = 0; x < AML_DT_ID_VARI_TOTAL; x++) {
405 for (y = 0; y < aml_each_id_length; y+=4) {
406 read_data = STRTOU32(fdt_addr + AML_DT_FIRST_DTB_OFFSET + \
407 i * aml_dtb_header_size + AML_DT_DTB_DT_INFO_OFFSET + \
408 (x * aml_each_id_length) + y);
409 dt_info[x][y+0] = (read_data >> 24) & 0xff;
410 dt_info[x][y+1] = (read_data >> 16) & 0xff;
411 dt_info[x][y+2] = (read_data >> 8) & 0xff;
412 dt_info[x][y+3] = (read_data >> 0) & 0xff;
413 }
414
415 for (z=0; z<aml_each_id_length; z++) {
416 /*fix string with \0*/
417 if (0x20 == (uint)dt_info[x][z]) {
418 dt_info[x][z] = '\0';
419 }
420 }
421 }
422
423 if (dt_tool_version == 1)
424 printf(" dtb %d soc: %.4s plat: %.4s vari: %.4s\n", i, (char *)(dt_info[0]), (char *)(dt_info[1]), (char *)(dt_info[2]));
425 else if(dt_tool_version == 2)
426 printf(" dtb %d soc: %.16s plat: %.16s vari: %.16s\n", i, (char *)(dt_info[0]), (char *)(dt_info[1]), (char *)(dt_info[2]));
427 uint match_str_counter = 0;
428
429 for (z=0; z<AML_DT_ID_VARI_TOTAL; z++) {
430 /*must match 3 strings*/
431 if (!strncmp(tokens[z], (char *)(dt_info[z]), strlen(tokens[z])) && \
432 (strlen(tokens[z]) == strlen(dt_info[z])))
433 match_str_counter++;
434 }
435
436 if (match_str_counter == AML_DT_ID_VARI_TOTAL) {
437 //printf("Find match dtb\n");
438 dtb_match_num = i;
439 }
440
441 for (z=0; z<AML_DT_ID_VARI_TOTAL; z++) {
442 /*clear data for next loop*/
443 memset(dt_info[z], 0, sizeof(aml_each_id_length));
444 }
445 }
446
447 /*clean malloc memory*/
448 for (i = 0; i < AML_DT_ID_VARI_TOTAL; i++) {
449 if (dt_info[i])
450 free(dt_info[i]);
451 }
452
453 if (dt_info)
454 free(dt_info);
455
456 /*if find match dtb, return address, or else return main entrance address*/
457 if (0xffff != dtb_match_num) {
458 printf(" Find match dtb: %d\n", dtb_match_num);
459 /*this offset is based on dtb image package, so should add on base address*/
460 *plen = STRTOU32(fdt_addr + AML_DT_FIRST_DTB_OFFSET + \
461 dtb_match_num * aml_dtb_header_size + aml_dtb_offset_offset+4);
462 return fdt_addr + STRTOU32(fdt_addr + AML_DT_FIRST_DTB_OFFSET + \
463 dtb_match_num * aml_dtb_header_size + aml_dtb_offset_offset);
464 } else {
465 printf(" Not match any dtb.\n");
466 return NULL;
467 }
468 } else {
469 printf(" Cannot find legal dtb!\n");
470 return NULL;
471 }
472
473 return NULL;
474}
475
476
477/**
478 * --- get upgrade package image data
479 *
480 * @zipArchive: zip archive object
481 * @imageName: upgrade package image's name
482 * @imageSize: upgrade package image's size
483 *
484 * return value:
485 * <0: failed
486 * =0: can't find image
487 * >0: get image data successful
488 */
489static unsigned char *s_pDtbBuffer = NULL;
490static int
491GetZipDtbImage(const ZipArchiveHandle za, const char *imageName, int *imageSize){
492 int len = 0;
493 int ret = 0;
494 unsigned char *paddr = NULL;
495
496 ZipString zip_path(imageName);
497 ZipEntry entry;
498 if (FindEntry(za, zip_path, &entry) != 0) {
499 printf("no %s in package!\n", imageName);
500 return 0;
501 }
502
503 *imageSize = entry.uncompressed_length;
504 if (*imageSize <= 0) {
505 printf("can't get package entry uncomp len(%d) (%s)\n",*imageSize, strerror(errno));
506 return -1;
507 }
508
509 len = *imageSize;
510
511 unsigned char* buffer = (unsigned char *)calloc(len, sizeof(unsigned char));
512 if (!buffer) {
513 printf("can't malloc %d size space (%s)\n",len, strerror(errno));
514 return -1;
515 }
516
517 ret = ExtractToMemory(za, &entry, buffer, entry.uncompressed_length);
518 if (ret != 0) {
519 printf("can't extract package entry to image buffer\n");
520 free(buffer);
521 return -1;
522 }
523
524
525 if (isEncrypted == 1) {
526 ret = DtbImgEncrypted(DTB_IMG, buffer, len, "1", buffer);
527 if (ret == 2) {
528 printf("no decrypt_dtb and no support!");
529 free(buffer);
530 return 2;
531 }else if (ret <= 0) {
532 printf("dtb.img encrypt from zip failed!\n");
533 free(buffer);
534 return -1;
535 }
536 }
537
538 paddr = GetMultiDtbEntry(buffer, &len);
539 if (paddr == NULL)
540 {
541 printf("Cannot find legal dtb from zip \n");
542 free(buffer);
543 return -1;
544 } else if (len == 0) {
545 printf("No need to check dtb \n");
546 free(buffer);
547 return 2;
548 }
549
550 if (s_pDtbBuffer != NULL) {
551 free(s_pDtbBuffer);
552 s_pDtbBuffer = NULL;
553 }
554
555 s_pDtbBuffer = (unsigned char *)calloc(len, sizeof(unsigned char));
556 if (!s_pDtbBuffer) {
557 printf("can't malloc %d size space (%s)\n",len, strerror(errno));
558 free(buffer);
559 return -1;
560 }
561
562 memcpy(s_pDtbBuffer, paddr, len);
563 free(buffer);
564
565 return 1;
566}
567
568static int
569GetDevDtbImage(){
570 int fd = 0;
571 int len = 0;
572 int ret = 0;
573 unsigned char *paddr = NULL;
574 const char *DTB_DEV= "/dev/dtb";
575 const int DTB_DATA_MAX = 256*1024;
576
577 unsigned char* buffer = (unsigned char *)calloc(DTB_DATA_MAX+256, sizeof(unsigned char));
578 if (buffer == NULL) {
579 printf("malloc %d failed!\n", DTB_DATA_MAX+256);
580 return -1;
581 }
582
583 fd = open(DTB_DEV, O_RDONLY);
584 if (fd < 0) {
585 printf("open %s failed!\n", DTB_DEV);
586 free(buffer);
587 return -1;
588 }
589
590 len = read(fd, buffer, DTB_DATA_MAX);
591 if (len < 0) {
592 printf("read failed len = %d\n", len);
593 close(fd);
594 free(buffer);
595 return -1;
596 }
597
598 close(fd);
599
600 if (isEncrypted == 1) {
601 ret = DtbImgEncrypted(DTB_IMG, buffer, len, "1", buffer);
602 if (ret <= 0) {
603 printf("dtb.img encrypt from dev failed!\n");
604 free(buffer);
605 return -1;
606 }
607 }
608 paddr = GetMultiDtbEntry(buffer, &len);
609 if (paddr == NULL) {
610 printf("Cannot find legal dtb from dev block \n");
611 free(buffer);
612 return -1;
613 }
614
615 if (s_pDtbBuffer != NULL) {
616 free(s_pDtbBuffer);
617 s_pDtbBuffer = NULL;
618 }
619
620 s_pDtbBuffer = (unsigned char *)calloc(len, sizeof(unsigned char));
621 if (s_pDtbBuffer == NULL) {
622 printf("malloc %d failed!\n", len);
623 free(buffer);
624 return -1;
625 }
626
627 memcpy(s_pDtbBuffer, paddr, len);
628 free(buffer);
629
630 return 0;
631}
632
633int
634GetEnvPartitionOffset(const ZipArchiveHandle za) {
635 int i = 0;
636 int find = 0;
637 int ret = -1;
638 int offset = 116*1024*1024; //bootloader(4M) GAP(32M) reserved(64M) GAP(8M) cache(--) GAP(8M)
639 int imageSize = 0;
640 int partition_num_zip = 0;
641
642 ret = GetZipDtbImage(za, DTB_IMG, &imageSize);
643 if ((ret == 0) || (ret == 2)) {
644 printf("no dtb.img in the update or no need check dtb, check dtb over!\n");
645 return 0;
646 } else if (ret < 0) {
647 printf("get dtb.img from update.zip failed!\n");
648 ret = -1;
649 goto END;
650 }
651
652 working_fdt = (struct fdt_header *)s_pDtbBuffer;
653
654 ret = GetPartitionFromDtb("/partitions", MAX_LEVEL, &partition_num_zip, 0);
655 if (ret != 0) {
656 printf("get partition map from dtb.img failed!\n");
657 ret = -1;
658 goto END;
659 }
660
661 for (i=0; i<partition_num_zip;i++) {
662 printf("%s:0x%08x\n", dtb_zip[i].partition_name, dtb_zip[i].partition_size);
663 if (!strcmp("cache", dtb_zip[i].partition_name)) {
664 offset += dtb_zip[i].partition_size;
665 find = 1;
666 }
667 }
668
669 if (find == 0) {
670 printf("get cache partition size from dtb.img failed!\n");
671 ret = -1;
672 goto END;
673 }
674 printf("env partition offset:0x%08x\n", offset);
675
676 ret = offset;
677
678END:
679 if (s_pDtbBuffer != NULL)
680 {
681 free(s_pDtbBuffer);
682 s_pDtbBuffer = NULL;
683 }
684
685 return ret;
686}
687
688int
689RecoveryDtbCheck(const ZipArchiveHandle za){
690 int i = 0, ret = -1, err = -1;
691 int fd = -1;
692 int partition_num_zip = 0;
693 int partition_num_dev = 0;
694 int imageSize = 0;
695 int recovery_dev = 0, recovery_zip = 0;
696 int data_dev = 0, data_zip = 0;
697 int recovery_offset_dev = 0, recovery_offset_zip = 0;
698 int data_offset_dev = 0, data_offset_zip = 0;
699 int device_type = 0;
700 int partition_num;
701 int cache_offset_dev = 0, cache_offset_zip = 0;
702 int recovery_size_dev = 0, recovery_size_zip = 0;
703 int cache_size_dev = 0, cache_size_zip = 0;
704
705 isEncrypted = IsPlatformEncrypted();
706 if (isEncrypted == 2) {
707 printf("kernel doesn't support!\n");
708 return 0;
709 } else if (isEncrypted < 0) {
710 return -1;
711 }
712
713 ret = GetZipDtbImage(za, DTB_IMG, &imageSize);
714 if ((ret == 0) || (ret == 2)) {
715 printf("no dtb.img in the update or no need check dtb, check dtb over!\n");
716 return 0;
717 } else if (ret < 0) {
718 printf("get dtb.img from update.zip failed!\n");
719 ret = -1;
720 goto END;
721 }
722
723 working_fdt = (struct fdt_header *)s_pDtbBuffer;
724
725 ret = GetPartitionFromDtb("/partitions", MAX_LEVEL, &partition_num_zip, 0);
726 if (ret != 0) {
727 printf("get partition map from dtb.img failed!\n");
728 ret = -1;
729 goto END;
730 }
731
732 ret = GetDevDtbImage();
733 if (ret != 0) {
734 printf("read dtb from /dev/dtb failed!\n");
735 ret = -1;
736 goto END;
737 }
738
739 working_fdt = (struct fdt_header *)s_pDtbBuffer;
740 ret = GetPartitionFromDtb("/partitions", MAX_LEVEL, &partition_num_dev, 1);
741 if (ret != 0) {
742 printf("get partition map from /dev/dtb failed!\n");
743 ret = -1;
744 goto END;
745 }
746
747 partition_num = partition_num_dev;
748 device_type = GetDeviceType();
749 printf("device_type = %d \n",device_type);
750
751 if (partition_num_zip != partition_num_dev) {
752 printf("partition num don't match zip:%d, dev:%d\n",partition_num_zip, partition_num_dev);
753 if (device_type == DEVICE_NAND) {
754 printf("the partitions changed & device is nand! can not upgrade!\n ");
755 ret = -1;
756 goto END;
757 }
758 #ifdef SUPPORT_PARTNUM_CHANGE
759 ret = 2;
760 partition_num = partition_num_zip > partition_num_dev ? partition_num_zip : partition_num_dev;
761 #else
762 printf("partition num don't match zip:%d, dev:%d, can not upgrade!\n",partition_num_zip, partition_num_dev);
763 ret = -1;
764 goto END;
765 #endif
766 }
767 printf("partition_num = %d \n",partition_num);
768
769 for (i=0; i<partition_num;i++) {
770 printf("%s:0x%08x\n", dtb_zip[i].partition_name, dtb_zip[i].partition_size);
771 printf("%s:0x%08x\n", dtb_dev[i].partition_name, dtb_dev[i].partition_size);
772
773 if (!strcmp("recovery", dtb_dev[i].partition_name)) {
774 recovery_size1 = dtb_zip[i].partition_size;
775 recovery_dev = i;
776 recovery_size_dev = dtb_dev[i].partition_size;
777 }
778 if (!strcmp("recovery", dtb_zip[i].partition_name)) {
779 recovery_zip = i;
780 recovery_size_zip = dtb_zip[i].partition_size;
781 }
782
783 if (!strcmp("data", dtb_dev[i].partition_name)) {
784 data_dev = i;
785 }
786 if (!strcmp("data", dtb_zip[i].partition_name)) {
787 data_zip = i;
788 }
789
790 if (!strcmp("cache", dtb_dev[i].partition_name)) {
791 cache_size_dev = dtb_dev[i].partition_size;
792 }
793 if (!strcmp("cache", dtb_zip[i].partition_name)) {
794 cache_size_zip = dtb_zip[i].partition_size;
795 }
796
797 if ((strcmp(dtb_zip[i].partition_name, dtb_dev[i].partition_name) != 0)||
798 (dtb_zip[i].partition_size != dtb_dev[i].partition_size)) {
799 ret = 2;
800 /*just emmc support partition changes*/
801 if (device_type == DEVICE_NAND) {
802 printf("the partitions changed & device is nand! can not upgrade!\n ");
803 ret = -1;
804 goto END;
805 }
806 }
807 }
808
809 /*the offset of recovery/data cannot be changed*/
810 for (i=0;i<recovery_dev;i++) {
811 recovery_offset_dev += dtb_dev[i].partition_size;
812 }
813 for (i=0;i<recovery_zip;i++) {
814 recovery_offset_zip += dtb_zip[i].partition_size;
815 }
816 for (i=0;i<data_dev;i++) {
817 data_offset_dev += dtb_dev[i].partition_size;
818 }
819 for (i=0;i<data_zip;i++) {
820 data_offset_zip += dtb_zip[i].partition_size;
821 }
822
823 for (i=0;i<2;i++) {
824 cache_offset_dev += dtb_dev[i].partition_size;
825 cache_offset_zip += dtb_zip[i].partition_size;
826 }
827
828 printf("recovery_dev: %d recovery_offset_dev :0x%08x\n", recovery_dev, recovery_offset_dev);
829 printf("recovery_zip: %d recovery_offset_zip :0x%08x\n", recovery_zip, recovery_offset_zip);
830 printf("data_dev: %d data_offset_dev :0x%08x\n", data_dev, data_offset_dev);
831 printf("data_zip: %d data_offset_zip :0x%08x\n", data_zip, data_offset_zip);
832 printf("cache_offset_dev :0x%08x, cache_size_dev: %d\n", cache_offset_dev, cache_size_dev);
833 printf("cache_offset_zip :0x%08x, cache_size_zip: %d\n", cache_offset_zip, cache_size_zip);
834
835 if (data_offset_dev != data_offset_zip) {
836 printf("data changed, need wipe_data\n ");
837 ret = 3;
838 }
839
840 if ((recovery_offset_dev != recovery_offset_zip) || (recovery_size_dev != recovery_size_zip)) {
841 printf("recovery part changed! can not upgrade!\n ");
842 ret = -1;
843 goto END;
844 }
845
846 if ((cache_offset_dev != cache_offset_zip) || (cache_size_dev != cache_size_zip)) {
847 printf("cache part changed! can not upgrade!\n ");
848 ret = -1;
849 goto END;
850 }
851
852END:
853 if (s_pDtbBuffer != NULL)
854 {
855 free(s_pDtbBuffer);
856 s_pDtbBuffer = NULL;
857 }
858
859 return ret;
860}
861