diff options
-rw-r--r-- | tools/ipodpatcher/ipodpatcher.c | 91 |
1 files changed, 55 insertions, 36 deletions
diff --git a/tools/ipodpatcher/ipodpatcher.c b/tools/ipodpatcher/ipodpatcher.c index b474355d82..29a5939cea 100644 --- a/tools/ipodpatcher/ipodpatcher.c +++ b/tools/ipodpatcher/ipodpatcher.c | |||
@@ -25,12 +25,11 @@ | |||
25 | #include <inttypes.h> | 25 | #include <inttypes.h> |
26 | #include <sys/types.h> | 26 | #include <sys/types.h> |
27 | #include <sys/stat.h> | 27 | #include <sys/stat.h> |
28 | #include <dirent.h> | ||
29 | 28 | ||
30 | #include "parttypes.h" | 29 | #include "parttypes.h" |
31 | #include "ipodio.h" | 30 | #include "ipodio.h" |
32 | 31 | ||
33 | #define VERSION "0.5" | 32 | #define VERSION "0.6cvs" |
34 | 33 | ||
35 | int verbose = 0; | 34 | int verbose = 0; |
36 | 35 | ||
@@ -338,11 +337,12 @@ void print_usage(void) { | |||
338 | fprintf(stderr,"\n"); | 337 | fprintf(stderr,"\n"); |
339 | fprintf(stderr,"Where [action] is one of the following options:\n"); | 338 | fprintf(stderr,"Where [action] is one of the following options:\n"); |
340 | fprintf(stderr," -l, --list\n"); | 339 | fprintf(stderr," -l, --list\n"); |
341 | fprintf(stderr," -r, --read-partition bootpartition.bin\n"); | 340 | fprintf(stderr," -r, --read-partition bootpartition.bin\n"); |
342 | fprintf(stderr," -w, --write-partition bootpartition.bin\n"); | 341 | fprintf(stderr," -w, --write-partition bootpartition.bin\n"); |
343 | fprintf(stderr," -rf, --read-firmware filename.ipod\n"); | 342 | fprintf(stderr," -rf, --read-firmware filename.ipod\n"); |
344 | fprintf(stderr," -wf, --write-firmware filename.ipod\n"); | 343 | fprintf(stderr," -wf, --write-firmware filename.ipod\n"); |
345 | fprintf(stderr," -a, --add-bootloader filename.ipod\n"); | 344 | fprintf(stderr," -a, --add-bootloader filename.ipod\n"); |
345 | fprintf(stderr," -ab, --add-bootloader-bin filename.bin\n"); | ||
346 | fprintf(stderr," -d, --delete-bootloader\n"); | 346 | fprintf(stderr," -d, --delete-bootloader\n"); |
347 | fprintf(stderr,"\n"); | 347 | fprintf(stderr,"\n"); |
348 | 348 | ||
@@ -371,6 +371,9 @@ enum { | |||
371 | WRITE_PARTITION | 371 | WRITE_PARTITION |
372 | }; | 372 | }; |
373 | 373 | ||
374 | #define DOT_IPOD 0 | ||
375 | #define DOT_BIN 1 | ||
376 | |||
374 | char* ftypename[] = { "OSOS", "RSRC", "AUPD", "HIBE" }; | 377 | char* ftypename[] = { "OSOS", "RSRC", "AUPD", "HIBE" }; |
375 | 378 | ||
376 | enum firmwaretype_t { | 379 | enum firmwaretype_t { |
@@ -472,7 +475,7 @@ int diskmove(HANDLE dh, int start, int nimages, struct ipod_directory_t* ipod_di | |||
472 | return 0; | 475 | return 0; |
473 | } | 476 | } |
474 | 477 | ||
475 | int add_bootloader(HANDLE dh, char* filename, int start, int sector_size, | 478 | int add_bootloader(HANDLE dh, int type, char* filename, int start, int sector_size, |
476 | int nimages, struct ipod_directory_t* ipod_directory, | 479 | int nimages, struct ipod_directory_t* ipod_directory, |
477 | off_t diroffset, int modelnum, char* modelname) | 480 | off_t diroffset, int modelnum, char* modelname) |
478 | { | 481 | { |
@@ -495,23 +498,27 @@ int add_bootloader(HANDLE dh, char* filename, int start, int sector_size, | |||
495 | return -1; | 498 | return -1; |
496 | } | 499 | } |
497 | 500 | ||
498 | n = read(infile,header,8); | 501 | if (type==DOT_IPOD) { |
499 | if (n < 8) { | 502 | n = read(infile,header,8); |
500 | fprintf(stderr,"[ERR] Failed to read header from %s\n",filename); | 503 | if (n < 8) { |
501 | close(infile); | 504 | fprintf(stderr,"[ERR] Failed to read header from %s\n",filename); |
502 | return -1; | 505 | close(infile); |
503 | } | 506 | return -1; |
507 | } | ||
504 | 508 | ||
505 | if (memcmp(header+4,modelname,4)!=0) { | 509 | if (memcmp(header+4,modelname,4)!=0) { |
506 | fprintf(stderr,"[ERR] Model name in input file (%c%c%c%c) doesn't match ipod model (%s)\n", | 510 | fprintf(stderr,"[ERR] Model name in input file (%c%c%c%c) doesn't match ipod model (%s)\n", |
507 | header[4],header[5],header[6],header[7],modelname); | 511 | header[4],header[5],header[6],header[7],modelname); |
508 | close(infile); | 512 | close(infile); |
509 | return -1; | 513 | return -1; |
510 | } | 514 | } |
511 | 515 | ||
512 | filechksum = be2int(header); | 516 | filechksum = be2int(header); |
513 | 517 | ||
514 | length=filesize(infile)-8; | 518 | length=filesize(infile)-8; |
519 | } else { | ||
520 | length=filesize(infile); | ||
521 | } | ||
515 | paddedlength=(length+sector_size-1)&~(sector_size-1); | 522 | paddedlength=(length+sector_size-1)&~(sector_size-1); |
516 | 523 | ||
517 | /* Now read our bootloader - we need to check it before modifying the partition*/ | 524 | /* Now read our bootloader - we need to check it before modifying the partition*/ |
@@ -522,18 +529,20 @@ int add_bootloader(HANDLE dh, char* filename, int start, int sector_size, | |||
522 | return -1; | 529 | return -1; |
523 | } | 530 | } |
524 | 531 | ||
525 | /* Calculate and confirm bootloader checksum */ | 532 | if (type==DOT_IPOD) { |
526 | chksum = modelnum; | 533 | /* Calculate and confirm bootloader checksum */ |
527 | for (i = 0; i < length; i++) { | 534 | chksum = modelnum; |
528 | /* add 8 unsigned bits but keep a 32 bit sum */ | 535 | for (i = 0; i < length; i++) { |
529 | chksum += sectorbuf[i]; | 536 | /* add 8 unsigned bits but keep a 32 bit sum */ |
530 | } | 537 | chksum += sectorbuf[i]; |
538 | } | ||
531 | 539 | ||
532 | if (chksum == filechksum) { | 540 | if (chksum == filechksum) { |
533 | fprintf(stderr,"[INFO] Checksum OK in %s\n",filename); | 541 | fprintf(stderr,"[INFO] Checksum OK in %s\n",filename); |
534 | } else { | 542 | } else { |
535 | fprintf(stderr,"[ERR] Checksum in %s failed check\n",filename); | 543 | fprintf(stderr,"[ERR] Checksum in %s failed check\n",filename); |
536 | return -1; | 544 | return -1; |
545 | } | ||
537 | } | 546 | } |
538 | 547 | ||
539 | if (ipod_directory[0].entryOffset>0) { | 548 | if (ipod_directory[0].entryOffset>0) { |
@@ -593,8 +602,8 @@ int add_bootloader(HANDLE dh, char* filename, int start, int sector_size, | |||
593 | return -1; | 602 | return -1; |
594 | } | 603 | } |
595 | 604 | ||
596 | /* Now read our bootloader - we need to seek back to 8 bytes from start */ | 605 | /* Now read our bootloader - we need to seek back to the start */ |
597 | lseek(infile,8,SEEK_SET); | 606 | lseek(infile,(type == DOT_IPOD ? 8 : 0),SEEK_SET); |
598 | n = read(infile,sectorbuf+entryOffset,length); | 607 | n = read(infile,sectorbuf+entryOffset,length); |
599 | if (n < 0) { | 608 | if (n < 0) { |
600 | fprintf(stderr,"[ERR] Couldn't read input file\n"); | 609 | fprintf(stderr,"[ERR] Couldn't read input file\n"); |
@@ -1195,6 +1204,7 @@ int main(int argc, char* argv[]) | |||
1195 | struct ipod_directory_t ipod_directory[MAX_IMAGES]; | 1204 | struct ipod_directory_t ipod_directory[MAX_IMAGES]; |
1196 | int action = SHOW_INFO; | 1205 | int action = SHOW_INFO; |
1197 | int sector_size; | 1206 | int sector_size; |
1207 | int type; | ||
1198 | char devicename[4096]; | 1208 | char devicename[4096]; |
1199 | HANDLE dh; | 1209 | HANDLE dh; |
1200 | 1210 | ||
@@ -1238,6 +1248,15 @@ int main(int argc, char* argv[]) | |||
1238 | } else if ((strcmp(argv[i],"-a")==0) || | 1248 | } else if ((strcmp(argv[i],"-a")==0) || |
1239 | (strcmp(argv[i],"--add-bootloader")==0)) { | 1249 | (strcmp(argv[i],"--add-bootloader")==0)) { |
1240 | action = ADD_BOOTLOADER; | 1250 | action = ADD_BOOTLOADER; |
1251 | type = DOT_IPOD; | ||
1252 | i++; | ||
1253 | if (i == argc) { print_usage(); return 1; } | ||
1254 | filename=argv[i]; | ||
1255 | i++; | ||
1256 | } else if ((strcmp(argv[i],"-ab")==0) || | ||
1257 | (strcmp(argv[i],"--add-bootloader-bin")==0)) { | ||
1258 | action = ADD_BOOTLOADER; | ||
1259 | type = DOT_BIN; | ||
1241 | i++; | 1260 | i++; |
1242 | if (i == argc) { print_usage(); return 1; } | 1261 | if (i == argc) { print_usage(); return 1; } |
1243 | filename=argv[i]; | 1262 | filename=argv[i]; |
@@ -1341,7 +1360,7 @@ int main(int argc, char* argv[]) | |||
1341 | return 5; | 1360 | return 5; |
1342 | } | 1361 | } |
1343 | 1362 | ||
1344 | if (add_bootloader(dh, filename,pinfo[0].start*sector_size, | 1363 | if (add_bootloader(dh, type, filename,pinfo[0].start*sector_size, |
1345 | sector_size, nimages, ipod_directory, diroffset, | 1364 | sector_size, nimages, ipod_directory, diroffset, |
1346 | modelnum, modelname)==0) { | 1365 | modelnum, modelname)==0) { |
1347 | fprintf(stderr,"[INFO] Bootloader %s written to device.\n",filename); | 1366 | fprintf(stderr,"[INFO] Bootloader %s written to device.\n",filename); |