forked from len0rd/rockbox
Rename variables sectorbuf and verbose to avoid clashes in rbutil. Cleanup exports a bit.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@17730 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
parent
8436e29e7e
commit
d131a31266
8 changed files with 163 additions and 167 deletions
|
|
@ -82,7 +82,7 @@ uint32_t htole32(uint32_t x)
|
||||||
|
|
||||||
|
|
||||||
/* A large aligned buffer for disk I/O */
|
/* A large aligned buffer for disk I/O */
|
||||||
extern unsigned char* sectorbuf;
|
extern unsigned char* ipod_sectorbuf;
|
||||||
|
|
||||||
/* TODO: Pass these as parameters to the various create_ functions */
|
/* TODO: Pass these as parameters to the various create_ functions */
|
||||||
|
|
||||||
|
|
@ -160,7 +160,7 @@ static int zero_sectors(struct ipod_t* ipod, uint64_t sector, int count)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
memset(sectorbuf, 0, 128 * ipod->sector_size);
|
memset(ipod_sectorbuf, 0, 128 * ipod->sector_size);
|
||||||
|
|
||||||
/* Write 128 sectors at a time */
|
/* Write 128 sectors at a time */
|
||||||
while (count) {
|
while (count) {
|
||||||
|
|
@ -169,7 +169,7 @@ static int zero_sectors(struct ipod_t* ipod, uint64_t sector, int count)
|
||||||
else
|
else
|
||||||
n = count;
|
n = count;
|
||||||
|
|
||||||
if (ipod_write(ipod,sectorbuf,n * ipod->sector_size) < 0) {
|
if (ipod_write(ipod,ipod_sectorbuf,n * ipod->sector_size) < 0) {
|
||||||
perror("[ERR] Write failed in zero_sectors\n");
|
perror("[ERR] Write failed in zero_sectors\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
@ -478,15 +478,15 @@ int format_partition(struct ipod_t* ipod, int partition)
|
||||||
fprintf(stderr,"[INFO] Initialising reserved sectors and FATs...\n" );
|
fprintf(stderr,"[INFO] Initialising reserved sectors and FATs...\n" );
|
||||||
|
|
||||||
/* Create the boot sector structure */
|
/* Create the boot sector structure */
|
||||||
create_boot_sector(sectorbuf, ipod, partition);
|
create_boot_sector(ipod_sectorbuf, ipod, partition);
|
||||||
create_fsinfo(sectorbuf + 512);
|
create_fsinfo(ipod_sectorbuf + 512);
|
||||||
|
|
||||||
/* Write boot sector and fsinfo at start of partition */
|
/* Write boot sector and fsinfo at start of partition */
|
||||||
if (ipod_seek(ipod, ipod->pinfo[partition].start * ipod->sector_size) < 0) {
|
if (ipod_seek(ipod, ipod->pinfo[partition].start * ipod->sector_size) < 0) {
|
||||||
fprintf(stderr,"[ERR] Seek failed\n");
|
fprintf(stderr,"[ERR] Seek failed\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if (ipod_write(ipod,sectorbuf,512 * 2) < 0) {
|
if (ipod_write(ipod,ipod_sectorbuf,512 * 2) < 0) {
|
||||||
perror("[ERR] Write failed (first copy of bootsect/fsinfo)\n");
|
perror("[ERR] Write failed (first copy of bootsect/fsinfo)\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
@ -496,13 +496,13 @@ int format_partition(struct ipod_t* ipod, int partition)
|
||||||
fprintf(stderr,"[ERR] Seek failed\n");
|
fprintf(stderr,"[ERR] Seek failed\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if (ipod_write(ipod,sectorbuf,512 * 2) < 0) {
|
if (ipod_write(ipod,ipod_sectorbuf,512 * 2) < 0) {
|
||||||
perror("[ERR] Write failed (first copy of bootsect/fsinfo)\n");
|
perror("[ERR] Write failed (first copy of bootsect/fsinfo)\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Create the first FAT sector */
|
/* Create the first FAT sector */
|
||||||
create_firstfatsector(sectorbuf);
|
create_firstfatsector(ipod_sectorbuf);
|
||||||
|
|
||||||
/* Write the first fat sector in the right places */
|
/* Write the first fat sector in the right places */
|
||||||
for ( i=0; i<NumFATs; i++ ) {
|
for ( i=0; i<NumFATs; i++ ) {
|
||||||
|
|
@ -513,7 +513,7 @@ int format_partition(struct ipod_t* ipod, int partition)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ipod_write(ipod,sectorbuf,512) < 0) {
|
if (ipod_write(ipod,ipod_sectorbuf,512) < 0) {
|
||||||
perror("[ERR] Write failed (first copy of bootsect/fsinfo)\n");
|
perror("[ERR] Write failed (first copy of bootsect/fsinfo)\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -46,9 +46,9 @@
|
||||||
#include "arc4.h"
|
#include "arc4.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
extern int verbose;
|
int ipod_verbose = 0;
|
||||||
|
|
||||||
unsigned char* sectorbuf;
|
unsigned char* ipod_sectorbuf;
|
||||||
|
|
||||||
/* The following string appears at the start of the firmware partition */
|
/* The following string appears at the start of the firmware partition */
|
||||||
static const char *apple_stop_sign = "{{~~ /-----\\ "\
|
static const char *apple_stop_sign = "{{~~ /-----\\ "\
|
||||||
|
|
@ -169,7 +169,7 @@ int read_partinfo(struct ipod_t* ipod, int silent)
|
||||||
int i;
|
int i;
|
||||||
unsigned long count;
|
unsigned long count;
|
||||||
|
|
||||||
count = ipod_read(ipod,sectorbuf, ipod->sector_size);
|
count = ipod_read(ipod,ipod_sectorbuf, ipod->sector_size);
|
||||||
|
|
||||||
if (count <= 0) {
|
if (count <= 0) {
|
||||||
print_error(" Error reading from disk: ");
|
print_error(" Error reading from disk: ");
|
||||||
|
|
@ -178,12 +178,12 @@ int read_partinfo(struct ipod_t* ipod, int silent)
|
||||||
|
|
||||||
memset(ipod->pinfo, 0, sizeof(ipod->pinfo));
|
memset(ipod->pinfo, 0, sizeof(ipod->pinfo));
|
||||||
|
|
||||||
if ((sectorbuf[510] == 0x55) && (sectorbuf[511] == 0xaa)) {
|
if ((ipod_sectorbuf[510] == 0x55) && (ipod_sectorbuf[511] == 0xaa)) {
|
||||||
/* DOS partition table */
|
/* DOS partition table */
|
||||||
ipod->macpod = 0;
|
ipod->macpod = 0;
|
||||||
/* parse partitions */
|
/* parse partitions */
|
||||||
for ( i = 0; i < 4; i++ ) {
|
for ( i = 0; i < 4; i++ ) {
|
||||||
unsigned char* ptr = sectorbuf + 0x1be + 16*i;
|
unsigned char* ptr = ipod_sectorbuf + 0x1be + 16*i;
|
||||||
ipod->pinfo[i].type = ptr[4];
|
ipod->pinfo[i].type = ptr[4];
|
||||||
ipod->pinfo[i].start = BYTES2INT32(ptr, 8);
|
ipod->pinfo[i].start = BYTES2INT32(ptr, 8);
|
||||||
ipod->pinfo[i].size = BYTES2INT32(ptr, 12);
|
ipod->pinfo[i].size = BYTES2INT32(ptr, 12);
|
||||||
|
|
@ -193,7 +193,7 @@ int read_partinfo(struct ipod_t* ipod, int silent)
|
||||||
/* not handled yet */
|
/* not handled yet */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if ((sectorbuf[0] == 'E') && (sectorbuf[1] == 'R')) {
|
} else if ((ipod_sectorbuf[0] == 'E') && (ipod_sectorbuf[1] == 'R')) {
|
||||||
/* Apple Partition Map */
|
/* Apple Partition Map */
|
||||||
|
|
||||||
/* APM parsing code based on the check_mac_partitions() function in
|
/* APM parsing code based on the check_mac_partitions() function in
|
||||||
|
|
@ -202,7 +202,7 @@ int read_partinfo(struct ipod_t* ipod, int silent)
|
||||||
|
|
||||||
int blkNo = 1;
|
int blkNo = 1;
|
||||||
int partBlkCount = 1;
|
int partBlkCount = 1;
|
||||||
int partBlkSizMul = sectorbuf[2] / 2;
|
int partBlkSizMul = ipod_sectorbuf[2] / 2;
|
||||||
|
|
||||||
int pmMapBlkCnt; /* # of blks in partition map */
|
int pmMapBlkCnt; /* # of blks in partition map */
|
||||||
int pmPyPartStart; /* physical start blk of partition */
|
int pmPyPartStart; /* physical start blk of partition */
|
||||||
|
|
@ -219,7 +219,7 @@ int read_partinfo(struct ipod_t* ipod, int silent)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
count = ipod_read(ipod, sectorbuf, ipod->sector_size);
|
count = ipod_read(ipod, ipod_sectorbuf, ipod->sector_size);
|
||||||
|
|
||||||
if (count <= 0) {
|
if (count <= 0) {
|
||||||
print_error(" Error reading from disk: ");
|
print_error(" Error reading from disk: ");
|
||||||
|
|
@ -227,26 +227,26 @@ int read_partinfo(struct ipod_t* ipod, int silent)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* see if it's a partition entry */
|
/* see if it's a partition entry */
|
||||||
if ((sectorbuf[0] != 'P') || (sectorbuf[1] != 'M')) {
|
if ((ipod_sectorbuf[0] != 'P') || (ipod_sectorbuf[1] != 'M')) {
|
||||||
/* end of partition table -> leave the loop */
|
/* end of partition table -> leave the loop */
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Extract the interesting entries */
|
/* Extract the interesting entries */
|
||||||
pmMapBlkCnt = be2int(sectorbuf + 4);
|
pmMapBlkCnt = be2int(ipod_sectorbuf + 4);
|
||||||
pmPyPartStart = be2int(sectorbuf + 8);
|
pmPyPartStart = be2int(ipod_sectorbuf + 8);
|
||||||
pmPartBlkCnt = be2int(sectorbuf + 12);
|
pmPartBlkCnt = be2int(ipod_sectorbuf + 12);
|
||||||
|
|
||||||
/* update the number of part map blocks */
|
/* update the number of part map blocks */
|
||||||
partBlkCount = pmMapBlkCnt;
|
partBlkCount = pmMapBlkCnt;
|
||||||
|
|
||||||
if (strncmp((char*)(sectorbuf + 48), "Apple_MDFW", 32)==0) {
|
if (strncmp((char*)(ipod_sectorbuf + 48), "Apple_MDFW", 32)==0) {
|
||||||
/* A Firmware partition */
|
/* A Firmware partition */
|
||||||
ipod->pinfo[i].start = pmPyPartStart;
|
ipod->pinfo[i].start = pmPyPartStart;
|
||||||
ipod->pinfo[i].size = pmPartBlkCnt;
|
ipod->pinfo[i].size = pmPartBlkCnt;
|
||||||
ipod->pinfo[i].type = 0;
|
ipod->pinfo[i].type = 0;
|
||||||
i++;
|
i++;
|
||||||
} else if (strncmp((char*)(sectorbuf + 48), "Apple_HFS", 32)==0) {
|
} else if (strncmp((char*)(ipod_sectorbuf + 48), "Apple_HFS", 32)==0) {
|
||||||
/* A HFS partition */
|
/* A HFS partition */
|
||||||
ipod->pinfo[i].start = pmPyPartStart;
|
ipod->pinfo[i].start = pmPyPartStart;
|
||||||
ipod->pinfo[i].size = pmPartBlkCnt;
|
ipod->pinfo[i].size = pmPartBlkCnt;
|
||||||
|
|
@ -298,7 +298,7 @@ int read_partition(struct ipod_t* ipod, int outfile)
|
||||||
chunksize = bytesleft;
|
chunksize = bytesleft;
|
||||||
}
|
}
|
||||||
|
|
||||||
n = ipod_read(ipod, sectorbuf, chunksize);
|
n = ipod_read(ipod, ipod_sectorbuf, chunksize);
|
||||||
|
|
||||||
if (n < 0) {
|
if (n < 0) {
|
||||||
return -1;
|
return -1;
|
||||||
|
|
@ -313,7 +313,7 @@ int read_partition(struct ipod_t* ipod, int outfile)
|
||||||
|
|
||||||
bytesleft -= n;
|
bytesleft -= n;
|
||||||
|
|
||||||
res = write(outfile,sectorbuf,n);
|
res = write(outfile,ipod_sectorbuf,n);
|
||||||
|
|
||||||
if (res < 0) {
|
if (res < 0) {
|
||||||
perror("[ERR] write in disk_read");
|
perror("[ERR] write in disk_read");
|
||||||
|
|
@ -348,7 +348,7 @@ int write_partition(struct ipod_t* ipod, int infile)
|
||||||
bytesread = 0;
|
bytesread = 0;
|
||||||
eof = 0;
|
eof = 0;
|
||||||
while (!eof) {
|
while (!eof) {
|
||||||
n = read(infile,sectorbuf,BUFFER_SIZE);
|
n = read(infile,ipod_sectorbuf,BUFFER_SIZE);
|
||||||
|
|
||||||
if (n < 0) {
|
if (n < 0) {
|
||||||
perror("[ERR] read in disk_write");
|
perror("[ERR] read in disk_write");
|
||||||
|
|
@ -366,7 +366,7 @@ int write_partition(struct ipod_t* ipod, int infile)
|
||||||
|
|
||||||
bytesread += n;
|
bytesread += n;
|
||||||
|
|
||||||
res = ipod_write(ipod, sectorbuf, n);
|
res = ipod_write(ipod, ipod_sectorbuf, n);
|
||||||
|
|
||||||
if (res < 0) {
|
if (res < 0) {
|
||||||
print_error(" Error writing to disk: ");
|
print_error(" Error writing to disk: ");
|
||||||
|
|
@ -403,7 +403,7 @@ int diskmove(struct ipod_t* ipod, int delta)
|
||||||
(ipod->sector_size-1)) & ~(ipod->sector_size-1);
|
(ipod->sector_size-1)) & ~(ipod->sector_size-1);
|
||||||
bytesleft = src_end - src_start;
|
bytesleft = src_end - src_start;
|
||||||
|
|
||||||
if (verbose) {
|
if (ipod_verbose) {
|
||||||
fprintf(stderr,"[INFO] Need to move images 2-%d forward %08x bytes\n", ipod->nimages,delta);
|
fprintf(stderr,"[INFO] Need to move images 2-%d forward %08x bytes\n", ipod->nimages,delta);
|
||||||
fprintf(stderr,"[VERB] src_start = %08x\n",src_start);
|
fprintf(stderr,"[VERB] src_start = %08x\n",src_start);
|
||||||
fprintf(stderr,"[VERB] src_end = %08x\n",src_end);
|
fprintf(stderr,"[VERB] src_end = %08x\n",src_end);
|
||||||
|
|
@ -419,7 +419,7 @@ int diskmove(struct ipod_t* ipod, int delta)
|
||||||
chunksize = BUFFER_SIZE;
|
chunksize = BUFFER_SIZE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (verbose) {
|
if (ipod_verbose) {
|
||||||
fprintf(stderr,"[VERB] Copying %08x bytes from %08x to %08x (absolute %08x to %08x)\n",
|
fprintf(stderr,"[VERB] Copying %08x bytes from %08x to %08x (absolute %08x to %08x)\n",
|
||||||
chunksize,
|
chunksize,
|
||||||
src_end-chunksize,
|
src_end-chunksize,
|
||||||
|
|
@ -434,7 +434,7 @@ int diskmove(struct ipod_t* ipod, int delta)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((n = ipod_read(ipod,sectorbuf,chunksize)) < 0) {
|
if ((n = ipod_read(ipod,ipod_sectorbuf,chunksize)) < 0) {
|
||||||
perror("[ERR] Write failed\n");
|
perror("[ERR] Write failed\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
@ -450,7 +450,7 @@ int diskmove(struct ipod_t* ipod, int delta)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((n = ipod_write(ipod,sectorbuf,chunksize)) < 0) {
|
if ((n = ipod_write(ipod,ipod_sectorbuf,chunksize)) < 0) {
|
||||||
perror("[ERR] Write failed\n");
|
perror("[ERR] Write failed\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
@ -494,7 +494,7 @@ int add_bootloader(struct ipod_t* ipod, char* filename, int type)
|
||||||
#ifdef WITH_BOOTOBJS
|
#ifdef WITH_BOOTOBJS
|
||||||
if (type == FILETYPE_INTERNAL) {
|
if (type == FILETYPE_INTERNAL) {
|
||||||
fprintf(stderr,"[INFO] Using internal bootloader - %d bytes\n",ipod->bootloader_len);
|
fprintf(stderr,"[INFO] Using internal bootloader - %d bytes\n",ipod->bootloader_len);
|
||||||
memcpy(sectorbuf+entryOffset,ipod->bootloader,ipod->bootloader_len);
|
memcpy(ipod_sectorbuf+entryOffset,ipod->bootloader,ipod->bootloader_len);
|
||||||
length = ipod->bootloader_len;
|
length = ipod->bootloader_len;
|
||||||
paddedlength=(ipod->bootloader_len+ipod->sector_size-1)&~(ipod->sector_size-1);
|
paddedlength=(ipod->bootloader_len+ipod->sector_size-1)&~(ipod->sector_size-1);
|
||||||
}
|
}
|
||||||
|
|
@ -567,7 +567,7 @@ int add_bootloader(struct ipod_t* ipod, char* filename, int type)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (verbose) {
|
if (ipod_verbose) {
|
||||||
fprintf(stderr,"[VERB] Original firmware begins at 0x%08x\n", ipod->ipod_directory[0].devOffset + ipod->sector_size);
|
fprintf(stderr,"[VERB] Original firmware begins at 0x%08x\n", ipod->ipod_directory[0].devOffset + ipod->sector_size);
|
||||||
fprintf(stderr,"[VERB] New entryOffset will be 0x%08x\n",entryOffset);
|
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);
|
fprintf(stderr,"[VERB] End of bootloader will be at 0x%08x\n",entryOffset+paddedlength);
|
||||||
|
|
@ -592,14 +592,14 @@ int add_bootloader(struct ipod_t* ipod, char* filename, int type)
|
||||||
|
|
||||||
/* We have moved the partitions, now we can write our bootloader */
|
/* We have moved the partitions, now we can write our bootloader */
|
||||||
|
|
||||||
/* Firstly read the original firmware into sectorbuf */
|
/* Firstly read the original firmware into ipod_sectorbuf */
|
||||||
fprintf(stderr,"[INFO] Reading original firmware...\n");
|
fprintf(stderr,"[INFO] Reading original firmware...\n");
|
||||||
if (ipod_seek(ipod, ipod->fwoffset+ipod->ipod_directory[0].devOffset) < 0) {
|
if (ipod_seek(ipod, ipod->fwoffset+ipod->ipod_directory[0].devOffset) < 0) {
|
||||||
fprintf(stderr,"[ERR] Seek failed\n");
|
fprintf(stderr,"[ERR] Seek failed\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((n = ipod_read(ipod,sectorbuf,entryOffset)) < 0) {
|
if ((n = ipod_read(ipod,ipod_sectorbuf,entryOffset)) < 0) {
|
||||||
perror("[ERR] Read failed\n");
|
perror("[ERR] Read failed\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
@ -612,19 +612,19 @@ int add_bootloader(struct ipod_t* ipod, char* filename, int type)
|
||||||
|
|
||||||
#ifdef WITH_BOOTOBJS
|
#ifdef WITH_BOOTOBJS
|
||||||
if (type == FILETYPE_INTERNAL) {
|
if (type == FILETYPE_INTERNAL) {
|
||||||
memcpy(sectorbuf+entryOffset,ipod->bootloader,ipod->bootloader_len);
|
memcpy(ipod_sectorbuf+entryOffset,ipod->bootloader,ipod->bootloader_len);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
memcpy(sectorbuf+entryOffset,bootloader_buf,length);
|
memcpy(ipod_sectorbuf+entryOffset,bootloader_buf,length);
|
||||||
free(bootloader_buf);
|
free(bootloader_buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Calculate new checksum for combined image */
|
/* Calculate new checksum for combined image */
|
||||||
chksum = 0;
|
chksum = 0;
|
||||||
for (i=0;i<entryOffset + length; i++) {
|
for (i=0;i<entryOffset + length; i++) {
|
||||||
chksum += sectorbuf[i];
|
chksum += ipod_sectorbuf[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Now write the combined firmware image to the disk */
|
/* Now write the combined firmware image to the disk */
|
||||||
|
|
@ -634,7 +634,7 @@ int add_bootloader(struct ipod_t* ipod, char* filename, int type)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((n = ipod_write(ipod,sectorbuf,entryOffset+paddedlength)) < 0) {
|
if ((n = ipod_write(ipod,ipod_sectorbuf,entryOffset+paddedlength)) < 0) {
|
||||||
perror("[ERR] Write failed\n");
|
perror("[ERR] Write failed\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
@ -655,22 +655,22 @@ int add_bootloader(struct ipod_t* ipod, char* filename, int type)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
n=ipod_read(ipod, sectorbuf, ipod->sector_size);
|
n=ipod_read(ipod, ipod_sectorbuf, ipod->sector_size);
|
||||||
if (n < 0) {
|
if (n < 0) {
|
||||||
fprintf(stderr,"[ERR] Directory read failed\n");
|
fprintf(stderr,"[ERR] Directory read failed\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Update entries for image 0 */
|
/* Update entries for image 0 */
|
||||||
int2le(entryOffset+length,sectorbuf+x+16);
|
int2le(entryOffset+length,ipod_sectorbuf+x+16);
|
||||||
int2le(entryOffset,sectorbuf+x+24);
|
int2le(entryOffset,ipod_sectorbuf+x+24);
|
||||||
int2le(chksum,sectorbuf+x+28);
|
int2le(chksum,ipod_sectorbuf+x+28);
|
||||||
int2le(0xffffffff,sectorbuf+x+36); /* loadAddr */
|
int2le(0xffffffff,ipod_sectorbuf+x+36); /* loadAddr */
|
||||||
|
|
||||||
/* Update devOffset entries for other images, if we have moved them */
|
/* Update devOffset entries for other images, if we have moved them */
|
||||||
if (delta > 0) {
|
if (delta > 0) {
|
||||||
for (i=1;i<ipod->nimages;i++) {
|
for (i=1;i<ipod->nimages;i++) {
|
||||||
int2le(le2int(sectorbuf+x+i*40+12)+delta,sectorbuf+x+i*40+12);
|
int2le(le2int(ipod_sectorbuf+x+i*40+12)+delta,ipod_sectorbuf+x+i*40+12);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -679,7 +679,7 @@ int add_bootloader(struct ipod_t* ipod, char* filename, int type)
|
||||||
fprintf(stderr,"[ERR] Seek to %d failed\n", (int)(ipod->start+ipod->diroffset-x));
|
fprintf(stderr,"[ERR] Seek to %d failed\n", (int)(ipod->start+ipod->diroffset-x));
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
n=ipod_write(ipod, sectorbuf, ipod->sector_size);
|
n=ipod_write(ipod, ipod_sectorbuf, ipod->sector_size);
|
||||||
if (n < 0) {
|
if (n < 0) {
|
||||||
fprintf(stderr,"[ERR] Directory write failed\n");
|
fprintf(stderr,"[ERR] Directory write failed\n");
|
||||||
return -1;
|
return -1;
|
||||||
|
|
@ -720,7 +720,7 @@ int delete_bootloader(struct ipod_t* ipod)
|
||||||
fprintf(stderr,"[INFO] Padding read from 0x%08x to 0x%08x bytes\n",
|
fprintf(stderr,"[INFO] Padding read from 0x%08x to 0x%08x bytes\n",
|
||||||
length,i);
|
length,i);
|
||||||
|
|
||||||
if ((n = ipod_read(ipod,sectorbuf,i)) < 0) {
|
if ((n = ipod_read(ipod,ipod_sectorbuf,i)) < 0) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -733,7 +733,7 @@ int delete_bootloader(struct ipod_t* ipod)
|
||||||
chksum = 0;
|
chksum = 0;
|
||||||
for (i = 0; i < length; i++) {
|
for (i = 0; i < length; i++) {
|
||||||
/* add 8 unsigned bits but keep a 32 bit sum */
|
/* add 8 unsigned bits but keep a 32 bit sum */
|
||||||
chksum += sectorbuf[i];
|
chksum += ipod_sectorbuf[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Now write back the updated directory entry */
|
/* Now write back the updated directory entry */
|
||||||
|
|
@ -745,17 +745,17 @@ int delete_bootloader(struct ipod_t* ipod)
|
||||||
/* Read directory */
|
/* Read directory */
|
||||||
if (ipod_seek(ipod, ipod->start + ipod->diroffset - x) < 0) { return -1; }
|
if (ipod_seek(ipod, ipod->start + ipod->diroffset - x) < 0) { return -1; }
|
||||||
|
|
||||||
n=ipod_read(ipod, sectorbuf, ipod->sector_size);
|
n=ipod_read(ipod, ipod_sectorbuf, ipod->sector_size);
|
||||||
if (n < 0) { return -1; }
|
if (n < 0) { return -1; }
|
||||||
|
|
||||||
/* Update entries for image 0 */
|
/* Update entries for image 0 */
|
||||||
int2le(length,sectorbuf+x+16);
|
int2le(length,ipod_sectorbuf+x+16);
|
||||||
int2le(0,sectorbuf+x+24);
|
int2le(0,ipod_sectorbuf+x+24);
|
||||||
int2le(chksum,sectorbuf+x+28);
|
int2le(chksum,ipod_sectorbuf+x+28);
|
||||||
|
|
||||||
/* Write directory */
|
/* Write directory */
|
||||||
if (ipod_seek(ipod, ipod->start + ipod->diroffset - x) < 0) { return -1; }
|
if (ipod_seek(ipod, ipod->start + ipod->diroffset - x) < 0) { return -1; }
|
||||||
n=ipod_write(ipod, sectorbuf, ipod->sector_size);
|
n=ipod_write(ipod, ipod_sectorbuf, ipod->sector_size);
|
||||||
if (n < 0) { return -1; }
|
if (n < 0) { return -1; }
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
@ -840,14 +840,14 @@ int write_firmware(struct ipod_t* ipod, char* filename, int type)
|
||||||
|
|
||||||
#ifdef WITH_BOOTOBJS
|
#ifdef WITH_BOOTOBJS
|
||||||
if (type == FILETYPE_INTERNAL) {
|
if (type == FILETYPE_INTERNAL) {
|
||||||
memcpy(sectorbuf,ipod->bootloader,ipod->bootloader_len);
|
memcpy(ipod_sectorbuf,ipod->bootloader,ipod->bootloader_len);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
fprintf(stderr,"[INFO] Reading input file...\n");
|
fprintf(stderr,"[INFO] Reading input file...\n");
|
||||||
/* We now know we have enough space, so write it. */
|
/* We now know we have enough space, so write it. */
|
||||||
n = read(infile,sectorbuf,length);
|
n = read(infile,ipod_sectorbuf,length);
|
||||||
if (n < 0) {
|
if (n < 0) {
|
||||||
fprintf(stderr,"[ERR] Couldn't read input file\n");
|
fprintf(stderr,"[ERR] Couldn't read input file\n");
|
||||||
close(infile);
|
close(infile);
|
||||||
|
|
@ -857,13 +857,13 @@ int write_firmware(struct ipod_t* ipod, char* filename, int type)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Pad the data with zeros */
|
/* Pad the data with zeros */
|
||||||
memset(sectorbuf+length,0,newsize-length);
|
memset(ipod_sectorbuf+length,0,newsize-length);
|
||||||
|
|
||||||
if (type==FILETYPE_DOT_IPOD) {
|
if (type==FILETYPE_DOT_IPOD) {
|
||||||
chksum = ipod->modelnum;
|
chksum = ipod->modelnum;
|
||||||
for (i = 0; i < length; i++) {
|
for (i = 0; i < length; i++) {
|
||||||
/* add 8 unsigned bits but keep a 32 bit sum */
|
/* add 8 unsigned bits but keep a 32 bit sum */
|
||||||
chksum += sectorbuf[i];
|
chksum += ipod_sectorbuf[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (chksum == filechksum) {
|
if (chksum == filechksum) {
|
||||||
|
|
@ -879,7 +879,7 @@ int write_firmware(struct ipod_t* ipod, char* filename, int type)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((n = ipod_write(ipod,sectorbuf,newsize)) < 0) {
|
if ((n = ipod_write(ipod,ipod_sectorbuf,newsize)) < 0) {
|
||||||
perror("[ERR] Write failed\n");
|
perror("[ERR] Write failed\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
@ -895,7 +895,7 @@ int write_firmware(struct ipod_t* ipod, char* filename, int type)
|
||||||
chksum = 0;
|
chksum = 0;
|
||||||
for (i = 0; i < length; i++) {
|
for (i = 0; i < length; i++) {
|
||||||
/* add 8 unsigned bits but keep a 32 bit sum */
|
/* add 8 unsigned bits but keep a 32 bit sum */
|
||||||
chksum += sectorbuf[i];
|
chksum += ipod_sectorbuf[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
x = ipod->diroffset % ipod->sector_size;
|
x = ipod->diroffset % ipod->sector_size;
|
||||||
|
|
@ -903,17 +903,17 @@ int write_firmware(struct ipod_t* ipod, char* filename, int type)
|
||||||
/* Read directory */
|
/* Read directory */
|
||||||
if (ipod_seek(ipod, ipod->start + ipod->diroffset - x) < 0) { return -1; }
|
if (ipod_seek(ipod, ipod->start + ipod->diroffset - x) < 0) { return -1; }
|
||||||
|
|
||||||
n=ipod_read(ipod, sectorbuf, ipod->sector_size);
|
n=ipod_read(ipod, ipod_sectorbuf, ipod->sector_size);
|
||||||
if (n < 0) { return -1; }
|
if (n < 0) { return -1; }
|
||||||
|
|
||||||
/* Update entries for image 0 */
|
/* Update entries for image 0 */
|
||||||
int2le(length,sectorbuf+x+16);
|
int2le(length,ipod_sectorbuf+x+16);
|
||||||
int2le(0,sectorbuf+x+24);
|
int2le(0,ipod_sectorbuf+x+24);
|
||||||
int2le(chksum,sectorbuf+x+28);
|
int2le(chksum,ipod_sectorbuf+x+28);
|
||||||
|
|
||||||
/* Write directory */
|
/* Write directory */
|
||||||
if (ipod_seek(ipod, ipod->start + ipod->diroffset - x) < 0) { return -1; }
|
if (ipod_seek(ipod, ipod->start + ipod->diroffset - x) < 0) { return -1; }
|
||||||
n=ipod_write(ipod, sectorbuf, ipod->sector_size);
|
n=ipod_write(ipod, ipod_sectorbuf, ipod->sector_size);
|
||||||
if (n < 0) { return -1; }
|
if (n < 0) { return -1; }
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
@ -945,7 +945,7 @@ int read_firmware(struct ipod_t* ipod, char* filename, int type)
|
||||||
fprintf(stderr,"[INFO] Padding read from 0x%08x to 0x%08x bytes\n",
|
fprintf(stderr,"[INFO] Padding read from 0x%08x to 0x%08x bytes\n",
|
||||||
length,i);
|
length,i);
|
||||||
|
|
||||||
if ((n = ipod_read(ipod,sectorbuf,i)) < 0) {
|
if ((n = ipod_read(ipod,ipod_sectorbuf,i)) < 0) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -965,7 +965,7 @@ int read_firmware(struct ipod_t* ipod, char* filename, int type)
|
||||||
chksum = ipod->modelnum;
|
chksum = ipod->modelnum;
|
||||||
for (i = 0; i < length; i++) {
|
for (i = 0; i < length; i++) {
|
||||||
/* add 8 unsigned bits but keep a 32 bit sum */
|
/* add 8 unsigned bits but keep a 32 bit sum */
|
||||||
chksum += sectorbuf[i];
|
chksum += ipod_sectorbuf[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
int2be(chksum,header);
|
int2be(chksum,header);
|
||||||
|
|
@ -977,7 +977,7 @@ int read_firmware(struct ipod_t* ipod, char* filename, int type)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
n = write(outfile,sectorbuf,length);
|
n = write(outfile,ipod_sectorbuf,length);
|
||||||
if (n != length) {
|
if (n != length) {
|
||||||
fprintf(stderr,"[ERR] Write error - %d\n",n);
|
fprintf(stderr,"[ERR] Write error - %d\n",n);
|
||||||
}
|
}
|
||||||
|
|
@ -1004,28 +1004,28 @@ int read_directory(struct ipod_t* ipod)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
n=ipod_read(ipod, sectorbuf, ipod->sector_size);
|
n=ipod_read(ipod, ipod_sectorbuf, ipod->sector_size);
|
||||||
if (n < 0) {
|
if (n < 0) {
|
||||||
fprintf(stderr,"[ERR] ipod_read(ipod,buf,0x%08x) failed in read_directory()\n", ipod->sector_size);
|
fprintf(stderr,"[ERR] ipod_read(ipod,buf,0x%08x) failed in read_directory()\n", ipod->sector_size);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (memcmp(sectorbuf,apple_stop_sign,sizeof(apple_stop_sign))!=0) {
|
if (memcmp(ipod_sectorbuf,apple_stop_sign,sizeof(apple_stop_sign))!=0) {
|
||||||
fprintf(stderr,"[ERR] Firmware partition doesn't contain Apple copyright, aborting.\n");
|
fprintf(stderr,"[ERR] Firmware partition doesn't contain Apple copyright, aborting.\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (memcmp(sectorbuf+0x100,"]ih[",4)!=0) {
|
if (memcmp(ipod_sectorbuf+0x100,"]ih[",4)!=0) {
|
||||||
fprintf(stderr,"[ERR] Bad firmware directory\n");
|
fprintf(stderr,"[ERR] Bad firmware directory\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
version = le2ushort(sectorbuf+0x10a);
|
version = le2ushort(ipod_sectorbuf+0x10a);
|
||||||
if ((version != 2) && (version != 3)) {
|
if ((version != 2) && (version != 3)) {
|
||||||
fprintf(stderr,"[ERR] Unknown firmware format version %04x\n",
|
fprintf(stderr,"[ERR] Unknown firmware format version %04x\n",
|
||||||
version);
|
version);
|
||||||
}
|
}
|
||||||
ipod->diroffset=le2int(sectorbuf+0x104) + 0x200;
|
ipod->diroffset=le2int(ipod_sectorbuf+0x104) + 0x200;
|
||||||
|
|
||||||
/* diroffset may not be sector-aligned */
|
/* diroffset may not be sector-aligned */
|
||||||
x = ipod->diroffset % ipod->sector_size;
|
x = ipod->diroffset % ipod->sector_size;
|
||||||
|
|
@ -1036,26 +1036,26 @@ int read_directory(struct ipod_t* ipod)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
n=ipod_read(ipod, sectorbuf, ipod->sector_size);
|
n=ipod_read(ipod, ipod_sectorbuf, ipod->sector_size);
|
||||||
if (n < 0) {
|
if (n < 0) {
|
||||||
fprintf(stderr,"[ERR] Read of directory failed.\n");
|
fprintf(stderr,"[ERR] Read of directory failed.\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
p = sectorbuf + x;
|
p = ipod_sectorbuf + x;
|
||||||
|
|
||||||
/* A hack to detect 2nd gen Nanos - maybe there is a better way? */
|
/* A hack to detect 2nd gen Nanos - maybe there is a better way? */
|
||||||
if (p[0] == 0)
|
if (p[0] == 0)
|
||||||
{
|
{
|
||||||
n=ipod_read(ipod, sectorbuf, ipod->sector_size);
|
n=ipod_read(ipod, ipod_sectorbuf, ipod->sector_size);
|
||||||
if (n < 0) {
|
if (n < 0) {
|
||||||
fprintf(stderr,"[ERR] Read of directory failed.\n");
|
fprintf(stderr,"[ERR] Read of directory failed.\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
p = sectorbuf;
|
p = ipod_sectorbuf;
|
||||||
}
|
}
|
||||||
|
|
||||||
while ((ipod->nimages < MAX_IMAGES) && (p < (sectorbuf + x + 400)) &&
|
while ((ipod->nimages < MAX_IMAGES) && (p < (ipod_sectorbuf + x + 400)) &&
|
||||||
((memcmp(p,"!ATA",4)==0) || (memcmp(p,"DNAN",4)==0))) {
|
((memcmp(p,"!ATA",4)==0) || (memcmp(p,"DNAN",4)==0))) {
|
||||||
p+=4;
|
p+=4;
|
||||||
if (memcmp(p,"soso",4)==0) {
|
if (memcmp(p,"soso",4)==0) {
|
||||||
|
|
@ -1109,7 +1109,7 @@ int list_images(struct ipod_t* ipod)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
if (verbose) {
|
if (ipod_verbose) {
|
||||||
printf(" Type id devOffset len addr entryOffset chksum vers loadAddr devOffset+len\n");
|
printf(" Type id devOffset len addr entryOffset chksum vers loadAddr devOffset+len\n");
|
||||||
for (i = 0 ; i < ipod->nimages; i++) {
|
for (i = 0 ; i < ipod->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,
|
printf("%d - %s 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x\n",i,
|
||||||
|
|
@ -1359,12 +1359,12 @@ int write_dos_partition_table(struct ipod_t* ipod)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Firstly zero the entire MBR */
|
/* Firstly zero the entire MBR */
|
||||||
memset(sectorbuf, 0, ipod->sector_size);
|
memset(ipod_sectorbuf, 0, ipod->sector_size);
|
||||||
|
|
||||||
/* Now add the partition info */
|
/* Now add the partition info */
|
||||||
for (i=0; i < 4 ; i++)
|
for (i=0; i < 4 ; i++)
|
||||||
{
|
{
|
||||||
p = sectorbuf + 0x1be + i*16;
|
p = ipod_sectorbuf + 0x1be + i*16;
|
||||||
|
|
||||||
/* Ensure first partition is type 0, and second is 0xb */
|
/* Ensure first partition is type 0, and second is 0xb */
|
||||||
if (i==0) { type = 0; }
|
if (i==0) { type = 0; }
|
||||||
|
|
@ -1377,8 +1377,8 @@ int write_dos_partition_table(struct ipod_t* ipod)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Finally add the magic */
|
/* Finally add the magic */
|
||||||
sectorbuf[0x1fe] = 0x55;
|
ipod_sectorbuf[0x1fe] = 0x55;
|
||||||
sectorbuf[0x1ff] = 0xaa;
|
ipod_sectorbuf[0x1ff] = 0xaa;
|
||||||
|
|
||||||
if (ipod_seek(ipod, 0) < 0) {
|
if (ipod_seek(ipod, 0) < 0) {
|
||||||
fprintf(stderr,"[ERR] Seek failed writing MBR\n");
|
fprintf(stderr,"[ERR] Seek failed writing MBR\n");
|
||||||
|
|
@ -1386,7 +1386,7 @@ int write_dos_partition_table(struct ipod_t* ipod)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Write MBR */
|
/* Write MBR */
|
||||||
if ((n = ipod_write(ipod, sectorbuf, ipod->sector_size)) < 0) {
|
if ((n = ipod_write(ipod, ipod_sectorbuf, ipod->sector_size)) < 0) {
|
||||||
perror("[ERR] Write failed\n");
|
perror("[ERR] Write failed\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
@ -1514,11 +1514,11 @@ static int find_key(struct ipod_t* ipod, int aupd, unsigned char* key)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((n = ipod_read(ipod, sectorbuf, 512)) < 0) {
|
if ((n = ipod_read(ipod, ipod_sectorbuf, 512)) < 0) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
n = GetSecurityBlockKey(sectorbuf, key);
|
n = GetSecurityBlockKey(ipod_sectorbuf, key);
|
||||||
|
|
||||||
if (n != 1)
|
if (n != 1)
|
||||||
{
|
{
|
||||||
|
|
@ -1569,7 +1569,7 @@ int read_aupd(struct ipod_t* ipod, char* filename)
|
||||||
|
|
||||||
i = (length+ipod->sector_size-1) & ~(ipod->sector_size-1);
|
i = (length+ipod->sector_size-1) & ~(ipod->sector_size-1);
|
||||||
|
|
||||||
if ((n = ipod_read(ipod,sectorbuf,i)) < 0) {
|
if ((n = ipod_read(ipod,ipod_sectorbuf,i)) < 0) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1581,12 +1581,12 @@ int read_aupd(struct ipod_t* ipod, char* filename)
|
||||||
|
|
||||||
/* Perform the decryption - this is standard (A)RC4 */
|
/* Perform the decryption - this is standard (A)RC4 */
|
||||||
matrixArc4Init(&rc4, key, 4);
|
matrixArc4Init(&rc4, key, 4);
|
||||||
matrixArc4(&rc4, sectorbuf, sectorbuf, length);
|
matrixArc4(&rc4, ipod_sectorbuf, ipod_sectorbuf, length);
|
||||||
|
|
||||||
chksum = 0;
|
chksum = 0;
|
||||||
for (i = 0; i < (int)length; i++) {
|
for (i = 0; i < (int)length; i++) {
|
||||||
/* add 8 unsigned bits but keep a 32 bit sum */
|
/* add 8 unsigned bits but keep a 32 bit sum */
|
||||||
chksum += sectorbuf[i];
|
chksum += ipod_sectorbuf[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (chksum != ipod->ipod_directory[aupd].chksum)
|
if (chksum != ipod->ipod_directory[aupd].chksum)
|
||||||
|
|
@ -1602,7 +1602,7 @@ int read_aupd(struct ipod_t* ipod, char* filename)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
n = write(outfile,sectorbuf,length);
|
n = write(outfile,ipod_sectorbuf,length);
|
||||||
if (n != length) {
|
if (n != length) {
|
||||||
fprintf(stderr,"[ERR] Write error - %d\n",n);
|
fprintf(stderr,"[ERR] Write error - %d\n",n);
|
||||||
}
|
}
|
||||||
|
|
@ -1673,7 +1673,7 @@ int write_aupd(struct ipod_t* ipod, char* filename)
|
||||||
/* We now know we have enough space, so write it. */
|
/* We now know we have enough space, so write it. */
|
||||||
|
|
||||||
fprintf(stderr,"[INFO] Reading input file...\n");
|
fprintf(stderr,"[INFO] Reading input file...\n");
|
||||||
n = read(infile,sectorbuf,length);
|
n = read(infile,ipod_sectorbuf,length);
|
||||||
if (n < 0) {
|
if (n < 0) {
|
||||||
fprintf(stderr,"[ERR] Couldn't read input file\n");
|
fprintf(stderr,"[ERR] Couldn't read input file\n");
|
||||||
close(infile);
|
close(infile);
|
||||||
|
|
@ -1682,25 +1682,25 @@ int write_aupd(struct ipod_t* ipod, char* filename)
|
||||||
close(infile);
|
close(infile);
|
||||||
|
|
||||||
/* Pad the data with zeros */
|
/* Pad the data with zeros */
|
||||||
memset(sectorbuf+length,0,newsize-length);
|
memset(ipod_sectorbuf+length,0,newsize-length);
|
||||||
|
|
||||||
/* Calculate the new checksum (before we encrypt) */
|
/* Calculate the new checksum (before we encrypt) */
|
||||||
chksum = 0;
|
chksum = 0;
|
||||||
for (i = 0; i < (int)length; i++) {
|
for (i = 0; i < (int)length; i++) {
|
||||||
/* add 8 unsigned bits but keep a 32 bit sum */
|
/* add 8 unsigned bits but keep a 32 bit sum */
|
||||||
chksum += sectorbuf[i];
|
chksum += ipod_sectorbuf[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Perform the encryption - this is standard (A)RC4 */
|
/* Perform the encryption - this is standard (A)RC4 */
|
||||||
matrixArc4Init(&rc4, key, 4);
|
matrixArc4Init(&rc4, key, 4);
|
||||||
matrixArc4(&rc4, sectorbuf, sectorbuf, length);
|
matrixArc4(&rc4, ipod_sectorbuf, ipod_sectorbuf, length);
|
||||||
|
|
||||||
if (ipod_seek(ipod, ipod->fwoffset+ipod->ipod_directory[aupd].devOffset) < 0) {
|
if (ipod_seek(ipod, ipod->fwoffset+ipod->ipod_directory[aupd].devOffset) < 0) {
|
||||||
fprintf(stderr,"[ERR] Seek failed\n");
|
fprintf(stderr,"[ERR] Seek failed\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((n = ipod_write(ipod,sectorbuf,newsize)) < 0) {
|
if ((n = ipod_write(ipod,ipod_sectorbuf,newsize)) < 0) {
|
||||||
perror("[ERR] Write failed\n");
|
perror("[ERR] Write failed\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
@ -1717,16 +1717,16 @@ int write_aupd(struct ipod_t* ipod, char* filename)
|
||||||
/* Read directory */
|
/* Read directory */
|
||||||
if (ipod_seek(ipod, ipod->start + ipod->diroffset - x) < 0) { return -1; }
|
if (ipod_seek(ipod, ipod->start + ipod->diroffset - x) < 0) { return -1; }
|
||||||
|
|
||||||
n=ipod_read(ipod, sectorbuf, ipod->sector_size);
|
n=ipod_read(ipod, ipod_sectorbuf, ipod->sector_size);
|
||||||
if (n < 0) { return -1; }
|
if (n < 0) { return -1; }
|
||||||
|
|
||||||
/* Update checksum */
|
/* Update checksum */
|
||||||
fprintf(stderr,"[INFO] Updating checksum to 0x%08x (was 0x%08x)\n",(unsigned int)chksum,le2int(sectorbuf + x + aupd*40 + 28));
|
fprintf(stderr,"[INFO] Updating checksum to 0x%08x (was 0x%08x)\n",(unsigned int)chksum,le2int(ipod_sectorbuf + x + aupd*40 + 28));
|
||||||
int2le(chksum,sectorbuf+x+aupd*40+28);
|
int2le(chksum,ipod_sectorbuf+x+aupd*40+28);
|
||||||
|
|
||||||
/* Write directory */
|
/* Write directory */
|
||||||
if (ipod_seek(ipod, ipod->start + ipod->diroffset - x) < 0) { return -1; }
|
if (ipod_seek(ipod, ipod->start + ipod->diroffset - x) < 0) { return -1; }
|
||||||
n=ipod_write(ipod, sectorbuf, ipod->sector_size);
|
n=ipod_write(ipod, ipod_sectorbuf, ipod->sector_size);
|
||||||
if (n < 0) { return -1; }
|
if (n < 0) { return -1; }
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
||||||
|
|
@ -29,7 +29,8 @@ extern "C" {
|
||||||
/* Size of buffer for disk I/O - 8MB is large enough for any version
|
/* Size of buffer for disk I/O - 8MB is large enough for any version
|
||||||
of the Apple firmware, but not the Nano's RSRC image. */
|
of the Apple firmware, but not the Nano's RSRC image. */
|
||||||
#define BUFFER_SIZE 8*1024*1024
|
#define BUFFER_SIZE 8*1024*1024
|
||||||
extern unsigned char* sectorbuf;
|
extern unsigned char* ipod_sectorbuf;
|
||||||
|
extern int ipod_verbose;
|
||||||
|
|
||||||
#define FILETYPE_DOT_IPOD 0
|
#define FILETYPE_DOT_IPOD 0
|
||||||
#define FILETYPE_DOT_BIN 1
|
#define FILETYPE_DOT_BIN 1
|
||||||
|
|
|
||||||
|
|
@ -31,8 +31,6 @@
|
||||||
|
|
||||||
#define VERSION "2.0 with v2.0 bootloaders"
|
#define VERSION "2.0 with v2.0 bootloaders"
|
||||||
|
|
||||||
int verbose = 0;
|
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
NONE,
|
NONE,
|
||||||
#ifdef WITH_BOOTOBJS
|
#ifdef WITH_BOOTOBJS
|
||||||
|
|
@ -155,7 +153,7 @@ int main(int argc, char* argv[])
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ipod_alloc_buffer(§orbuf,BUFFER_SIZE) < 0) {
|
if (ipod_alloc_buffer(&ipod_sectorbuf,BUFFER_SIZE) < 0) {
|
||||||
fprintf(stderr,"Failed to allocate memory buffer\n");
|
fprintf(stderr,"Failed to allocate memory buffer\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -297,7 +295,7 @@ int main(int argc, char* argv[])
|
||||||
i++;
|
i++;
|
||||||
} else if ((strcmp(argv[i],"-v")==0) ||
|
} else if ((strcmp(argv[i],"-v")==0) ||
|
||||||
(strcmp(argv[i],"--verbose")==0)) {
|
(strcmp(argv[i],"--verbose")==0)) {
|
||||||
verbose++;
|
ipod_verbose++;
|
||||||
i++;
|
i++;
|
||||||
} else if ((strcmp(argv[i],"-f")==0) ||
|
} else if ((strcmp(argv[i],"-f")==0) ||
|
||||||
(strcmp(argv[i],"--format")==0)) {
|
(strcmp(argv[i],"--format")==0)) {
|
||||||
|
|
|
||||||
|
|
@ -807,7 +807,7 @@ int verbose =0;
|
||||||
// reserves memory for ipodpatcher
|
// reserves memory for ipodpatcher
|
||||||
bool initIpodpatcher()
|
bool initIpodpatcher()
|
||||||
{
|
{
|
||||||
if (ipod_alloc_buffer(§orbuf,BUFFER_SIZE) < 0) return true;
|
if (ipod_alloc_buffer(&ipod_sectorbuf,BUFFER_SIZE) < 0) return true;
|
||||||
else return false;
|
else return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1050,7 +1050,7 @@ void BootloaderInstaller::ipodFinish()
|
||||||
// reserves memory for sansapatcher
|
// reserves memory for sansapatcher
|
||||||
bool initSansapatcher()
|
bool initSansapatcher()
|
||||||
{
|
{
|
||||||
if (sansa_alloc_buffer(§orbuf,BUFFER_SIZE) < 0) return true;
|
if (sansa_alloc_buffer(&sansa_sectorbuf,BUFFER_SIZE) < 0) return true;
|
||||||
else return false;
|
else return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -32,10 +32,6 @@
|
||||||
|
|
||||||
#define VERSION "0.6 with v4.0 bootloaders"
|
#define VERSION "0.6 with v4.0 bootloaders"
|
||||||
|
|
||||||
unsigned char* sectorbuf;
|
|
||||||
|
|
||||||
int verbose = 0;
|
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
NONE,
|
NONE,
|
||||||
INSTALL,
|
INSTALL,
|
||||||
|
|
@ -150,7 +146,7 @@ int main(int argc, char* argv[])
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sansa_alloc_buffer(§orbuf,BUFFER_SIZE) < 0) {
|
if (sansa_alloc_buffer(&sansa_sectorbuf,BUFFER_SIZE) < 0) {
|
||||||
fprintf(stderr,"Failed to allocate memory buffer\n");
|
fprintf(stderr,"Failed to allocate memory buffer\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -38,14 +38,14 @@
|
||||||
#define NVPARAMS_OFFSET 0x780000
|
#define NVPARAMS_OFFSET 0x780000
|
||||||
#define NVPARAMS_SIZE (0x80000-0x200)
|
#define NVPARAMS_SIZE (0x80000-0x200)
|
||||||
|
|
||||||
extern int verbose;
|
int sansa_verbose = 0;
|
||||||
|
|
||||||
/* Windows requires the buffer for disk I/O to be aligned in memory on a
|
/* Windows requires the buffer for disk I/O to be aligned in memory on a
|
||||||
multiple of the disk volume size - so we use a single global variable
|
multiple of the disk volume size - so we use a single global variable
|
||||||
and initialise it with sansa_alloc_buf() in main().
|
and initialise it with sansa_alloc_buf() in main().
|
||||||
*/
|
*/
|
||||||
|
|
||||||
extern unsigned char* sectorbuf;
|
unsigned char* sansa_sectorbuf;
|
||||||
|
|
||||||
static off_t filesize(int fd) {
|
static off_t filesize(int fd) {
|
||||||
struct stat buf;
|
struct stat buf;
|
||||||
|
|
@ -94,17 +94,17 @@ int sansa_read_partinfo(struct sansa_t* sansa, int silent)
|
||||||
int i;
|
int i;
|
||||||
unsigned long count;
|
unsigned long count;
|
||||||
|
|
||||||
count = sansa_read(sansa,sectorbuf, sansa->sector_size);
|
count = sansa_read(sansa,sansa_sectorbuf, sansa->sector_size);
|
||||||
|
|
||||||
if (count <= 0) {
|
if (count <= 0) {
|
||||||
print_error(" Error reading from disk: ");
|
print_error(" Error reading from disk: ");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((sectorbuf[510] == 0x55) && (sectorbuf[511] == 0xaa)) {
|
if ((sansa_sectorbuf[510] == 0x55) && (sansa_sectorbuf[511] == 0xaa)) {
|
||||||
/* parse partitions */
|
/* parse partitions */
|
||||||
for ( i = 0; i < 4; i++ ) {
|
for ( i = 0; i < 4; i++ ) {
|
||||||
unsigned char* ptr = sectorbuf + 0x1be + 16*i;
|
unsigned char* ptr = sansa_sectorbuf + 0x1be + 16*i;
|
||||||
sansa->pinfo[i].type = ptr[4];
|
sansa->pinfo[i].type = ptr[4];
|
||||||
sansa->pinfo[i].start = BYTES2INT32(ptr, 8);
|
sansa->pinfo[i].start = BYTES2INT32(ptr, 8);
|
||||||
sansa->pinfo[i].size = BYTES2INT32(ptr, 12);
|
sansa->pinfo[i].size = BYTES2INT32(ptr, 12);
|
||||||
|
|
@ -114,7 +114,7 @@ int sansa_read_partinfo(struct sansa_t* sansa, int silent)
|
||||||
/* not handled yet */
|
/* not handled yet */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if ((sectorbuf[0] == 'E') && (sectorbuf[1] == 'R')) {
|
} else if ((sansa_sectorbuf[0] == 'E') && (sansa_sectorbuf[1] == 'R')) {
|
||||||
if (!silent) fprintf(stderr,"[ERR] Bad boot sector signature\n");
|
if (!silent) fprintf(stderr,"[ERR] Bad boot sector signature\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
@ -405,14 +405,14 @@ int is_sansa(struct sansa_t* sansa)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check Bootloader header */
|
/* Check Bootloader header */
|
||||||
if (sansa_seek_and_read(sansa, sansa->start, sectorbuf, 0x200) < 0) {
|
if (sansa_seek_and_read(sansa, sansa->start, sansa_sectorbuf, 0x200) < 0) {
|
||||||
return -2;
|
return -2;
|
||||||
}
|
}
|
||||||
if (memcmp(sectorbuf,"PPBL",4)!=0) {
|
if (memcmp(sansa_sectorbuf,"PPBL",4)!=0) {
|
||||||
/* No bootloader header, abort */
|
/* No bootloader header, abort */
|
||||||
return -4;
|
return -4;
|
||||||
}
|
}
|
||||||
ppbl_length = (le2int(sectorbuf+4) + 0x1ff) & ~0x1ff;
|
ppbl_length = (le2int(sansa_sectorbuf+4) + 0x1ff) & ~0x1ff;
|
||||||
|
|
||||||
/* Sanity/safety check - the bootloader can't be larger than PPMI_OFFSET */
|
/* Sanity/safety check - the bootloader can't be larger than PPMI_OFFSET */
|
||||||
if (ppbl_length > PPMI_OFFSET)
|
if (ppbl_length > PPMI_OFFSET)
|
||||||
|
|
@ -421,12 +421,12 @@ int is_sansa(struct sansa_t* sansa)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Load Sansa bootloader and check for "Sansa C200" magic string */
|
/* Load Sansa bootloader and check for "Sansa C200" magic string */
|
||||||
if (sansa_seek_and_read(sansa, sansa->start + 0x200, sectorbuf, ppbl_length) < 0) {
|
if (sansa_seek_and_read(sansa, sansa->start + 0x200, sansa_sectorbuf, ppbl_length) < 0) {
|
||||||
fprintf(stderr,"[ERR] Seek and read to 0x%08llx in is_sansa failed.\n",
|
fprintf(stderr,"[ERR] Seek and read to 0x%08llx in is_sansa failed.\n",
|
||||||
sansa->start+0x200);
|
sansa->start+0x200);
|
||||||
return -6;
|
return -6;
|
||||||
}
|
}
|
||||||
if (sansa_memmem(sectorbuf, ppbl_length, "Sansa C200", 10) != NULL) {
|
if (sansa_memmem(sansa_sectorbuf, ppbl_length, "Sansa C200", 10) != NULL) {
|
||||||
/* C200 */
|
/* C200 */
|
||||||
sansa->targetname="c200";
|
sansa->targetname="c200";
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -435,25 +435,25 @@ int is_sansa(struct sansa_t* sansa)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check Main firmware header */
|
/* Check Main firmware header */
|
||||||
if (sansa_seek_and_read(sansa, sansa->start+PPMI_OFFSET, sectorbuf, 0x200) < 0) {
|
if (sansa_seek_and_read(sansa, sansa->start+PPMI_OFFSET, sansa_sectorbuf, 0x200) < 0) {
|
||||||
fprintf(stderr,"[ERR] Seek to 0x%08llx in is_sansa failed.\n",
|
fprintf(stderr,"[ERR] Seek to 0x%08llx in is_sansa failed.\n",
|
||||||
sansa->start+PPMI_OFFSET);
|
sansa->start+PPMI_OFFSET);
|
||||||
return -5;
|
return -5;
|
||||||
}
|
}
|
||||||
if (memcmp(sectorbuf,"PPMI",4)!=0) {
|
if (memcmp(sansa_sectorbuf,"PPMI",4)!=0) {
|
||||||
/* No bootloader header, abort */
|
/* No bootloader header, abort */
|
||||||
return -7;
|
return -7;
|
||||||
}
|
}
|
||||||
ppmi_length = le2int(sectorbuf+4);
|
ppmi_length = le2int(sansa_sectorbuf+4);
|
||||||
|
|
||||||
/* Check main mi4 file header */
|
/* Check main mi4 file header */
|
||||||
if (sansa_seek_and_read(sansa, sansa->start+PPMI_OFFSET+0x200, sectorbuf, 0x200) < 0) {
|
if (sansa_seek_and_read(sansa, sansa->start+PPMI_OFFSET+0x200, sansa_sectorbuf, 0x200) < 0) {
|
||||||
fprintf(stderr,"[ERR] Seek to 0x%08llx in is_sansa failed.\n",
|
fprintf(stderr,"[ERR] Seek to 0x%08llx in is_sansa failed.\n",
|
||||||
sansa->start+PPMI_OFFSET+0x200);
|
sansa->start+PPMI_OFFSET+0x200);
|
||||||
return -5;
|
return -5;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (get_mi4header(sectorbuf,&mi4header) < 0) {
|
if (get_mi4header(sansa_sectorbuf,&mi4header) < 0) {
|
||||||
fprintf(stderr,"[ERR] Invalid mi4header\n");
|
fprintf(stderr,"[ERR] Invalid mi4header\n");
|
||||||
return -6;
|
return -6;
|
||||||
}
|
}
|
||||||
|
|
@ -465,15 +465,15 @@ int is_sansa(struct sansa_t* sansa)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
sansa->hasoldbootloader = 0;
|
sansa->hasoldbootloader = 0;
|
||||||
if (memcmp(sectorbuf+0x1f8,"RBBL",4)==0) {
|
if (memcmp(sansa_sectorbuf+0x1f8,"RBBL",4)==0) {
|
||||||
/* Look for an original firmware after the first image */
|
/* Look for an original firmware after the first image */
|
||||||
if (sansa_seek_and_read(sansa,
|
if (sansa_seek_and_read(sansa,
|
||||||
sansa->start + PPMI_OFFSET + 0x200 + ppmi_length,
|
sansa->start + PPMI_OFFSET + 0x200 + ppmi_length,
|
||||||
sectorbuf, 512) < 0) {
|
sansa_sectorbuf, 512) < 0) {
|
||||||
return -7;
|
return -7;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (get_mi4header(sectorbuf,&mi4header)!=0) {
|
if (get_mi4header(sansa_sectorbuf,&mi4header)!=0) {
|
||||||
fprintf(stderr,"[ERR] No original firmware found\n");
|
fprintf(stderr,"[ERR] No original firmware found\n");
|
||||||
sansa->hasoldbootloader = 1;
|
sansa->hasoldbootloader = 1;
|
||||||
}
|
}
|
||||||
|
|
@ -654,7 +654,7 @@ int sansa_read_firmware(struct sansa_t* sansa, char* filename)
|
||||||
int outfile;
|
int outfile;
|
||||||
struct mi4header_t mi4header;
|
struct mi4header_t mi4header;
|
||||||
|
|
||||||
res = load_original_firmware(sansa,sectorbuf,&mi4header);
|
res = load_original_firmware(sansa,sansa_sectorbuf,&mi4header);
|
||||||
if (res < 0)
|
if (res < 0)
|
||||||
return res;
|
return res;
|
||||||
|
|
||||||
|
|
@ -664,7 +664,7 @@ int sansa_read_firmware(struct sansa_t* sansa, char* filename)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
res = write(outfile,sectorbuf,mi4header.mi4size);
|
res = write(outfile,sansa_sectorbuf,mi4header.mi4size);
|
||||||
if (res != (int)mi4header.mi4size) {
|
if (res != (int)mi4header.mi4size) {
|
||||||
fprintf(stderr,"[ERR] Write error - %d\n", res);
|
fprintf(stderr,"[ERR] Write error - %d\n", res);
|
||||||
return -1;
|
return -1;
|
||||||
|
|
@ -704,14 +704,14 @@ int sansa_add_bootloader(struct sansa_t* sansa, char* filename, int type)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Create PPMI header */
|
/* Create PPMI header */
|
||||||
memset(sectorbuf,0,0x200);
|
memset(sansa_sectorbuf,0,0x200);
|
||||||
memcpy(sectorbuf,"PPMI",4);
|
memcpy(sansa_sectorbuf,"PPMI",4);
|
||||||
int2le(bl_length, sectorbuf+4);
|
int2le(bl_length, sansa_sectorbuf+4);
|
||||||
int2le(0x00020000, sectorbuf+8);
|
int2le(0x00020000, sansa_sectorbuf+8);
|
||||||
|
|
||||||
if (type==FILETYPE_MI4) {
|
if (type==FILETYPE_MI4) {
|
||||||
/* Read bootloader into sectorbuf+0x200 */
|
/* Read bootloader into sansa_sectorbuf+0x200 */
|
||||||
n = read(infile,sectorbuf+0x200,bl_length);
|
n = read(infile,sansa_sectorbuf+0x200,bl_length);
|
||||||
close(infile);
|
close(infile);
|
||||||
if (n < bl_length) {
|
if (n < bl_length) {
|
||||||
fprintf(stderr,"[ERR] Short read - requested %d bytes, received %d\n"
|
fprintf(stderr,"[ERR] Short read - requested %d bytes, received %d\n"
|
||||||
|
|
@ -719,7 +719,7 @@ int sansa_add_bootloader(struct sansa_t* sansa, char* filename, int type)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (memcmp(sectorbuf+0x200+0x1f8,"RBBL",4)!=0) {
|
if (memcmp(sansa_sectorbuf+0x200+0x1f8,"RBBL",4)!=0) {
|
||||||
fprintf(stderr,"[ERR] %s is not a Rockbox bootloader, aborting.\n",
|
fprintf(stderr,"[ERR] %s is not a Rockbox bootloader, aborting.\n",
|
||||||
filename);
|
filename);
|
||||||
return -1;
|
return -1;
|
||||||
|
|
@ -727,15 +727,15 @@ int sansa_add_bootloader(struct sansa_t* sansa, char* filename, int type)
|
||||||
} else {
|
} else {
|
||||||
#ifndef RBUTIL
|
#ifndef RBUTIL
|
||||||
if (strcmp(sansa->targetname,"c200") == 0) {
|
if (strcmp(sansa->targetname,"c200") == 0) {
|
||||||
memcpy(sectorbuf+0x200,bootimg_c200,LEN_bootimg_c200);
|
memcpy(sansa_sectorbuf+0x200,bootimg_c200,LEN_bootimg_c200);
|
||||||
} else {
|
} else {
|
||||||
memcpy(sectorbuf+0x200,bootimg_e200,LEN_bootimg_e200);
|
memcpy(sansa_sectorbuf+0x200,bootimg_e200,LEN_bootimg_e200);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Load original firmware from Sansa to the space after the bootloader */
|
/* Load original firmware from Sansa to the space after the bootloader */
|
||||||
res = load_original_firmware(sansa,sectorbuf+0x200+bl_length,&mi4header);
|
res = load_original_firmware(sansa,sansa_sectorbuf+0x200+bl_length,&mi4header);
|
||||||
if (res < 0)
|
if (res < 0)
|
||||||
return res;
|
return res;
|
||||||
|
|
||||||
|
|
@ -749,7 +749,7 @@ int sansa_add_bootloader(struct sansa_t* sansa, char* filename, int type)
|
||||||
|
|
||||||
length = 0x200 + bl_length + mi4header.mi4size;
|
length = 0x200 + bl_length + mi4header.mi4size;
|
||||||
|
|
||||||
n=sansa_write(sansa, sectorbuf, length);
|
n=sansa_write(sansa, sansa_sectorbuf, length);
|
||||||
if (n < length) {
|
if (n < length) {
|
||||||
fprintf(stderr,"[ERR] Short write in add_bootloader\n");
|
fprintf(stderr,"[ERR] Short write in add_bootloader\n");
|
||||||
return -6;
|
return -6;
|
||||||
|
|
@ -765,16 +765,16 @@ int sansa_delete_bootloader(struct sansa_t* sansa)
|
||||||
int n;
|
int n;
|
||||||
int length;
|
int length;
|
||||||
|
|
||||||
/* Load original firmware from Sansa to sectorbuf+0x200 */
|
/* Load original firmware from Sansa to sansa_sectorbuf+0x200 */
|
||||||
res = load_original_firmware(sansa,sectorbuf+0x200,&mi4header);
|
res = load_original_firmware(sansa,sansa_sectorbuf+0x200,&mi4header);
|
||||||
if (res < 0)
|
if (res < 0)
|
||||||
return res;
|
return res;
|
||||||
|
|
||||||
/* Create PPMI header */
|
/* Create PPMI header */
|
||||||
memset(sectorbuf,0,0x200);
|
memset(sansa_sectorbuf,0,0x200);
|
||||||
memcpy(sectorbuf,"PPMI",4);
|
memcpy(sansa_sectorbuf,"PPMI",4);
|
||||||
int2le(mi4header.mi4size, sectorbuf+4);
|
int2le(mi4header.mi4size, sansa_sectorbuf+4);
|
||||||
int2le(0x00020000, sectorbuf+8);
|
int2le(0x00020000, sansa_sectorbuf+8);
|
||||||
|
|
||||||
/* Now write the whole thing back to the Sansa */
|
/* Now write the whole thing back to the Sansa */
|
||||||
|
|
||||||
|
|
@ -786,7 +786,7 @@ int sansa_delete_bootloader(struct sansa_t* sansa)
|
||||||
|
|
||||||
length = 0x200 + mi4header.mi4size;
|
length = 0x200 + mi4header.mi4size;
|
||||||
|
|
||||||
n=sansa_write(sansa, sectorbuf, length);
|
n=sansa_write(sansa, sansa_sectorbuf, length);
|
||||||
if (n < length) {
|
if (n < length) {
|
||||||
fprintf(stderr,"[ERR] Short write in delete_bootloader\n");
|
fprintf(stderr,"[ERR] Short write in delete_bootloader\n");
|
||||||
return -6;
|
return -6;
|
||||||
|
|
@ -801,20 +801,20 @@ void sansa_list_images(struct sansa_t* sansa)
|
||||||
loff_t ppmi_length;
|
loff_t ppmi_length;
|
||||||
|
|
||||||
/* Check Main firmware header */
|
/* Check Main firmware header */
|
||||||
if (sansa_seek_and_read(sansa, sansa->start+PPMI_OFFSET, sectorbuf, 0x200) < 0) {
|
if (sansa_seek_and_read(sansa, sansa->start+PPMI_OFFSET, sansa_sectorbuf, 0x200) < 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
ppmi_length = le2int(sectorbuf+4);
|
ppmi_length = le2int(sansa_sectorbuf+4);
|
||||||
|
|
||||||
printf("[INFO] Image 1 - %llu bytes\n",ppmi_length);
|
printf("[INFO] Image 1 - %llu bytes\n",ppmi_length);
|
||||||
|
|
||||||
/* Look for an original firmware after the first image */
|
/* Look for an original firmware after the first image */
|
||||||
if (sansa_seek_and_read(sansa, sansa->start + PPMI_OFFSET + 0x200 + ppmi_length, sectorbuf, 512) < 0) {
|
if (sansa_seek_and_read(sansa, sansa->start + PPMI_OFFSET + 0x200 + ppmi_length, sansa_sectorbuf, 512) < 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (get_mi4header(sectorbuf,&mi4header)==0) {
|
if (get_mi4header(sansa_sectorbuf,&mi4header)==0) {
|
||||||
printf("[INFO] Image 2 - %d bytes\n",mi4header.mi4size);
|
printf("[INFO] Image 2 - %d bytes\n",mi4header.mi4size);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -864,8 +864,8 @@ int sansa_update_of(struct sansa_t* sansa, char* filename)
|
||||||
of_length = filesize(infile);
|
of_length = filesize(infile);
|
||||||
|
|
||||||
/* Load original firmware from file */
|
/* Load original firmware from file */
|
||||||
memset(sectorbuf,0,0x200);
|
memset(sansa_sectorbuf,0,0x200);
|
||||||
n = read(infile,sectorbuf,of_length);
|
n = read(infile,sansa_sectorbuf,of_length);
|
||||||
close(infile);
|
close(infile);
|
||||||
if (n < of_length) {
|
if (n < of_length) {
|
||||||
fprintf(stderr,"[ERR] Short read - requested %d bytes, received %d\n"
|
fprintf(stderr,"[ERR] Short read - requested %d bytes, received %d\n"
|
||||||
|
|
@ -874,13 +874,13 @@ int sansa_update_of(struct sansa_t* sansa, char* filename)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check we have a valid MI4 file. */
|
/* Check we have a valid MI4 file. */
|
||||||
if (get_mi4header(sectorbuf,&mi4header)!=0) {
|
if (get_mi4header(sansa_sectorbuf,&mi4header)!=0) {
|
||||||
fprintf(stderr,"[ERR] %s is not a valid mi4 file\n",filename);
|
fprintf(stderr,"[ERR] %s is not a valid mi4 file\n",filename);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Decrypt and build the header */
|
/* Decrypt and build the header */
|
||||||
if(prepare_original_firmware(sectorbuf, &mi4header)!=0){
|
if(prepare_original_firmware(sansa_sectorbuf, &mi4header)!=0){
|
||||||
fprintf(stderr,"[ERR] Unable to build decrypted mi4 from %s\n"
|
fprintf(stderr,"[ERR] Unable to build decrypted mi4 from %s\n"
|
||||||
,filename);
|
,filename);
|
||||||
return -1;
|
return -1;
|
||||||
|
|
@ -893,7 +893,7 @@ int sansa_update_of(struct sansa_t* sansa, char* filename)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
n=sansa_write(sansa, sectorbuf, of_length);
|
n=sansa_write(sansa, sansa_sectorbuf, of_length);
|
||||||
if (n < of_length) {
|
if (n < of_length) {
|
||||||
fprintf(stderr,"[ERR] Short write in sansa_update_of\n");
|
fprintf(stderr,"[ERR] Short write in sansa_update_of\n");
|
||||||
return -1;
|
return -1;
|
||||||
|
|
@ -910,8 +910,8 @@ int sansa_update_of(struct sansa_t* sansa, char* filename)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
memset(sectorbuf,0,NVPARAMS_SIZE);
|
memset(sansa_sectorbuf,0,NVPARAMS_SIZE);
|
||||||
n=sansa_write(sansa, sectorbuf, NVPARAMS_SIZE);
|
n=sansa_write(sansa, sansa_sectorbuf, NVPARAMS_SIZE);
|
||||||
if (n < NVPARAMS_SIZE) {
|
if (n < NVPARAMS_SIZE) {
|
||||||
fprintf(stderr,"[ERR] Short write in sansa_update_of\n");
|
fprintf(stderr,"[ERR] Short write in sansa_update_of\n");
|
||||||
return -1;
|
return -1;
|
||||||
|
|
@ -937,7 +937,7 @@ int sansa_update_ppbl(struct sansa_t* sansa, char* filename)
|
||||||
|
|
||||||
ppbl_length = filesize(infile);
|
ppbl_length = filesize(infile);
|
||||||
|
|
||||||
n = read(infile,sectorbuf+0x200,ppbl_length);
|
n = read(infile,sansa_sectorbuf+0x200,ppbl_length);
|
||||||
close(infile);
|
close(infile);
|
||||||
if (n < ppbl_length) {
|
if (n < ppbl_length) {
|
||||||
fprintf(stderr,"[ERR] Short read - requested %d bytes, received %d\n", ppbl_length, n);
|
fprintf(stderr,"[ERR] Short read - requested %d bytes, received %d\n", ppbl_length, n);
|
||||||
|
|
@ -945,10 +945,10 @@ int sansa_update_ppbl(struct sansa_t* sansa, char* filename)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Step 2 - Build the header */
|
/* Step 2 - Build the header */
|
||||||
memset(sectorbuf,0,0x200);
|
memset(sansa_sectorbuf,0,0x200);
|
||||||
memcpy(sectorbuf,"PPBL",4);
|
memcpy(sansa_sectorbuf,"PPBL",4);
|
||||||
int2le(ppbl_length, sectorbuf+4);
|
int2le(ppbl_length, sansa_sectorbuf+4);
|
||||||
int2le(0x00010000, sectorbuf+8);
|
int2le(0x00010000, sansa_sectorbuf+8);
|
||||||
|
|
||||||
/* Step 3 - write the bootloader to the Sansa */
|
/* Step 3 - write the bootloader to the Sansa */
|
||||||
if (sansa_seek(sansa, sansa->start) < 0) {
|
if (sansa_seek(sansa, sansa->start) < 0) {
|
||||||
|
|
@ -956,7 +956,7 @@ int sansa_update_ppbl(struct sansa_t* sansa, char* filename)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
n=sansa_write(sansa, sectorbuf, ppbl_length + 0x200);
|
n=sansa_write(sansa, sansa_sectorbuf, ppbl_length + 0x200);
|
||||||
if (n < (ppbl_length+0x200)) {
|
if (n < (ppbl_length+0x200)) {
|
||||||
fprintf(stderr,"[ERR] Short write in sansa_update_ppbl\n");
|
fprintf(stderr,"[ERR] Short write in sansa_update_ppbl\n");
|
||||||
return -1;
|
return -1;
|
||||||
|
|
|
||||||
|
|
@ -26,10 +26,11 @@ extern "C" {
|
||||||
|
|
||||||
#include "sansaio.h"
|
#include "sansaio.h"
|
||||||
|
|
||||||
|
extern int sansa_verbose;
|
||||||
/* Size of buffer for disk I/O - 8MB is large enough for any version
|
/* Size of buffer for disk I/O - 8MB is large enough for any version
|
||||||
of the Apple firmware, but not the Nano's RSRC image. */
|
of the Apple firmware, but not the Nano's RSRC image. */
|
||||||
#define BUFFER_SIZE 8*1024*1024
|
#define BUFFER_SIZE 8*1024*1024
|
||||||
extern unsigned char* sectorbuf;
|
extern unsigned char* sansa_sectorbuf;
|
||||||
|
|
||||||
#define FILETYPE_MI4 0
|
#define FILETYPE_MI4 0
|
||||||
#define FILETYPE_INTERNAL 1
|
#define FILETYPE_INTERNAL 1
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue