forked from len0rd/rockbox
Implement the add/delete bootloader functionality.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@11765 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
parent
da945c0873
commit
75a11124f0
1 changed files with 421 additions and 59 deletions
|
|
@ -31,7 +31,7 @@
|
|||
|
||||
#define VERSION "0.5"
|
||||
|
||||
//#define DEBUG
|
||||
int verbose = 0;
|
||||
|
||||
/* The following string appears at the start of the firmware partition */
|
||||
static const char *apple_stop_sign = "{{~~ /-----\\ "\
|
||||
|
|
@ -337,8 +337,8 @@ void print_usage(void) {
|
|||
fprintf(stderr," -l, --list\n");
|
||||
fprintf(stderr," -r, --read-partition bootpartition.bin\n");
|
||||
fprintf(stderr," -w, --write-partition bootpartition.bin\n");
|
||||
fprintf(stderr," -ef, --extract-firmware filename.ipod\n");
|
||||
fprintf(stderr," -rf, --replace-firmware filename.ipod\n");
|
||||
fprintf(stderr," -rf, --read-firmware filename.ipod\n");
|
||||
fprintf(stderr," -wf, --write-firmware filename.ipod\n");
|
||||
fprintf(stderr," -a, --add-bootloader filename.ipod\n");
|
||||
fprintf(stderr," -d, --delete-bootloader\n");
|
||||
fprintf(stderr,"\n");
|
||||
|
|
@ -360,10 +360,10 @@ enum {
|
|||
NONE,
|
||||
SHOW_INFO,
|
||||
LIST_IMAGES,
|
||||
REMOVE_BOOTLOADER,
|
||||
INSERT_BOOTLOADER,
|
||||
EXTRACT_FIRMWARE,
|
||||
REPLACE_FIRMWARE,
|
||||
DELETE_BOOTLOADER,
|
||||
ADD_BOOTLOADER,
|
||||
READ_FIRMWARE,
|
||||
WRITE_FIRMWARE,
|
||||
READ_PARTITION,
|
||||
WRITE_PARTITION
|
||||
};
|
||||
|
|
@ -389,16 +389,344 @@ struct ipod_directory_t {
|
|||
uint32_t loadAddr;
|
||||
};
|
||||
|
||||
int remove_bootloader(HANDLE dh, int start, int sector_size,
|
||||
struct ipod_directory_t* ipod_directory)
|
||||
|
||||
int diskmove(HANDLE dh, int start, int nimages, struct ipod_directory_t* ipod_directory,
|
||||
int sector_size,int delta)
|
||||
{
|
||||
fprintf(stderr,"[ERR] Sorry, not yet implemented.\n");
|
||||
return -1;
|
||||
int src_start;
|
||||
int src_end;
|
||||
int dest_start;
|
||||
int dest_end;
|
||||
int bytesleft;
|
||||
int chunksize;
|
||||
int i;
|
||||
int n;
|
||||
|
||||
src_start = start + ipod_directory[1].devOffset + sector_size;
|
||||
src_end = (start + ipod_directory[nimages-1].devOffset + sector_size + ipod_directory[nimages-1].len + (sector_size-1)) & ~(sector_size-1);
|
||||
bytesleft = src_end - src_start;
|
||||
dest_start = start + src_start + delta;
|
||||
dest_end = start + src_end + delta;
|
||||
|
||||
if (verbose) {
|
||||
fprintf(stderr,"[INFO] Need to move images 2-%d forward %08x bytes\n",nimages,delta);
|
||||
fprintf(stderr,"[VERB] src_start = %08x\n",src_start);
|
||||
fprintf(stderr,"[VERB] src_end = %08x\n",src_end);
|
||||
fprintf(stderr,"[VERB] dest_start = %08x\n",dest_start);
|
||||
fprintf(stderr,"[VERB] dest_end = %08x\n",dest_end);
|
||||
fprintf(stderr,"[VERB] bytes to copy = %08x\n",bytesleft);
|
||||
}
|
||||
|
||||
while (bytesleft > 0) {
|
||||
if (bytesleft <= BUFFER_SIZE) {
|
||||
chunksize = bytesleft;
|
||||
} else {
|
||||
chunksize = BUFFER_SIZE;
|
||||
}
|
||||
|
||||
if (verbose) {
|
||||
fprintf(stderr,"[VERB] Copying %08x bytes from %08x to %08x\n",
|
||||
chunksize,
|
||||
dest_end-chunksize,
|
||||
dest_end-chunksize+delta);
|
||||
}
|
||||
|
||||
|
||||
if (ipod_seek(dh,dest_end-chunksize) < 0) {
|
||||
fprintf(stderr,"[ERR] Seek failed\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ((n = ipod_read(dh,sectorbuf,chunksize)) < 0) {
|
||||
perror("[ERR] Write failed\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (n < chunksize) {
|
||||
fprintf(stderr,"[ERR] Short read - requested %d bytes, received %d\n",
|
||||
i,n);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (ipod_seek(dh,dest_end-chunksize+delta) < 0) {
|
||||
fprintf(stderr,"[ERR] Seek failed\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ((n = ipod_write(dh,sectorbuf,chunksize)) < 0) {
|
||||
perror("[ERR] Write failed\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (n < chunksize) {
|
||||
fprintf(stderr,"[ERR] Short write - requested %d bytes, received %d\n"
|
||||
,i,n);
|
||||
return -1;
|
||||
}
|
||||
|
||||
dest_end -= chunksize;
|
||||
bytesleft -= chunksize;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int replace_firmware(HANDLE dh, char* filename, int start, int sector_size,
|
||||
int nimages, struct ipod_directory_t* ipod_directory,
|
||||
off_t diroffset, int modelnum, char* modelname)
|
||||
int add_bootloader(HANDLE dh, char* filename, int start, int sector_size,
|
||||
int nimages, struct ipod_directory_t* ipod_directory,
|
||||
off_t diroffset, int modelnum, char* modelname)
|
||||
{
|
||||
int length;
|
||||
int i;
|
||||
int n;
|
||||
int infile;
|
||||
int paddedlength;
|
||||
int entryOffset;
|
||||
int delta = 0;
|
||||
unsigned long chksum=0;
|
||||
unsigned long filechksum=0;
|
||||
unsigned char header[8]; /* Header for .ipod file */
|
||||
|
||||
/* First check that the input file is the correct type for this ipod. */
|
||||
infile=open(filename,O_RDONLY);
|
||||
if (infile < 0) {
|
||||
fprintf(stderr,"[ERR] Couldn't open input file %s\n",filename);
|
||||
return -1;
|
||||
}
|
||||
|
||||
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,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],modelname);
|
||||
close(infile);
|
||||
return -1;
|
||||
}
|
||||
|
||||
filechksum = be2int(header);
|
||||
|
||||
length=filesize(infile)-8;
|
||||
paddedlength=(length+sector_size-1)&~(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");
|
||||
close(infile);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Calculate and confirm bootloader checksum */
|
||||
chksum = 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);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (ipod_directory[0].entryOffset>0) {
|
||||
/* Keep the same entryOffset */
|
||||
entryOffset = ipod_directory[0].entryOffset;
|
||||
} else {
|
||||
entryOffset = (ipod_directory[0].len+sector_size-1)&~(sector_size-1);
|
||||
}
|
||||
|
||||
if (entryOffset+paddedlength > BUFFER_SIZE) {
|
||||
fprintf(stderr,"[ERR] Input file too big for buffer\n");
|
||||
close(infile);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (verbose) {
|
||||
fprintf(stderr,"[VERB] Original firmware begins at 0x%08x\n",ipod_directory[0].devOffset + sector_size);
|
||||
fprintf(stderr,"[VERB] New entryOffset will be 0x%08x\n",entryOffset);
|
||||
fprintf(stderr,"[VERB] End of bootloader will be at 0x%08x\n",entryOffset+paddedlength);
|
||||
}
|
||||
|
||||
/* Check if we have enough space */
|
||||
/* TODO: Check the size of the partition. */
|
||||
if (nimages > 1) {
|
||||
if ((entryOffset+paddedlength) >= ipod_directory[1].devOffset) {
|
||||
fprintf(stderr,"[INFO] Moving images to create room for new firmware...\n");
|
||||
delta = entryOffset+paddedlength-ipod_directory[1].devOffset;
|
||||
|
||||
if (diskmove(dh,start,nimages,ipod_directory,sector_size,delta) < 0) {
|
||||
close(infile);
|
||||
fprintf(stderr,"[ERR] Image movement failed.\n");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* We have moved the partitions, now we can write our bootloader */
|
||||
|
||||
/* Firstly read the original firmware into sectorbuf */
|
||||
fprintf(stderr,"[INFO] Reading original firmware...\n");
|
||||
|
||||
if (ipod_seek(dh,start+sector_size+ipod_directory[0].devOffset) < 0) {
|
||||
fprintf(stderr,"[ERR] Seek failed\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ((n = ipod_read(dh,sectorbuf,entryOffset)) < 0) {
|
||||
perror("[ERR] Read failed\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (n < entryOffset) {
|
||||
fprintf(stderr,"[ERR] Short read - requested %d bytes, received %d\n"
|
||||
,i,n);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Now read our bootloader - we need to seek back to 8 bytes from start */
|
||||
lseek(infile,8,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++) {
|
||||
chksum += sectorbuf[i];
|
||||
}
|
||||
|
||||
/* Now write the combined firmware image to the disk */
|
||||
|
||||
if (ipod_seek(dh,start+sector_size+ipod_directory[0].devOffset) < 0) {
|
||||
fprintf(stderr,"[ERR] Seek failed\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ((n = ipod_write(dh,sectorbuf,entryOffset+paddedlength)) < 0) {
|
||||
perror("[ERR] Write failed\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (n < (entryOffset+paddedlength)) {
|
||||
fprintf(stderr,"[ERR] Short read - requested %d bytes, received %d\n"
|
||||
,i,n);
|
||||
return -1;
|
||||
}
|
||||
|
||||
fprintf(stderr,"[INFO] Wrote %d bytes to firmware partition\n",entryOffset+paddedlength);
|
||||
|
||||
|
||||
/* Read directory */
|
||||
if (ipod_seek(dh,start + diroffset) < 0) { return -1; }
|
||||
|
||||
n=ipod_read(dh, sectorbuf, sector_size);
|
||||
if (n < 0) { return -1; }
|
||||
|
||||
/* Update entries for image 0 */
|
||||
int2le(entryOffset+length,sectorbuf+16);
|
||||
int2le(entryOffset,sectorbuf+24);
|
||||
int2le(chksum,sectorbuf+28);
|
||||
|
||||
/* Update devOffset entries for other images, if we have moved them */
|
||||
if (delta > 0) {
|
||||
for (i=1;i<nimages;i++) {
|
||||
int2le(le2int(sectorbuf+i*40+12)+delta,sectorbuf+i*40+12);
|
||||
}
|
||||
}
|
||||
|
||||
/* Write directory */
|
||||
if (ipod_seek(dh,start + diroffset) < 0) { return -1; }
|
||||
n=ipod_write(dh, sectorbuf, sector_size);
|
||||
if (n < 0) { return -1; }
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int delete_bootloader(HANDLE dh, int start, int sector_size, off_t diroffset,
|
||||
struct ipod_directory_t* ipod_directory)
|
||||
{
|
||||
int length;
|
||||
int i;
|
||||
int n;
|
||||
unsigned long chksum=0; /* 32 bit checksum - Rockbox .ipod style*/
|
||||
|
||||
/* Removing the bootloader involves adjusting the "length",
|
||||
"chksum" and "entryOffset" values in the osos image's directory
|
||||
entry. */
|
||||
|
||||
/* Firstly check we have a bootloader... */
|
||||
|
||||
if (ipod_directory[0].entryOffset == 0) {
|
||||
fprintf(stderr,"[ERR] No bootloader found.\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
length = ipod_directory[0].entryOffset;
|
||||
|
||||
/* Read the firmware so we can calculate the checksum */
|
||||
fprintf(stderr,"[INFO] Reading firmware (%d bytes)\n",length);
|
||||
|
||||
if (ipod_seek(dh,start+sector_size+ipod_directory[0].devOffset) < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
i = (length+sector_size-1) & ~(sector_size-1);
|
||||
fprintf(stderr,"[INFO] Padding read from 0x%08x to 0x%08x bytes\n",
|
||||
length,i);
|
||||
|
||||
if ((n = ipod_read(dh,sectorbuf,i)) < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (n < i) {
|
||||
fprintf(stderr,"[ERR] Short read - requested %d bytes, received %d\n",
|
||||
i,n);
|
||||
return -1;
|
||||
}
|
||||
|
||||
chksum = 0;
|
||||
for (i = 0; i < length; i++) {
|
||||
/* add 8 unsigned bits but keep a 32 bit sum */
|
||||
chksum += sectorbuf[i];
|
||||
}
|
||||
|
||||
/* Now write back the updated directory entry */
|
||||
|
||||
fprintf(stderr,"[INFO] Updating firmware checksum\n");
|
||||
|
||||
/* Read directory */
|
||||
if (ipod_seek(dh,start + diroffset) < 0) { return -1; }
|
||||
|
||||
n=ipod_read(dh, sectorbuf, sector_size);
|
||||
if (n < 0) { return -1; }
|
||||
|
||||
/* Update entries for image 0 */
|
||||
int2le(length,sectorbuf+16);
|
||||
int2le(0,sectorbuf+24);
|
||||
int2le(chksum,sectorbuf+28);
|
||||
|
||||
/* Write directory */
|
||||
if (ipod_seek(dh,start + diroffset) < 0) { return -1; }
|
||||
n=ipod_write(dh, sectorbuf, sector_size);
|
||||
if (n < 0) { return -1; }
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int write_firmware(HANDLE dh, char* filename, int start, int sector_size,
|
||||
int nimages, struct ipod_directory_t* ipod_directory,
|
||||
off_t diroffset, int modelnum, char* modelname)
|
||||
{
|
||||
int length;
|
||||
int i;
|
||||
|
|
@ -414,11 +742,14 @@ int replace_firmware(HANDLE dh, char* filename, int start, int sector_size,
|
|||
infile=open(filename,O_RDONLY);
|
||||
if (infile < 0) {
|
||||
fprintf(stderr,"[ERR] Couldn't open input file %s\n",filename);
|
||||
return -1;
|
||||
}
|
||||
|
||||
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,modelname,4)!=0) {
|
||||
|
|
@ -523,7 +854,7 @@ int replace_firmware(HANDLE dh, char* filename, int start, int sector_size,
|
|||
return 0;
|
||||
}
|
||||
|
||||
int extract_firmware(HANDLE dh, char* filename, int start, int sector_size,
|
||||
int read_firmware(HANDLE dh, char* filename, int start, int sector_size,
|
||||
struct ipod_directory_t* ipod_directory,
|
||||
int modelnum, char* modelname)
|
||||
{
|
||||
|
|
@ -661,22 +992,22 @@ int list_images(int nimages, struct ipod_directory_t* ipod_directory,
|
|||
{
|
||||
int i;
|
||||
|
||||
#ifdef DEBUG
|
||||
printf(" Type id devOffset len addr entryOffset chksum vers loadAddr devOffset+len\n");
|
||||
for (i = 0 ; i < nimages; i++) {
|
||||
printf("%d - %s 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x\n",i,
|
||||
ftypename[ipod_directory[i].ftype],
|
||||
ipod_directory[i].id,
|
||||
ipod_directory[i].devOffset,
|
||||
ipod_directory[i].len,
|
||||
ipod_directory[i].addr,
|
||||
ipod_directory[i].entryOffset,
|
||||
ipod_directory[i].chksum,
|
||||
ipod_directory[i].vers,
|
||||
ipod_directory[i].loadAddr,
|
||||
ipod_directory[i].devOffset+sector_size+((ipod_directory[i].len+sector_size-1)&~(sector_size-1)));
|
||||
if (verbose) {
|
||||
printf(" Type id devOffset len addr entryOffset chksum vers loadAddr devOffset+len\n");
|
||||
for (i = 0 ; i < nimages; i++) {
|
||||
printf("%d - %s 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x\n",i,
|
||||
ftypename[ipod_directory[i].ftype],
|
||||
ipod_directory[i].id,
|
||||
ipod_directory[i].devOffset,
|
||||
ipod_directory[i].len,
|
||||
ipod_directory[i].addr,
|
||||
ipod_directory[i].entryOffset,
|
||||
ipod_directory[i].chksum,
|
||||
ipod_directory[i].vers,
|
||||
ipod_directory[i].loadAddr,
|
||||
ipod_directory[i].devOffset+sector_size+((ipod_directory[i].len+sector_size-1)&~(sector_size-1)));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
printf("\n");
|
||||
printf("Listing firmware partition contents:\n");
|
||||
|
|
@ -732,7 +1063,8 @@ int main(int argc, char* argv[])
|
|||
fprintf(stderr,"This is free software; see the source for copying conditions. There is NO\n");
|
||||
fprintf(stderr,"warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\n");
|
||||
|
||||
if (argc < 2) {
|
||||
if ((argc < 2) || (strcmp(argv[1],"-h")==0) ||
|
||||
(strcmp(argv[1],"--help")==0)) {
|
||||
print_usage();
|
||||
return 1;
|
||||
}
|
||||
|
|
@ -751,19 +1083,27 @@ int main(int argc, char* argv[])
|
|||
if ((strcmp(argv[i],"-l")==0) || (strcmp(argv[i],"--list")==0)) {
|
||||
action = LIST_IMAGES;
|
||||
i++;
|
||||
} else if (strcmp(argv[i],"--remove-bootloader")==0) {
|
||||
action = REMOVE_BOOTLOADER;
|
||||
} else if ((strcmp(argv[i],"-d")==0) ||
|
||||
(strcmp(argv[i],"--delete-bootloader")==0)) {
|
||||
action = DELETE_BOOTLOADER;
|
||||
i++;
|
||||
} else if ((strcmp(argv[i],"-ef")==0) ||
|
||||
(strcmp(argv[i],"--extract-firmware")==0)) {
|
||||
action = EXTRACT_FIRMWARE;
|
||||
} else if ((strcmp(argv[i],"-a")==0) ||
|
||||
(strcmp(argv[i],"--add-bootloader")==0)) {
|
||||
action = ADD_BOOTLOADER;
|
||||
i++;
|
||||
if (i == argc) { print_usage(); return 1; }
|
||||
filename=argv[i];
|
||||
i++;
|
||||
} else if ((strcmp(argv[i],"-rf")==0) ||
|
||||
(strcmp(argv[i],"--replace-firmware")==0)) {
|
||||
action = REPLACE_FIRMWARE;
|
||||
(strcmp(argv[i],"--read-firmware")==0)) {
|
||||
action = READ_FIRMWARE;
|
||||
i++;
|
||||
if (i == argc) { print_usage(); return 1; }
|
||||
filename=argv[i];
|
||||
i++;
|
||||
} else if ((strcmp(argv[i],"-wf")==0) ||
|
||||
(strcmp(argv[i],"--write-firmware")==0)) {
|
||||
action = WRITE_FIRMWARE;
|
||||
i++;
|
||||
if (i == argc) { print_usage(); return 1; }
|
||||
filename=argv[i];
|
||||
|
|
@ -782,6 +1122,10 @@ int main(int argc, char* argv[])
|
|||
if (i == argc) { print_usage(); return 1; }
|
||||
filename=argv[i];
|
||||
i++;
|
||||
} else if ((strcmp(argv[i],"-v")==0) ||
|
||||
(strcmp(argv[i],"--verbose")==0)) {
|
||||
verbose++;
|
||||
i++;
|
||||
} else {
|
||||
print_usage(); return 1;
|
||||
}
|
||||
|
|
@ -868,34 +1212,52 @@ int main(int argc, char* argv[])
|
|||
|
||||
if (action==LIST_IMAGES) {
|
||||
list_images(nimages,ipod_directory,sector_size);
|
||||
} else if (action==REMOVE_BOOTLOADER) {
|
||||
if (ipod_directory[0].entryOffset==0) {
|
||||
fprintf(stderr,"[ERR] No bootloader detected.\n");
|
||||
} else {
|
||||
if (remove_bootloader(dh, pinfo[0].start*sector_size, sector_size,
|
||||
ipod_directory)==0) {
|
||||
fprintf(stderr,"[INFO] Bootloader removed.\n");
|
||||
}
|
||||
}
|
||||
} else if (action==REPLACE_FIRMWARE) {
|
||||
} else if (action==DELETE_BOOTLOADER) {
|
||||
if (ipod_reopen_rw(&dh, devicename) < 0) {
|
||||
return 5;
|
||||
}
|
||||
|
||||
if (replace_firmware(dh, filename,pinfo[0].start*sector_size,
|
||||
sector_size, nimages, ipod_directory, diroffset,
|
||||
modelnum, modelname)==0) {
|
||||
fprintf(stderr,"[INFO] Firmware replaced with %s.\n",filename);
|
||||
if (ipod_directory[0].entryOffset==0) {
|
||||
fprintf(stderr,"[ERR] No bootloader detected.\n");
|
||||
} else {
|
||||
fprintf(stderr,"[ERR] --replace-firmware failed.\n");
|
||||
if (delete_bootloader(dh, pinfo[0].start*sector_size, sector_size,
|
||||
diroffset, ipod_directory)==0) {
|
||||
fprintf(stderr,"[INFO] Bootloader removed.\n");
|
||||
} else {
|
||||
fprintf(stderr,"[ERR] --delete-bootloader failed.\n");
|
||||
}
|
||||
}
|
||||
} else if (action==EXTRACT_FIRMWARE) {
|
||||
if (extract_firmware(dh, filename,pinfo[0].start*sector_size,
|
||||
sector_size, ipod_directory, modelnum, modelname
|
||||
)==0) {
|
||||
fprintf(stderr,"[INFO] Firmware extracted to %s.\n",filename);
|
||||
} else if (action==ADD_BOOTLOADER) {
|
||||
if (ipod_reopen_rw(&dh, devicename) < 0) {
|
||||
return 5;
|
||||
}
|
||||
|
||||
if (add_bootloader(dh, filename,pinfo[0].start*sector_size,
|
||||
sector_size, nimages, ipod_directory, diroffset,
|
||||
modelnum, modelname)==0) {
|
||||
fprintf(stderr,"[INFO] Bootloader %s written to device.\n",filename);
|
||||
} else {
|
||||
fprintf(stderr,"[ERR] --extract-firmware failed.\n");
|
||||
fprintf(stderr,"[ERR] --add-bootloader failed.\n");
|
||||
}
|
||||
} else if (action==WRITE_FIRMWARE) {
|
||||
if (ipod_reopen_rw(&dh, devicename) < 0) {
|
||||
return 5;
|
||||
}
|
||||
|
||||
if (write_firmware(dh, filename,pinfo[0].start*sector_size,
|
||||
sector_size, nimages, ipod_directory, diroffset,
|
||||
modelnum, modelname)==0) {
|
||||
fprintf(stderr,"[INFO] Firmware %s written to device.\n",filename);
|
||||
} else {
|
||||
fprintf(stderr,"[ERR] --write-firmware failed.\n");
|
||||
}
|
||||
} else if (action==READ_FIRMWARE) {
|
||||
if (read_firmware(dh, filename,pinfo[0].start*sector_size,
|
||||
sector_size, ipod_directory, modelnum, modelname
|
||||
)==0) {
|
||||
fprintf(stderr,"[INFO] Firmware read to file %s.\n",filename);
|
||||
} else {
|
||||
fprintf(stderr,"[ERR] --read-firmware failed.\n");
|
||||
}
|
||||
} else if (action==READ_PARTITION) {
|
||||
outfile = open(filename,O_CREAT|O_WRONLY|O_BINARY,S_IREAD|S_IWRITE);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue