diff options
author | Dave Chapman <dave@dchapman.com> | 2007-02-08 18:05:50 +0000 |
---|---|---|
committer | Dave Chapman <dave@dchapman.com> | 2007-02-08 18:05:50 +0000 |
commit | bdc27ff20c3666989cd8ba83fc9a43c25382ced4 (patch) | |
tree | fb66ef4d48bc2c2a97ac68fe78c8bb2901f296e0 /tools | |
parent | deb83637512488b42a848ced66d039fa8df0f428 (diff) | |
download | rockbox-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
Diffstat (limited to 'tools')
-rw-r--r-- | tools/ipodpatcher/Makefile | 48 | ||||
-rw-r--r-- | tools/ipodpatcher/ipod2c.c | 139 | ||||
-rw-r--r-- | tools/ipodpatcher/ipodio.h | 4 | ||||
-rw-r--r-- | tools/ipodpatcher/ipodpatcher.c | 257 |
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 @@ CFLAGS=-Wall +BOOT_H = ipod3g.h ipod4g.h ipodcolor.h ipodmini.h ipodmini2g.h ipodnano.h ipodvideo.h + +# Uncomment the next two lines to build with embedded bootloaders and the +# --install option and interactive mode. You need the full set of Rockbox +# bootloaders in this directory - download them from +# http://download.rockbox.org/bootloader/ipod/bootloaders.zip + +BOOTSRC = ipod3g.c ipod4g.c ipodcolor.c ipodmini.c ipodmini2g.c ipodnano.c ipodvideo.c +CFLAGS += -DWITH_BOOTOBJS + ifeq ($(findstring CYGWIN,$(shell uname)),CYGWIN) OUTPUT=ipodpatcher.exe CROSS= @@ -9,15 +19,43 @@ OUTPUT=ipodpatcher CROSS=i586-mingw32msvc- endif +NATIVECC = gcc +CC = $(CROSS)gcc + all: $(OUTPUT) -ipodpatcher: ipodpatcher.c ipodio-posix.c parttypes.h - gcc $(CFLAGS) -o ipodpatcher ipodpatcher.c ipodio-posix.c +ipodpatcher: ipodpatcher.c ipodio-posix.c parttypes.h $(BOOTSRC) + gcc $(CFLAGS) -o ipodpatcher ipodpatcher.c ipodio-posix.c $(BOOTSRC) strip ipodpatcher -ipodpatcher.exe: ipodpatcher.c ipodio-win32.c parttypes.h - $(CROSS)gcc $(CFLAGS) -o ipodpatcher.exe ipodpatcher.c ipodio-win32.c +ipodpatcher.exe: ipodpatcher.c ipodio-win32.c parttypes.h $(BOOTSRC) + $(CC) $(CFLAGS) -o ipodpatcher.exe ipodpatcher.c ipodio-win32.c $(BOOTSRC) $(CROSS)strip ipodpatcher.exe +ipod2c: ipod2c.c + $(NATIVECC) $(CFLAGS) -o ipod2c ipod2c.c + +ipod3g.c: bootloader-ipod3g.ipod ipod2c + ./ipod2c bootloader-ipod3g.ipod ipod3g + +ipod4g.c: bootloader-ipod4g.ipod ipod2c + ./ipod2c bootloader-ipod4g.ipod ipod4g + +ipodcolor.c: bootloader-ipodcolor.ipod ipod2c + ./ipod2c bootloader-ipodcolor.ipod ipodcolor + +ipodmini.c: bootloader-ipodmini.ipod ipod2c + ./ipod2c bootloader-ipodmini.ipod ipodmini + +ipodmini2g.c: bootloader-ipodmini2g.ipod ipod2c + ./ipod2c bootloader-ipodmini2g.ipod ipodmini2g + +ipodnano.c: bootloader-ipodnano.ipod ipod2c + ./ipod2c bootloader-ipodnano.ipod ipodnano + +ipodvideo.c: bootloader-ipodvideo.ipod ipod2c + ./ipod2c bootloader-ipodvideo.ipod ipodvideo + + clean: - rm -f ipodpatcher.exe ipodpatcher *~ + 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 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id: ipodio-win32.c 12205 2007-02-05 01:20:20Z dave $ + * + * Copyright (C) 2007 Dave Chapman + * + * All files in this archive are subject to the GNU General Public License. + * See the file COPYING in the source tree root for full license agreement. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ****************************************************************************/ + +#include <stdio.h> +#include <string.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <unistd.h> +#include <fcntl.h> +#include <stdlib.h> + +#ifndef O_BINARY +#define O_BINARY 0 +#endif + +static off_t filesize(int fd) +{ + struct stat buf; + + fstat(fd,&buf); + return buf.st_size; +} + +static int write_cfile(unsigned char* buf, off_t len, char* cname) +{ + char filename[256]; + FILE* fp; + int i; + + snprintf(filename,256,"%s.c",cname); + + fp = fopen(filename,"w+"); + if (fp == NULL) { + fprintf(stderr,"Couldn't open %s\n",filename); + return -1; + } + + fprintf(fp,"/* Generated by ipod2c */\n\n"); + fprintf(fp,"unsigned char %s[] = {",cname); + + for (i=0;i<len;i++) { + if ((i % 16) == 0) { + fprintf(fp,"\n "); + } + if (i == (len-1)) { + fprintf(fp,"0x%02x",buf[i]); + } else { + fprintf(fp,"0x%02x, ",buf[i]); + } + } + fprintf(fp,"\n};\n"); + + fclose(fp); + return 0; +} + +static int write_hfile(unsigned char* buf, off_t len, char* cname) +{ + char filename[256]; + FILE* fp; + + snprintf(filename,256,"%s.h",cname); + fp = fopen(filename,"w+"); + if (fp == NULL) { + fprintf(stderr,"Couldn't open %s\n",filename); + return -1; + } + + fprintf(fp,"/* Generated by ipod2c */\n\n"); + fprintf(fp,"#define LEN_%s %d\n",cname,(int)len); + fprintf(fp,"extern unsigned char %s[];\n",cname); + fclose(fp); + return 0; +} + +int main (int argc, char* argv[]) +{ + char* infile; + char* cname; + int fd; + unsigned char* buf; + int len; + int n; + + if (argc != 3) { + fprintf(stderr,"Usage: ipod2c file.bin cname\n"); + return 0; + } + + infile=argv[1]; + cname=argv[2]; + + fd = open(infile,O_RDONLY); + if (fd < 0) { + fprintf(stderr,"Can not open %s\n",infile); + return 0; + } + + len = filesize(fd) - 8; + + n = lseek(fd,8,SEEK_SET); + if (n != 8) { + fprintf(stderr,"Seek failed\n"); + return 0; + } + + buf = malloc(len); + n = read(fd,buf,len); + if (n < len) { + fprintf(stderr,"Short read, aborting\n"); + return 0; + } + close(fd); + + if (write_cfile(buf,len,cname) < 0) { + return -1; + } + if (write_hfile(buf,len,cname) < 0) { + return -1; + } + + return 0; +} 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 { char* modelname; char* modelstr; int macpod; +#ifdef WITH_BOOTOBJS + unsigned char* bootloader; + int bootloader_len; +#endif }; void 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 @@ #include "parttypes.h" #include "ipodio.h" +#ifdef WITH_BOOTOBJS +#include "ipod3g.h" +#include "ipod4g.h" +#include "ipodmini.h" +#include "ipodmini2g.h" +#include "ipodcolor.h" +#include "ipodnano.h" +#include "ipodvideo.h" +#endif + #define VERSION "0.8svn" int verbose = 0; @@ -401,12 +411,15 @@ void print_usage(void) { fprintf(stderr,"Usage: ipodpatcher --scan\n"); #ifdef __WIN32__ - fprintf(stderr," or ipodpatcher DISKNO [action]\n"); + fprintf(stderr," or ipodpatcher [DISKNO] [action]\n"); #else - fprintf(stderr," or ipodpatcher device [action]\n"); + fprintf(stderr," or ipodpatcher [device] [action]\n"); #endif fprintf(stderr,"\n"); fprintf(stderr,"Where [action] is one of the following options:\n"); +#ifdef WITH_BOOTOBJS + fprintf(stderr," --install\n"); +#endif fprintf(stderr," -l, --list\n"); fprintf(stderr," -r, --read-partition bootpartition.bin\n"); fprintf(stderr," -w, --write-partition bootpartition.bin\n"); @@ -439,6 +452,10 @@ void print_usage(void) enum { NONE, +#ifdef WITH_BOOTOBJS + INSTALL, +#endif + INTERACTIVE, SHOW_INFO, LIST_IMAGES, DELETE_BOOTLOADER, @@ -449,8 +466,11 @@ enum { WRITE_PARTITION }; -#define DOT_IPOD 0 -#define DOT_BIN 1 +#define FILETYPE_DOT_IPOD 0 +#define FILETYPE_DOT_BIN 1 +#ifdef WITH_BOOTOBJS + #define FILETYPE_INTERNAL 2 +#endif char* ftypename[] = { "OSOS", "RSRC", "AUPD", "HIBE" }; @@ -548,70 +568,82 @@ int add_bootloader(struct ipod_t* ipod, char* filename, int type) unsigned long filechksum=0; unsigned char header[8]; /* Header for .ipod file */ - infile=open(filename,O_RDONLY); - if (infile < 0) { - fprintf(stderr,"[ERR] Couldn't open input file %s\n",filename); - return -1; + /* Calculate the position in the OSOS image where our bootloader will go. */ + if (ipod->ipod_directory[0].entryOffset>0) { + /* Keep the same entryOffset */ + entryOffset = ipod->ipod_directory[0].entryOffset; + } else { + entryOffset = (ipod->ipod_directory[0].len+ipod->sector_size-1)&~(ipod->sector_size-1); } - if (type==DOT_IPOD) { - /* First check that the input file is the correct type for this ipod. */ - n = read(infile,header,8); - if (n < 8) { - fprintf(stderr,"[ERR] Failed to read header from %s\n",filename); - close(infile); +#ifdef WITH_BOOTOBJS + if (type == FILETYPE_INTERNAL) { + fprintf(stderr,"[INFO] Using internal bootloader - %d bytes\n",ipod->bootloader_len); + memcpy(sectorbuf+entryOffset,ipod->bootloader,ipod->bootloader_len); + length = ipod->bootloader_len; + paddedlength=(ipod->bootloader_len+ipod->sector_size-1)&~(ipod->sector_size-1); + } + else +#endif + { + infile=open(filename,O_RDONLY); + if (infile < 0) { + fprintf(stderr,"[ERR] Couldn't open input file %s\n",filename); return -1; } - if (memcmp(header+4, ipod->modelname,4)!=0) { - fprintf(stderr,"[ERR] Model name in input file (%c%c%c%c) doesn't match ipod model (%s)\n", - header[4],header[5],header[6],header[7], ipod->modelname); - close(infile); - return -1; + if (type==FILETYPE_DOT_IPOD) { + /* First check that the input file is the correct type for this ipod. */ + n = read(infile,header,8); + if (n < 8) { + fprintf(stderr,"[ERR] Failed to read header from %s\n",filename); + close(infile); + return -1; + } + + if (memcmp(header+4, ipod->modelname,4)!=0) { + fprintf(stderr,"[ERR] Model name in input file (%c%c%c%c) doesn't match ipod model (%s)\n", + header[4],header[5],header[6],header[7], ipod->modelname); + close(infile); + return -1; + } + + filechksum = be2int(header); + + length=filesize(infile)-8; + } else { + length=filesize(infile); } - - filechksum = be2int(header); - - length=filesize(infile)-8; - } else { - length=filesize(infile); - } - paddedlength=(length+ipod->sector_size-1)&~(ipod->sector_size-1); - - /* Now read our bootloader - we need to check it before modifying the partition*/ - n = read(infile,sectorbuf,length); - if (n < 0) { - fprintf(stderr,"[ERR] Couldn't read input file\n"); + paddedlength=(length+ipod->sector_size-1)&~(ipod->sector_size-1); + + /* Now read our bootloader - we need to check it before modifying the partition*/ + n = read(infile,sectorbuf+entryOffset,length); close(infile); - return -1; - } - - if (type==DOT_IPOD) { - /* Calculate and confirm bootloader checksum */ - chksum = ipod->modelnum; - for (i = 0; i < length; i++) { - /* add 8 unsigned bits but keep a 32 bit sum */ - chksum += sectorbuf[i]; - } - if (chksum == filechksum) { - fprintf(stderr,"[INFO] Checksum OK in %s\n",filename); - } else { - fprintf(stderr,"[ERR] Checksum in %s failed check\n",filename); + if (n < 0) { + fprintf(stderr,"[ERR] Couldn't read input file\n"); return -1; } - } - - if (ipod->ipod_directory[0].entryOffset>0) { - /* Keep the same entryOffset */ - entryOffset = ipod->ipod_directory[0].entryOffset; - } else { - entryOffset = (ipod->ipod_directory[0].len+ipod->sector_size-1)&~(ipod->sector_size-1); + + if (type==FILETYPE_DOT_IPOD) { + /* Calculate and confirm bootloader checksum */ + chksum = ipod->modelnum; + for (i = entryOffset; i < entryOffset+length; i++) { + /* add 8 unsigned bits but keep a 32 bit sum */ + chksum += sectorbuf[i]; + } + + if (chksum == filechksum) { + fprintf(stderr,"[INFO] Checksum OK in %s\n",filename); + } else { + fprintf(stderr,"[ERR] Checksum in %s failed check\n",filename); + return -1; + } + } } if (entryOffset+paddedlength > BUFFER_SIZE) { fprintf(stderr,"[ERR] Input file too big for buffer\n"); - close(infile); return -1; } @@ -624,14 +656,13 @@ int add_bootloader(struct ipod_t* ipod, char* filename, int type) /* Check if we have enough space */ /* TODO: Check the size of the partition. */ if (ipod->nimages > 1) { - if ((ipod->ipod_directory[0].devOffset+entryOffset+paddedlength) >= + if ((ipod->ipod_directory[0].devOffset+entryOffset+paddedlength) > ipod->ipod_directory[1].devOffset) { fprintf(stderr,"[INFO] Moving images to create room for new firmware...\n"); delta = ipod->ipod_directory[0].devOffset + entryOffset+paddedlength - ipod->ipod_directory[1].devOffset; if (diskmove(ipod, delta) < 0) { - close(infile); fprintf(stderr,"[ERR] Image movement failed.\n"); return -1; } @@ -643,7 +674,6 @@ int add_bootloader(struct ipod_t* ipod, char* filename, int type) /* Firstly read the original firmware into sectorbuf */ fprintf(stderr,"[INFO] Reading original firmware...\n"); - if (ipod_seek(ipod, ipod->fwoffset+ipod->ipod_directory[0].devOffset) < 0) { fprintf(stderr,"[ERR] Seek failed\n"); return -1; @@ -660,16 +690,6 @@ int add_bootloader(struct ipod_t* ipod, char* filename, int type) return -1; } - /* Now read our bootloader - we need to seek back to the start */ - lseek(infile,(type == DOT_IPOD ? 8 : 0),SEEK_SET); - n = read(infile,sectorbuf+entryOffset,length); - if (n < 0) { - fprintf(stderr,"[ERR] Couldn't read input file\n"); - close(infile); - return -1; - } - close(infile); - /* Calculate new checksum for combined image */ chksum = 0; for (i=0;i<entryOffset + length; i++) { @@ -830,7 +850,7 @@ int write_firmware(struct ipod_t* ipod, char* filename, int type) return -1; } - if (type==DOT_IPOD) { + if (type==FILETYPE_DOT_IPOD) { n = read(infile,header,8); if (n < 8) { 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) } close(infile); - if (type==DOT_IPOD) { + if (type==FILETYPE_DOT_IPOD) { chksum = ipod->modelnum; for (i = 0; i < length; i++) { /* add 8 unsigned bits but keep a 32 bit sum */ @@ -1170,40 +1190,72 @@ int getmodel(struct ipod_t* ipod, int ipod_version) ipod->modelstr="3rd Generation"; ipod->modelnum = 7; ipod->modelname = "ip3g"; +#ifdef WITH_BOOTOBJS + ipod->bootloader = ipod3g; + ipod->bootloader_len = LEN_ipod3g; +#endif break; case 0x40: ipod->modelstr="1st Generation Mini"; ipod->modelnum = 9; ipod->modelname = "mini"; +#ifdef WITH_BOOTOBJS + ipod->bootloader = ipodmini; + ipod->bootloader_len = LEN_ipodmini; +#endif break; case 0x50: ipod->modelstr="4th Generation"; ipod->modelnum = 8; ipod->modelname = "ip4g"; +#ifdef WITH_BOOTOBJS + ipod->bootloader = ipod4g; + ipod->bootloader_len = LEN_ipod4g; +#endif break; case 0x60: ipod->modelstr="Photo/Color"; ipod->modelnum = 3; ipod->modelname = "ipco"; +#ifdef WITH_BOOTOBJS + ipod->bootloader = ipodcolor; + ipod->bootloader_len = LEN_ipodcolor; +#endif break; case 0x70: ipod->modelstr="2nd Generation Mini"; ipod->modelnum = 11; ipod->modelname = "mn2g"; +#ifdef WITH_BOOTOBJS + ipod->bootloader = ipodmini2g; + ipod->bootloader_len = LEN_ipodmini2g; +#endif break; case 0xc0: ipod->modelstr="1st Generation Nano"; ipod->modelnum = 4; ipod->modelname = "nano"; +#ifdef WITH_BOOTOBJS + ipod->bootloader = ipodnano; + ipod->bootloader_len = LEN_ipodnano; +#endif break; case 0xb0: ipod->modelstr="Video (aka 5th Generation)"; ipod->modelnum = 5; ipod->modelname = "ipvd"; +#ifdef WITH_BOOTOBJS + ipod->bootloader = ipodvideo; + ipod->bootloader_len = LEN_ipodvideo; +#endif break; default: ipod->modelname = NULL; ipod->modelnum = 0; +#ifdef WITH_BOOTOBJS + ipod->bootloader = NULL; + ipod->bootloader_len = 0; +#endif return -1; } return 0; @@ -1279,6 +1331,9 @@ int ipod_scan(struct ipod_t* ipod) int main(int argc, char* argv[]) { +#ifdef WITH_BOOTOBJS + char yesno[4]; +#endif int i; int n; int infile, outfile; @@ -1320,18 +1375,40 @@ int main(int argc, char* argv[]) n = ipod_scan(&ipod); if (n==0) { fprintf(stderr,"[ERR] No ipods found, aborting\n"); - return 0; + fprintf(stderr,"[ERR] Please connect your ipod and ensure it is in disk mode\n"); } else if (n > 1) { fprintf(stderr,"[ERR] %d ipods found, aborting\n",n); + fprintf(stderr,"[ERR] Please connect only one ipod.\n"); + } + + if (n != 1) { +#ifdef WITH_BOOTOBJS + if (argc==1) { + printf("\nPress ENTER to exit ipodpatcher :"); + fgets(yesno,4,stdin); + } +#endif return 0; } + i = 1; } +#ifdef WITH_BOOTOBJS + action = INTERACTIVE; +#else + action = NONE; +#endif + while (i < argc) { if ((strcmp(argv[i],"-l")==0) || (strcmp(argv[i],"--list")==0)) { action = LIST_IMAGES; i++; +#ifdef WITH_BOOTOBJS + } else if (strcmp(argv[i],"--install")==0) { + action = INSTALL; + i++; +#endif } else if ((strcmp(argv[i],"-d")==0) || (strcmp(argv[i],"--delete-bootloader")==0)) { action = DELETE_BOOTLOADER; @@ -1339,7 +1416,7 @@ int main(int argc, char* argv[]) } else if ((strcmp(argv[i],"-a")==0) || (strcmp(argv[i],"--add-bootloader")==0)) { action = ADD_BOOTLOADER; - type = DOT_IPOD; + type = FILETYPE_DOT_IPOD; i++; if (i == argc) { print_usage(); return 1; } filename=argv[i]; @@ -1347,7 +1424,7 @@ int main(int argc, char* argv[]) } else if ((strcmp(argv[i],"-ab")==0) || (strcmp(argv[i],"--add-bootloader-bin")==0)) { action = ADD_BOOTLOADER; - type = DOT_BIN; + type = FILETYPE_DOT_BIN; i++; if (i == argc) { print_usage(); return 1; } filename=argv[i]; @@ -1362,7 +1439,7 @@ int main(int argc, char* argv[]) } else if ((strcmp(argv[i],"-wf")==0) || (strcmp(argv[i],"--write-firmware")==0)) { action = WRITE_FIRMWARE; - type = DOT_IPOD; + type = FILETYPE_DOT_IPOD; i++; if (i == argc) { print_usage(); return 1; } filename=argv[i]; @@ -1370,7 +1447,7 @@ int main(int argc, char* argv[]) } else if ((strcmp(argv[i],"-wfb")==0) || (strcmp(argv[i],"--write-firmware-bin")==0)) { action = WRITE_FIRMWARE; - type = DOT_BIN; + type = FILETYPE_DOT_BIN; i++; if (i == argc) { print_usage(); return 1; } filename=argv[i]; @@ -1444,6 +1521,26 @@ int main(int argc, char* argv[]) if (action==LIST_IMAGES) { list_images(&ipod); +#ifdef WITH_BOOTOBJS + } else if (action==INTERACTIVE) { + + printf("Do you wish to install the rockbox bootloader? (y/n) :"); + if (fgets(yesno,4,stdin)) { + if (yesno[0]=='y') { + if (ipod_reopen_rw(&ipod) < 0) { + return 5; + } + + if (add_bootloader(&ipod, NULL, FILETYPE_INTERNAL)==0) { + fprintf(stderr,"[INFO] Bootloader installed successfully.\n"); + } else { + fprintf(stderr,"[ERR] --install failed.\n"); + } + printf("Press ENTER to exit ipodpatcher :"); + fgets(yesno,4,stdin); + } + } +#endif } else if (action==DELETE_BOOTLOADER) { if (ipod_reopen_rw(&ipod) < 0) { return 5; @@ -1468,6 +1565,18 @@ int main(int argc, char* argv[]) } else { fprintf(stderr,"[ERR] --add-bootloader failed.\n"); } +#ifdef WITH_BOOTOBJS + } else if (action==INSTALL) { + if (ipod_reopen_rw(&ipod) < 0) { + return 5; + } + + if (add_bootloader(&ipod, NULL, FILETYPE_INTERNAL)==0) { + fprintf(stderr,"[INFO] Bootloader installed successfully.\n"); + } else { + fprintf(stderr,"[ERR] --install failed.\n"); + } +#endif } else if (action==WRITE_FIRMWARE) { if (ipod_reopen_rw(&ipod) < 0) { return 5; |