summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDave Chapman <dave@dchapman.com>2007-02-08 18:05:50 +0000
committerDave Chapman <dave@dchapman.com>2007-02-08 18:05:50 +0000
commitbdc27ff20c3666989cd8ba83fc9a43c25382ced4 (patch)
treefb66ef4d48bc2c2a97ac68fe78c8bb2901f296e0
parentdeb83637512488b42a848ced66d039fa8df0f428 (diff)
downloadrockbox-bdc27ff20c3666989cd8ba83fc9a43c25382ced4.tar.gz
rockbox-bdc27ff20c3666989cd8ba83fc9a43c25382ced4.zip
Work-in-progress (i.e. not well tested) changes: Add the option to build ipodpatcher with the Rockbox bootloaders embedded (see the comments in the Makefile for build instructions). This gives a new --install option which will search for an ipod, and if exactly one is found, will install the embedded bootloader. Even easier is the new interactive mode - running ipodpatcher with no command-line options (e.g. double-clicking on ipodpatcher.exe in Windows) will cause ipodpatcher to search for an ipod, and if exactly one is found, ask the user if he/she wishes to install the bootloader. Thanks to Bryan Childs for sample code to deal with prompts.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@12235 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r--tools/ipodpatcher/Makefile48
-rw-r--r--tools/ipodpatcher/ipod2c.c139
-rw-r--r--tools/ipodpatcher/ipodio.h4
-rw-r--r--tools/ipodpatcher/ipodpatcher.c257
4 files changed, 369 insertions, 79 deletions
diff --git a/tools/ipodpatcher/Makefile b/tools/ipodpatcher/Makefile
index d796f4494c..559b2f3ea5 100644
--- a/tools/ipodpatcher/Makefile
+++ b/tools/ipodpatcher/Makefile
@@ -1,5 +1,15 @@
1CFLAGS=-Wall 1CFLAGS=-Wall
2 2
3BOOT_H = ipod3g.h ipod4g.h ipodcolor.h ipodmini.h ipodmini2g.h ipodnano.h ipodvideo.h
4
5# Uncomment the next two lines to build with embedded bootloaders and the
6# --install option and interactive mode. You need the full set of Rockbox
7# bootloaders in this directory - download them from
8# http://download.rockbox.org/bootloader/ipod/bootloaders.zip
9
10BOOTSRC = ipod3g.c ipod4g.c ipodcolor.c ipodmini.c ipodmini2g.c ipodnano.c ipodvideo.c
11CFLAGS += -DWITH_BOOTOBJS
12
3ifeq ($(findstring CYGWIN,$(shell uname)),CYGWIN) 13ifeq ($(findstring CYGWIN,$(shell uname)),CYGWIN)
4OUTPUT=ipodpatcher.exe 14OUTPUT=ipodpatcher.exe
5CROSS= 15CROSS=
@@ -9,15 +19,43 @@ OUTPUT=ipodpatcher
9CROSS=i586-mingw32msvc- 19CROSS=i586-mingw32msvc-
10endif 20endif
11 21
22NATIVECC = gcc
23CC = $(CROSS)gcc
24
12all: $(OUTPUT) 25all: $(OUTPUT)
13 26
14ipodpatcher: ipodpatcher.c ipodio-posix.c parttypes.h 27ipodpatcher: ipodpatcher.c ipodio-posix.c parttypes.h $(BOOTSRC)
15 gcc $(CFLAGS) -o ipodpatcher ipodpatcher.c ipodio-posix.c 28 gcc $(CFLAGS) -o ipodpatcher ipodpatcher.c ipodio-posix.c $(BOOTSRC)
16 strip ipodpatcher 29 strip ipodpatcher
17 30
18ipodpatcher.exe: ipodpatcher.c ipodio-win32.c parttypes.h 31ipodpatcher.exe: ipodpatcher.c ipodio-win32.c parttypes.h $(BOOTSRC)
19 $(CROSS)gcc $(CFLAGS) -o ipodpatcher.exe ipodpatcher.c ipodio-win32.c 32 $(CC) $(CFLAGS) -o ipodpatcher.exe ipodpatcher.c ipodio-win32.c $(BOOTSRC)
20 $(CROSS)strip ipodpatcher.exe 33 $(CROSS)strip ipodpatcher.exe
21 34
35ipod2c: ipod2c.c
36 $(NATIVECC) $(CFLAGS) -o ipod2c ipod2c.c
37
38ipod3g.c: bootloader-ipod3g.ipod ipod2c
39 ./ipod2c bootloader-ipod3g.ipod ipod3g
40
41ipod4g.c: bootloader-ipod4g.ipod ipod2c
42 ./ipod2c bootloader-ipod4g.ipod ipod4g
43
44ipodcolor.c: bootloader-ipodcolor.ipod ipod2c
45 ./ipod2c bootloader-ipodcolor.ipod ipodcolor
46
47ipodmini.c: bootloader-ipodmini.ipod ipod2c
48 ./ipod2c bootloader-ipodmini.ipod ipodmini
49
50ipodmini2g.c: bootloader-ipodmini2g.ipod ipod2c
51 ./ipod2c bootloader-ipodmini2g.ipod ipodmini2g
52
53ipodnano.c: bootloader-ipodnano.ipod ipod2c
54 ./ipod2c bootloader-ipodnano.ipod ipodnano
55
56ipodvideo.c: bootloader-ipodvideo.ipod ipod2c
57 ./ipod2c bootloader-ipodvideo.ipod ipodvideo
58
59
22clean: 60clean:
23 rm -f ipodpatcher.exe ipodpatcher *~ 61 rm -f ipodpatcher.exe ipodpatcher ipod2c *~ $(BOOTSRC) $(BOOT_H)
diff --git a/tools/ipodpatcher/ipod2c.c b/tools/ipodpatcher/ipod2c.c
new file mode 100644
index 0000000000..af2e25dd09
--- /dev/null
+++ b/tools/ipodpatcher/ipod2c.c
@@ -0,0 +1,139 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id: ipodio-win32.c 12205 2007-02-05 01:20:20Z dave $
9 *
10 * Copyright (C) 2007 Dave Chapman
11 *
12 * All files in this archive are subject to the GNU General Public License.
13 * See the file COPYING in the source tree root for full license agreement.
14 *
15 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
16 * KIND, either express or implied.
17 *
18 ****************************************************************************/
19
20#include <stdio.h>
21#include <string.h>
22#include <sys/types.h>
23#include <sys/stat.h>
24#include <unistd.h>
25#include <fcntl.h>
26#include <stdlib.h>
27
28#ifndef O_BINARY
29#define O_BINARY 0
30#endif
31
32static off_t filesize(int fd)
33{
34 struct stat buf;
35
36 fstat(fd,&buf);
37 return buf.st_size;
38}
39
40static int write_cfile(unsigned char* buf, off_t len, char* cname)
41{
42 char filename[256];
43 FILE* fp;
44 int i;
45
46 snprintf(filename,256,"%s.c",cname);
47
48 fp = fopen(filename,"w+");
49 if (fp == NULL) {
50 fprintf(stderr,"Couldn't open %s\n",filename);
51 return -1;
52 }
53
54 fprintf(fp,"/* Generated by ipod2c */\n\n");
55 fprintf(fp,"unsigned char %s[] = {",cname);
56
57 for (i=0;i<len;i++) {
58 if ((i % 16) == 0) {
59 fprintf(fp,"\n ");
60 }
61 if (i == (len-1)) {
62 fprintf(fp,"0x%02x",buf[i]);
63 } else {
64 fprintf(fp,"0x%02x, ",buf[i]);
65 }
66 }
67 fprintf(fp,"\n};\n");
68
69 fclose(fp);
70 return 0;
71}
72
73static int write_hfile(unsigned char* buf, off_t len, char* cname)
74{
75 char filename[256];
76 FILE* fp;
77
78 snprintf(filename,256,"%s.h",cname);
79 fp = fopen(filename,"w+");
80 if (fp == NULL) {
81 fprintf(stderr,"Couldn't open %s\n",filename);
82 return -1;
83 }
84
85 fprintf(fp,"/* Generated by ipod2c */\n\n");
86 fprintf(fp,"#define LEN_%s %d\n",cname,(int)len);
87 fprintf(fp,"extern unsigned char %s[];\n",cname);
88 fclose(fp);
89 return 0;
90}
91
92int main (int argc, char* argv[])
93{
94 char* infile;
95 char* cname;
96 int fd;
97 unsigned char* buf;
98 int len;
99 int n;
100
101 if (argc != 3) {
102 fprintf(stderr,"Usage: ipod2c file.bin cname\n");
103 return 0;
104 }
105
106 infile=argv[1];
107 cname=argv[2];
108
109 fd = open(infile,O_RDONLY);
110 if (fd < 0) {
111 fprintf(stderr,"Can not open %s\n",infile);
112 return 0;
113 }
114
115 len = filesize(fd) - 8;
116
117 n = lseek(fd,8,SEEK_SET);
118 if (n != 8) {
119 fprintf(stderr,"Seek failed\n");
120 return 0;
121 }
122
123 buf = malloc(len);
124 n = read(fd,buf,len);
125 if (n < len) {
126 fprintf(stderr,"Short read, aborting\n");
127 return 0;
128 }
129 close(fd);
130
131 if (write_cfile(buf,len,cname) < 0) {
132 return -1;
133 }
134 if (write_hfile(buf,len,cname) < 0) {
135 return -1;
136 }
137
138 return 0;
139}
diff --git a/tools/ipodpatcher/ipodio.h b/tools/ipodpatcher/ipodio.h
index 9624849562..d0641faa2b 100644
--- a/tools/ipodpatcher/ipodio.h
+++ b/tools/ipodpatcher/ipodio.h
@@ -71,6 +71,10 @@ struct ipod_t {
71 char* modelname; 71 char* modelname;
72 char* modelstr; 72 char* modelstr;
73 int macpod; 73 int macpod;
74#ifdef WITH_BOOTOBJS
75 unsigned char* bootloader;
76 int bootloader_len;
77#endif
74}; 78};
75 79
76void print_error(char* msg); 80void print_error(char* msg);
diff --git a/tools/ipodpatcher/ipodpatcher.c b/tools/ipodpatcher/ipodpatcher.c
index bcabe43fc8..8f8fda2e3f 100644
--- a/tools/ipodpatcher/ipodpatcher.c
+++ b/tools/ipodpatcher/ipodpatcher.c
@@ -29,6 +29,16 @@
29#include "parttypes.h" 29#include "parttypes.h"
30#include "ipodio.h" 30#include "ipodio.h"
31 31
32#ifdef WITH_BOOTOBJS
33#include "ipod3g.h"
34#include "ipod4g.h"
35#include "ipodmini.h"
36#include "ipodmini2g.h"
37#include "ipodcolor.h"
38#include "ipodnano.h"
39#include "ipodvideo.h"
40#endif
41
32#define VERSION "0.8svn" 42#define VERSION "0.8svn"
33 43
34int verbose = 0; 44int verbose = 0;
@@ -401,12 +411,15 @@ void print_usage(void)
401{ 411{
402 fprintf(stderr,"Usage: ipodpatcher --scan\n"); 412 fprintf(stderr,"Usage: ipodpatcher --scan\n");
403#ifdef __WIN32__ 413#ifdef __WIN32__
404 fprintf(stderr," or ipodpatcher DISKNO [action]\n"); 414 fprintf(stderr," or ipodpatcher [DISKNO] [action]\n");
405#else 415#else
406 fprintf(stderr," or ipodpatcher device [action]\n"); 416 fprintf(stderr," or ipodpatcher [device] [action]\n");
407#endif 417#endif
408 fprintf(stderr,"\n"); 418 fprintf(stderr,"\n");
409 fprintf(stderr,"Where [action] is one of the following options:\n"); 419 fprintf(stderr,"Where [action] is one of the following options:\n");
420#ifdef WITH_BOOTOBJS
421 fprintf(stderr," --install\n");
422#endif
410 fprintf(stderr," -l, --list\n"); 423 fprintf(stderr," -l, --list\n");
411 fprintf(stderr," -r, --read-partition bootpartition.bin\n"); 424 fprintf(stderr," -r, --read-partition bootpartition.bin\n");
412 fprintf(stderr," -w, --write-partition bootpartition.bin\n"); 425 fprintf(stderr," -w, --write-partition bootpartition.bin\n");
@@ -439,6 +452,10 @@ void print_usage(void)
439 452
440enum { 453enum {
441 NONE, 454 NONE,
455#ifdef WITH_BOOTOBJS
456 INSTALL,
457#endif
458 INTERACTIVE,
442 SHOW_INFO, 459 SHOW_INFO,
443 LIST_IMAGES, 460 LIST_IMAGES,
444 DELETE_BOOTLOADER, 461 DELETE_BOOTLOADER,
@@ -449,8 +466,11 @@ enum {
449 WRITE_PARTITION 466 WRITE_PARTITION
450}; 467};
451 468
452#define DOT_IPOD 0 469#define FILETYPE_DOT_IPOD 0
453#define DOT_BIN 1 470#define FILETYPE_DOT_BIN 1
471#ifdef WITH_BOOTOBJS
472 #define FILETYPE_INTERNAL 2
473#endif
454 474
455char* ftypename[] = { "OSOS", "RSRC", "AUPD", "HIBE" }; 475char* ftypename[] = { "OSOS", "RSRC", "AUPD", "HIBE" };
456 476
@@ -548,70 +568,82 @@ int add_bootloader(struct ipod_t* ipod, char* filename, int type)
548 unsigned long filechksum=0; 568 unsigned long filechksum=0;
549 unsigned char header[8]; /* Header for .ipod file */ 569 unsigned char header[8]; /* Header for .ipod file */
550 570
551 infile=open(filename,O_RDONLY); 571 /* Calculate the position in the OSOS image where our bootloader will go. */
552 if (infile < 0) { 572 if (ipod->ipod_directory[0].entryOffset>0) {
553 fprintf(stderr,"[ERR] Couldn't open input file %s\n",filename); 573 /* Keep the same entryOffset */
554 return -1; 574 entryOffset = ipod->ipod_directory[0].entryOffset;
575 } else {
576 entryOffset = (ipod->ipod_directory[0].len+ipod->sector_size-1)&~(ipod->sector_size-1);
555 } 577 }
556 578
557 if (type==DOT_IPOD) { 579#ifdef WITH_BOOTOBJS
558 /* First check that the input file is the correct type for this ipod. */ 580 if (type == FILETYPE_INTERNAL) {
559 n = read(infile,header,8); 581 fprintf(stderr,"[INFO] Using internal bootloader - %d bytes\n",ipod->bootloader_len);
560 if (n < 8) { 582 memcpy(sectorbuf+entryOffset,ipod->bootloader,ipod->bootloader_len);
561 fprintf(stderr,"[ERR] Failed to read header from %s\n",filename); 583 length = ipod->bootloader_len;
562 close(infile); 584 paddedlength=(ipod->bootloader_len+ipod->sector_size-1)&~(ipod->sector_size-1);
585 }
586 else
587#endif
588 {
589 infile=open(filename,O_RDONLY);
590 if (infile < 0) {
591 fprintf(stderr,"[ERR] Couldn't open input file %s\n",filename);
563 return -1; 592 return -1;
564 } 593 }
565 594
566 if (memcmp(header+4, ipod->modelname,4)!=0) { 595 if (type==FILETYPE_DOT_IPOD) {
567 fprintf(stderr,"[ERR] Model name in input file (%c%c%c%c) doesn't match ipod model (%s)\n", 596 /* First check that the input file is the correct type for this ipod. */
568 header[4],header[5],header[6],header[7], ipod->modelname); 597 n = read(infile,header,8);
569 close(infile); 598 if (n < 8) {
570 return -1; 599 fprintf(stderr,"[ERR] Failed to read header from %s\n",filename);
600 close(infile);
601 return -1;
602 }
603
604 if (memcmp(header+4, ipod->modelname,4)!=0) {
605 fprintf(stderr,"[ERR] Model name in input file (%c%c%c%c) doesn't match ipod model (%s)\n",
606 header[4],header[5],header[6],header[7], ipod->modelname);
607 close(infile);
608 return -1;
609 }
610
611 filechksum = be2int(header);
612
613 length=filesize(infile)-8;
614 } else {
615 length=filesize(infile);
571 } 616 }
572 617 paddedlength=(length+ipod->sector_size-1)&~(ipod->sector_size-1);
573 filechksum = be2int(header); 618
574 619 /* Now read our bootloader - we need to check it before modifying the partition*/
575 length=filesize(infile)-8; 620 n = read(infile,sectorbuf+entryOffset,length);
576 } else {
577 length=filesize(infile);
578 }
579 paddedlength=(length+ipod->sector_size-1)&~(ipod->sector_size-1);
580
581 /* Now read our bootloader - we need to check it before modifying the partition*/
582 n = read(infile,sectorbuf,length);
583 if (n < 0) {
584 fprintf(stderr,"[ERR] Couldn't read input file\n");
585 close(infile); 621 close(infile);
586 return -1;
587 }
588
589 if (type==DOT_IPOD) {
590 /* Calculate and confirm bootloader checksum */
591 chksum = ipod->modelnum;
592 for (i = 0; i < length; i++) {
593 /* add 8 unsigned bits but keep a 32 bit sum */
594 chksum += sectorbuf[i];
595 }
596 622
597 if (chksum == filechksum) { 623 if (n < 0) {
598 fprintf(stderr,"[INFO] Checksum OK in %s\n",filename); 624 fprintf(stderr,"[ERR] Couldn't read input file\n");
599 } else {
600 fprintf(stderr,"[ERR] Checksum in %s failed check\n",filename);
601 return -1; 625 return -1;
602 } 626 }
603 } 627
604 628 if (type==FILETYPE_DOT_IPOD) {
605 if (ipod->ipod_directory[0].entryOffset>0) { 629 /* Calculate and confirm bootloader checksum */
606 /* Keep the same entryOffset */ 630 chksum = ipod->modelnum;
607 entryOffset = ipod->ipod_directory[0].entryOffset; 631 for (i = entryOffset; i < entryOffset+length; i++) {
608 } else { 632 /* add 8 unsigned bits but keep a 32 bit sum */
609 entryOffset = (ipod->ipod_directory[0].len+ipod->sector_size-1)&~(ipod->sector_size-1); 633 chksum += sectorbuf[i];
634 }
635
636 if (chksum == filechksum) {
637 fprintf(stderr,"[INFO] Checksum OK in %s\n",filename);
638 } else {
639 fprintf(stderr,"[ERR] Checksum in %s failed check\n",filename);
640 return -1;
641 }
642 }
610 } 643 }
611 644
612 if (entryOffset+paddedlength > BUFFER_SIZE) { 645 if (entryOffset+paddedlength > BUFFER_SIZE) {
613 fprintf(stderr,"[ERR] Input file too big for buffer\n"); 646 fprintf(stderr,"[ERR] Input file too big for buffer\n");
614 close(infile);
615 return -1; 647 return -1;
616 } 648 }
617 649
@@ -624,14 +656,13 @@ int add_bootloader(struct ipod_t* ipod, char* filename, int type)
624 /* Check if we have enough space */ 656 /* Check if we have enough space */
625 /* TODO: Check the size of the partition. */ 657 /* TODO: Check the size of the partition. */
626 if (ipod->nimages > 1) { 658 if (ipod->nimages > 1) {
627 if ((ipod->ipod_directory[0].devOffset+entryOffset+paddedlength) >= 659 if ((ipod->ipod_directory[0].devOffset+entryOffset+paddedlength) >
628 ipod->ipod_directory[1].devOffset) { 660 ipod->ipod_directory[1].devOffset) {
629 fprintf(stderr,"[INFO] Moving images to create room for new firmware...\n"); 661 fprintf(stderr,"[INFO] Moving images to create room for new firmware...\n");
630 delta = ipod->ipod_directory[0].devOffset + entryOffset+paddedlength 662 delta = ipod->ipod_directory[0].devOffset + entryOffset+paddedlength
631 - ipod->ipod_directory[1].devOffset; 663 - ipod->ipod_directory[1].devOffset;
632 664
633 if (diskmove(ipod, delta) < 0) { 665 if (diskmove(ipod, delta) < 0) {
634 close(infile);
635 fprintf(stderr,"[ERR] Image movement failed.\n"); 666 fprintf(stderr,"[ERR] Image movement failed.\n");
636 return -1; 667 return -1;
637 } 668 }
@@ -643,7 +674,6 @@ int add_bootloader(struct ipod_t* ipod, char* filename, int type)
643 674
644 /* Firstly read the original firmware into sectorbuf */ 675 /* Firstly read the original firmware into sectorbuf */
645 fprintf(stderr,"[INFO] Reading original firmware...\n"); 676 fprintf(stderr,"[INFO] Reading original firmware...\n");
646
647 if (ipod_seek(ipod, ipod->fwoffset+ipod->ipod_directory[0].devOffset) < 0) { 677 if (ipod_seek(ipod, ipod->fwoffset+ipod->ipod_directory[0].devOffset) < 0) {
648 fprintf(stderr,"[ERR] Seek failed\n"); 678 fprintf(stderr,"[ERR] Seek failed\n");
649 return -1; 679 return -1;
@@ -660,16 +690,6 @@ int add_bootloader(struct ipod_t* ipod, char* filename, int type)
660 return -1; 690 return -1;
661 } 691 }
662 692
663 /* Now read our bootloader - we need to seek back to the start */
664 lseek(infile,(type == DOT_IPOD ? 8 : 0),SEEK_SET);
665 n = read(infile,sectorbuf+entryOffset,length);
666 if (n < 0) {
667 fprintf(stderr,"[ERR] Couldn't read input file\n");
668 close(infile);
669 return -1;
670 }
671 close(infile);
672
673 /* Calculate new checksum for combined image */ 693 /* Calculate new checksum for combined image */
674 chksum = 0; 694 chksum = 0;
675 for (i=0;i<entryOffset + length; i++) { 695 for (i=0;i<entryOffset + length; i++) {
@@ -830,7 +850,7 @@ int write_firmware(struct ipod_t* ipod, char* filename, int type)
830 return -1; 850 return -1;
831 } 851 }
832 852
833 if (type==DOT_IPOD) { 853 if (type==FILETYPE_DOT_IPOD) {
834 n = read(infile,header,8); 854 n = read(infile,header,8);
835 if (n < 8) { 855 if (n < 8) {
836 fprintf(stderr,"[ERR] Failed to read header from %s\n",filename); 856 fprintf(stderr,"[ERR] Failed to read header from %s\n",filename);
@@ -887,7 +907,7 @@ int write_firmware(struct ipod_t* ipod, char* filename, int type)
887 } 907 }
888 close(infile); 908 close(infile);
889 909
890 if (type==DOT_IPOD) { 910 if (type==FILETYPE_DOT_IPOD) {
891 chksum = ipod->modelnum; 911 chksum = ipod->modelnum;
892 for (i = 0; i < length; i++) { 912 for (i = 0; i < length; i++) {
893 /* add 8 unsigned bits but keep a 32 bit sum */ 913 /* add 8 unsigned bits but keep a 32 bit sum */
@@ -1170,40 +1190,72 @@ int getmodel(struct ipod_t* ipod, int ipod_version)
1170 ipod->modelstr="3rd Generation"; 1190 ipod->modelstr="3rd Generation";
1171 ipod->modelnum = 7; 1191 ipod->modelnum = 7;
1172 ipod->modelname = "ip3g"; 1192 ipod->modelname = "ip3g";
1193#ifdef WITH_BOOTOBJS
1194 ipod->bootloader = ipod3g;
1195 ipod->bootloader_len = LEN_ipod3g;
1196#endif
1173 break; 1197 break;
1174 case 0x40: 1198 case 0x40:
1175 ipod->modelstr="1st Generation Mini"; 1199 ipod->modelstr="1st Generation Mini";
1176 ipod->modelnum = 9; 1200 ipod->modelnum = 9;
1177 ipod->modelname = "mini"; 1201 ipod->modelname = "mini";
1202#ifdef WITH_BOOTOBJS
1203 ipod->bootloader = ipodmini;
1204 ipod->bootloader_len = LEN_ipodmini;
1205#endif
1178 break; 1206 break;
1179 case 0x50: 1207 case 0x50:
1180 ipod->modelstr="4th Generation"; 1208 ipod->modelstr="4th Generation";
1181 ipod->modelnum = 8; 1209 ipod->modelnum = 8;
1182 ipod->modelname = "ip4g"; 1210 ipod->modelname = "ip4g";
1211#ifdef WITH_BOOTOBJS
1212 ipod->bootloader = ipod4g;
1213 ipod->bootloader_len = LEN_ipod4g;
1214#endif
1183 break; 1215 break;
1184 case 0x60: 1216 case 0x60:
1185 ipod->modelstr="Photo/Color"; 1217 ipod->modelstr="Photo/Color";
1186 ipod->modelnum = 3; 1218 ipod->modelnum = 3;
1187 ipod->modelname = "ipco"; 1219 ipod->modelname = "ipco";
1220#ifdef WITH_BOOTOBJS
1221 ipod->bootloader = ipodcolor;
1222 ipod->bootloader_len = LEN_ipodcolor;
1223#endif
1188 break; 1224 break;
1189 case 0x70: 1225 case 0x70:
1190 ipod->modelstr="2nd Generation Mini"; 1226 ipod->modelstr="2nd Generation Mini";
1191 ipod->modelnum = 11; 1227 ipod->modelnum = 11;
1192 ipod->modelname = "mn2g"; 1228 ipod->modelname = "mn2g";
1229#ifdef WITH_BOOTOBJS
1230 ipod->bootloader = ipodmini2g;
1231 ipod->bootloader_len = LEN_ipodmini2g;
1232#endif
1193 break; 1233 break;
1194 case 0xc0: 1234 case 0xc0:
1195 ipod->modelstr="1st Generation Nano"; 1235 ipod->modelstr="1st Generation Nano";
1196 ipod->modelnum = 4; 1236 ipod->modelnum = 4;
1197 ipod->modelname = "nano"; 1237 ipod->modelname = "nano";
1238#ifdef WITH_BOOTOBJS
1239 ipod->bootloader = ipodnano;
1240 ipod->bootloader_len = LEN_ipodnano;
1241#endif
1198 break; 1242 break;
1199 case 0xb0: 1243 case 0xb0:
1200 ipod->modelstr="Video (aka 5th Generation)"; 1244 ipod->modelstr="Video (aka 5th Generation)";
1201 ipod->modelnum = 5; 1245 ipod->modelnum = 5;
1202 ipod->modelname = "ipvd"; 1246 ipod->modelname = "ipvd";
1247#ifdef WITH_BOOTOBJS
1248 ipod->bootloader = ipodvideo;
1249 ipod->bootloader_len = LEN_ipodvideo;
1250#endif
1203 break; 1251 break;
1204 default: 1252 default:
1205 ipod->modelname = NULL; 1253 ipod->modelname = NULL;
1206 ipod->modelnum = 0; 1254 ipod->modelnum = 0;
1255#ifdef WITH_BOOTOBJS
1256 ipod->bootloader = NULL;
1257 ipod->bootloader_len = 0;
1258#endif
1207 return -1; 1259 return -1;
1208 } 1260 }
1209 return 0; 1261 return 0;
@@ -1279,6 +1331,9 @@ int ipod_scan(struct ipod_t* ipod)
1279 1331
1280int main(int argc, char* argv[]) 1332int main(int argc, char* argv[])
1281{ 1333{
1334#ifdef WITH_BOOTOBJS
1335 char yesno[4];
1336#endif
1282 int i; 1337 int i;
1283 int n; 1338 int n;
1284 int infile, outfile; 1339 int infile, outfile;
@@ -1320,18 +1375,40 @@ int main(int argc, char* argv[])
1320 n = ipod_scan(&ipod); 1375 n = ipod_scan(&ipod);
1321 if (n==0) { 1376 if (n==0) {
1322 fprintf(stderr,"[ERR] No ipods found, aborting\n"); 1377 fprintf(stderr,"[ERR] No ipods found, aborting\n");
1323 return 0; 1378 fprintf(stderr,"[ERR] Please connect your ipod and ensure it is in disk mode\n");
1324 } else if (n > 1) { 1379 } else if (n > 1) {
1325 fprintf(stderr,"[ERR] %d ipods found, aborting\n",n); 1380 fprintf(stderr,"[ERR] %d ipods found, aborting\n",n);
1381 fprintf(stderr,"[ERR] Please connect only one ipod.\n");
1382 }
1383
1384 if (n != 1) {
1385#ifdef WITH_BOOTOBJS
1386 if (argc==1) {
1387 printf("\nPress ENTER to exit ipodpatcher :");
1388 fgets(yesno,4,stdin);
1389 }
1390#endif
1326 return 0; 1391 return 0;
1327 } 1392 }
1393
1328 i = 1; 1394 i = 1;
1329 } 1395 }
1330 1396
1397#ifdef WITH_BOOTOBJS
1398 action = INTERACTIVE;
1399#else
1400 action = NONE;
1401#endif
1402
1331 while (i < argc) { 1403 while (i < argc) {
1332 if ((strcmp(argv[i],"-l")==0) || (strcmp(argv[i],"--list")==0)) { 1404 if ((strcmp(argv[i],"-l")==0) || (strcmp(argv[i],"--list")==0)) {
1333 action = LIST_IMAGES; 1405 action = LIST_IMAGES;
1334 i++; 1406 i++;
1407#ifdef WITH_BOOTOBJS
1408 } else if (strcmp(argv[i],"--install")==0) {
1409 action = INSTALL;
1410 i++;
1411#endif
1335 } else if ((strcmp(argv[i],"-d")==0) || 1412 } else if ((strcmp(argv[i],"-d")==0) ||
1336 (strcmp(argv[i],"--delete-bootloader")==0)) { 1413 (strcmp(argv[i],"--delete-bootloader")==0)) {
1337 action = DELETE_BOOTLOADER; 1414 action = DELETE_BOOTLOADER;
@@ -1339,7 +1416,7 @@ int main(int argc, char* argv[])
1339 } else if ((strcmp(argv[i],"-a")==0) || 1416 } else if ((strcmp(argv[i],"-a")==0) ||
1340 (strcmp(argv[i],"--add-bootloader")==0)) { 1417 (strcmp(argv[i],"--add-bootloader")==0)) {
1341 action = ADD_BOOTLOADER; 1418 action = ADD_BOOTLOADER;
1342 type = DOT_IPOD; 1419 type = FILETYPE_DOT_IPOD;
1343 i++; 1420 i++;
1344 if (i == argc) { print_usage(); return 1; } 1421 if (i == argc) { print_usage(); return 1; }
1345 filename=argv[i]; 1422 filename=argv[i];
@@ -1347,7 +1424,7 @@ int main(int argc, char* argv[])
1347 } else if ((strcmp(argv[i],"-ab")==0) || 1424 } else if ((strcmp(argv[i],"-ab")==0) ||
1348 (strcmp(argv[i],"--add-bootloader-bin")==0)) { 1425 (strcmp(argv[i],"--add-bootloader-bin")==0)) {
1349 action = ADD_BOOTLOADER; 1426 action = ADD_BOOTLOADER;
1350 type = DOT_BIN; 1427 type = FILETYPE_DOT_BIN;
1351 i++; 1428 i++;
1352 if (i == argc) { print_usage(); return 1; } 1429 if (i == argc) { print_usage(); return 1; }
1353 filename=argv[i]; 1430 filename=argv[i];
@@ -1362,7 +1439,7 @@ int main(int argc, char* argv[])
1362 } else if ((strcmp(argv[i],"-wf")==0) || 1439 } else if ((strcmp(argv[i],"-wf")==0) ||
1363 (strcmp(argv[i],"--write-firmware")==0)) { 1440 (strcmp(argv[i],"--write-firmware")==0)) {
1364 action = WRITE_FIRMWARE; 1441 action = WRITE_FIRMWARE;
1365 type = DOT_IPOD; 1442 type = FILETYPE_DOT_IPOD;
1366 i++; 1443 i++;
1367 if (i == argc) { print_usage(); return 1; } 1444 if (i == argc) { print_usage(); return 1; }
1368 filename=argv[i]; 1445 filename=argv[i];
@@ -1370,7 +1447,7 @@ int main(int argc, char* argv[])
1370 } else if ((strcmp(argv[i],"-wfb")==0) || 1447 } else if ((strcmp(argv[i],"-wfb")==0) ||
1371 (strcmp(argv[i],"--write-firmware-bin")==0)) { 1448 (strcmp(argv[i],"--write-firmware-bin")==0)) {
1372 action = WRITE_FIRMWARE; 1449 action = WRITE_FIRMWARE;
1373 type = DOT_BIN; 1450 type = FILETYPE_DOT_BIN;
1374 i++; 1451 i++;
1375 if (i == argc) { print_usage(); return 1; } 1452 if (i == argc) { print_usage(); return 1; }
1376 filename=argv[i]; 1453 filename=argv[i];
@@ -1444,6 +1521,26 @@ int main(int argc, char* argv[])
1444 1521
1445 if (action==LIST_IMAGES) { 1522 if (action==LIST_IMAGES) {
1446 list_images(&ipod); 1523 list_images(&ipod);
1524#ifdef WITH_BOOTOBJS
1525 } else if (action==INTERACTIVE) {
1526
1527 printf("Do you wish to install the rockbox bootloader? (y/n) :");
1528 if (fgets(yesno,4,stdin)) {
1529 if (yesno[0]=='y') {
1530 if (ipod_reopen_rw(&ipod) < 0) {
1531 return 5;
1532 }
1533
1534 if (add_bootloader(&ipod, NULL, FILETYPE_INTERNAL)==0) {
1535 fprintf(stderr,"[INFO] Bootloader installed successfully.\n");
1536 } else {
1537 fprintf(stderr,"[ERR] --install failed.\n");
1538 }
1539 printf("Press ENTER to exit ipodpatcher :");
1540 fgets(yesno,4,stdin);
1541 }
1542 }
1543#endif
1447 } else if (action==DELETE_BOOTLOADER) { 1544 } else if (action==DELETE_BOOTLOADER) {
1448 if (ipod_reopen_rw(&ipod) < 0) { 1545 if (ipod_reopen_rw(&ipod) < 0) {
1449 return 5; 1546 return 5;
@@ -1468,6 +1565,18 @@ int main(int argc, char* argv[])
1468 } else { 1565 } else {
1469 fprintf(stderr,"[ERR] --add-bootloader failed.\n"); 1566 fprintf(stderr,"[ERR] --add-bootloader failed.\n");
1470 } 1567 }
1568#ifdef WITH_BOOTOBJS
1569 } else if (action==INSTALL) {
1570 if (ipod_reopen_rw(&ipod) < 0) {
1571 return 5;
1572 }
1573
1574 if (add_bootloader(&ipod, NULL, FILETYPE_INTERNAL)==0) {
1575 fprintf(stderr,"[INFO] Bootloader installed successfully.\n");
1576 } else {
1577 fprintf(stderr,"[ERR] --install failed.\n");
1578 }
1579#endif
1471 } else if (action==WRITE_FIRMWARE) { 1580 } else if (action==WRITE_FIRMWARE) {
1472 if (ipod_reopen_rw(&ipod) < 0) { 1581 if (ipod_reopen_rw(&ipod) < 0) {
1473 return 5; 1582 return 5;