mirror of
https://github.com/Rockbox/rockbox.git
synced 2025-12-09 13:15:18 -05:00
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
This commit is contained in:
parent
deb8363751
commit
bdc27ff20c
4 changed files with 374 additions and 84 deletions
|
|
@ -1,5 +1,15 @@
|
||||||
CFLAGS=-Wall
|
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)
|
ifeq ($(findstring CYGWIN,$(shell uname)),CYGWIN)
|
||||||
OUTPUT=ipodpatcher.exe
|
OUTPUT=ipodpatcher.exe
|
||||||
CROSS=
|
CROSS=
|
||||||
|
|
@ -9,15 +19,43 @@ OUTPUT=ipodpatcher
|
||||||
CROSS=i586-mingw32msvc-
|
CROSS=i586-mingw32msvc-
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
NATIVECC = gcc
|
||||||
|
CC = $(CROSS)gcc
|
||||||
|
|
||||||
all: $(OUTPUT)
|
all: $(OUTPUT)
|
||||||
|
|
||||||
ipodpatcher: ipodpatcher.c ipodio-posix.c parttypes.h
|
ipodpatcher: ipodpatcher.c ipodio-posix.c parttypes.h $(BOOTSRC)
|
||||||
gcc $(CFLAGS) -o ipodpatcher ipodpatcher.c ipodio-posix.c
|
gcc $(CFLAGS) -o ipodpatcher ipodpatcher.c ipodio-posix.c $(BOOTSRC)
|
||||||
strip ipodpatcher
|
strip ipodpatcher
|
||||||
|
|
||||||
ipodpatcher.exe: ipodpatcher.c ipodio-win32.c parttypes.h
|
ipodpatcher.exe: ipodpatcher.c ipodio-win32.c parttypes.h $(BOOTSRC)
|
||||||
$(CROSS)gcc $(CFLAGS) -o ipodpatcher.exe ipodpatcher.c ipodio-win32.c
|
$(CC) $(CFLAGS) -o ipodpatcher.exe ipodpatcher.c ipodio-win32.c $(BOOTSRC)
|
||||||
$(CROSS)strip ipodpatcher.exe
|
$(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:
|
clean:
|
||||||
rm -f ipodpatcher.exe ipodpatcher *~
|
rm -f ipodpatcher.exe ipodpatcher ipod2c *~ $(BOOTSRC) $(BOOT_H)
|
||||||
|
|
|
||||||
139
tools/ipodpatcher/ipod2c.c
Normal file
139
tools/ipodpatcher/ipod2c.c
Normal file
|
|
@ -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;
|
||||||
|
}
|
||||||
|
|
@ -71,6 +71,10 @@ struct ipod_t {
|
||||||
char* modelname;
|
char* modelname;
|
||||||
char* modelstr;
|
char* modelstr;
|
||||||
int macpod;
|
int macpod;
|
||||||
|
#ifdef WITH_BOOTOBJS
|
||||||
|
unsigned char* bootloader;
|
||||||
|
int bootloader_len;
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
void print_error(char* msg);
|
void print_error(char* msg);
|
||||||
|
|
|
||||||
|
|
@ -29,6 +29,16 @@
|
||||||
#include "parttypes.h"
|
#include "parttypes.h"
|
||||||
#include "ipodio.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"
|
#define VERSION "0.8svn"
|
||||||
|
|
||||||
int verbose = 0;
|
int verbose = 0;
|
||||||
|
|
@ -401,12 +411,15 @@ void print_usage(void)
|
||||||
{
|
{
|
||||||
fprintf(stderr,"Usage: ipodpatcher --scan\n");
|
fprintf(stderr,"Usage: ipodpatcher --scan\n");
|
||||||
#ifdef __WIN32__
|
#ifdef __WIN32__
|
||||||
fprintf(stderr," or ipodpatcher DISKNO [action]\n");
|
fprintf(stderr," or ipodpatcher [DISKNO] [action]\n");
|
||||||
#else
|
#else
|
||||||
fprintf(stderr," or ipodpatcher device [action]\n");
|
fprintf(stderr," or ipodpatcher [device] [action]\n");
|
||||||
#endif
|
#endif
|
||||||
fprintf(stderr,"\n");
|
fprintf(stderr,"\n");
|
||||||
fprintf(stderr,"Where [action] is one of the following options:\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," -l, --list\n");
|
||||||
fprintf(stderr," -r, --read-partition bootpartition.bin\n");
|
fprintf(stderr," -r, --read-partition bootpartition.bin\n");
|
||||||
fprintf(stderr," -w, --write-partition bootpartition.bin\n");
|
fprintf(stderr," -w, --write-partition bootpartition.bin\n");
|
||||||
|
|
@ -439,6 +452,10 @@ void print_usage(void)
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
NONE,
|
NONE,
|
||||||
|
#ifdef WITH_BOOTOBJS
|
||||||
|
INSTALL,
|
||||||
|
#endif
|
||||||
|
INTERACTIVE,
|
||||||
SHOW_INFO,
|
SHOW_INFO,
|
||||||
LIST_IMAGES,
|
LIST_IMAGES,
|
||||||
DELETE_BOOTLOADER,
|
DELETE_BOOTLOADER,
|
||||||
|
|
@ -449,8 +466,11 @@ enum {
|
||||||
WRITE_PARTITION
|
WRITE_PARTITION
|
||||||
};
|
};
|
||||||
|
|
||||||
#define DOT_IPOD 0
|
#define FILETYPE_DOT_IPOD 0
|
||||||
#define DOT_BIN 1
|
#define FILETYPE_DOT_BIN 1
|
||||||
|
#ifdef WITH_BOOTOBJS
|
||||||
|
#define FILETYPE_INTERNAL 2
|
||||||
|
#endif
|
||||||
|
|
||||||
char* ftypename[] = { "OSOS", "RSRC", "AUPD", "HIBE" };
|
char* ftypename[] = { "OSOS", "RSRC", "AUPD", "HIBE" };
|
||||||
|
|
||||||
|
|
@ -548,60 +568,7 @@ int add_bootloader(struct ipod_t* ipod, char* filename, int type)
|
||||||
unsigned long filechksum=0;
|
unsigned long filechksum=0;
|
||||||
unsigned char header[8]; /* Header for .ipod file */
|
unsigned char header[8]; /* Header for .ipod file */
|
||||||
|
|
||||||
infile=open(filename,O_RDONLY);
|
/* Calculate the position in the OSOS image where our bootloader will go. */
|
||||||
if (infile < 0) {
|
|
||||||
fprintf(stderr,"[ERR] Couldn't open input file %s\n",filename);
|
|
||||||
return -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);
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
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");
|
|
||||||
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);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ipod->ipod_directory[0].entryOffset>0) {
|
if (ipod->ipod_directory[0].entryOffset>0) {
|
||||||
/* Keep the same entryOffset */
|
/* Keep the same entryOffset */
|
||||||
entryOffset = ipod->ipod_directory[0].entryOffset;
|
entryOffset = ipod->ipod_directory[0].entryOffset;
|
||||||
|
|
@ -609,9 +576,74 @@ int add_bootloader(struct ipod_t* ipod, char* filename, int type)
|
||||||
entryOffset = (ipod->ipod_directory[0].len+ipod->sector_size-1)&~(ipod->sector_size-1);
|
entryOffset = (ipod->ipod_directory[0].len+ipod->sector_size-1)&~(ipod->sector_size-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#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 (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);
|
||||||
|
}
|
||||||
|
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);
|
||||||
|
|
||||||
|
if (n < 0) {
|
||||||
|
fprintf(stderr,"[ERR] Couldn't read input file\n");
|
||||||
|
return -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) {
|
if (entryOffset+paddedlength > BUFFER_SIZE) {
|
||||||
fprintf(stderr,"[ERR] Input file too big for buffer\n");
|
fprintf(stderr,"[ERR] Input file too big for buffer\n");
|
||||||
close(infile);
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -624,14 +656,13 @@ int add_bootloader(struct ipod_t* ipod, char* filename, int type)
|
||||||
/* Check if we have enough space */
|
/* Check if we have enough space */
|
||||||
/* TODO: Check the size of the partition. */
|
/* TODO: Check the size of the partition. */
|
||||||
if (ipod->nimages > 1) {
|
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) {
|
ipod->ipod_directory[1].devOffset) {
|
||||||
fprintf(stderr,"[INFO] Moving images to create room for new firmware...\n");
|
fprintf(stderr,"[INFO] Moving images to create room for new firmware...\n");
|
||||||
delta = ipod->ipod_directory[0].devOffset + entryOffset+paddedlength
|
delta = ipod->ipod_directory[0].devOffset + entryOffset+paddedlength
|
||||||
- ipod->ipod_directory[1].devOffset;
|
- ipod->ipod_directory[1].devOffset;
|
||||||
|
|
||||||
if (diskmove(ipod, delta) < 0) {
|
if (diskmove(ipod, delta) < 0) {
|
||||||
close(infile);
|
|
||||||
fprintf(stderr,"[ERR] Image movement failed.\n");
|
fprintf(stderr,"[ERR] Image movement failed.\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
@ -643,7 +674,6 @@ int add_bootloader(struct ipod_t* ipod, char* filename, int type)
|
||||||
|
|
||||||
/* Firstly read the original firmware into sectorbuf */
|
/* Firstly read the original firmware into 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;
|
||||||
|
|
@ -660,16 +690,6 @@ int add_bootloader(struct ipod_t* ipod, char* filename, int type)
|
||||||
return -1;
|
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 */
|
/* Calculate new checksum for combined image */
|
||||||
chksum = 0;
|
chksum = 0;
|
||||||
for (i=0;i<entryOffset + length; i++) {
|
for (i=0;i<entryOffset + length; i++) {
|
||||||
|
|
@ -830,7 +850,7 @@ int write_firmware(struct ipod_t* ipod, char* filename, int type)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (type==DOT_IPOD) {
|
if (type==FILETYPE_DOT_IPOD) {
|
||||||
n = read(infile,header,8);
|
n = read(infile,header,8);
|
||||||
if (n < 8) {
|
if (n < 8) {
|
||||||
fprintf(stderr,"[ERR] Failed to read header from %s\n",filename);
|
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);
|
close(infile);
|
||||||
|
|
||||||
if (type==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 */
|
||||||
|
|
@ -1170,40 +1190,72 @@ int getmodel(struct ipod_t* ipod, int ipod_version)
|
||||||
ipod->modelstr="3rd Generation";
|
ipod->modelstr="3rd Generation";
|
||||||
ipod->modelnum = 7;
|
ipod->modelnum = 7;
|
||||||
ipod->modelname = "ip3g";
|
ipod->modelname = "ip3g";
|
||||||
|
#ifdef WITH_BOOTOBJS
|
||||||
|
ipod->bootloader = ipod3g;
|
||||||
|
ipod->bootloader_len = LEN_ipod3g;
|
||||||
|
#endif
|
||||||
break;
|
break;
|
||||||
case 0x40:
|
case 0x40:
|
||||||
ipod->modelstr="1st Generation Mini";
|
ipod->modelstr="1st Generation Mini";
|
||||||
ipod->modelnum = 9;
|
ipod->modelnum = 9;
|
||||||
ipod->modelname = "mini";
|
ipod->modelname = "mini";
|
||||||
|
#ifdef WITH_BOOTOBJS
|
||||||
|
ipod->bootloader = ipodmini;
|
||||||
|
ipod->bootloader_len = LEN_ipodmini;
|
||||||
|
#endif
|
||||||
break;
|
break;
|
||||||
case 0x50:
|
case 0x50:
|
||||||
ipod->modelstr="4th Generation";
|
ipod->modelstr="4th Generation";
|
||||||
ipod->modelnum = 8;
|
ipod->modelnum = 8;
|
||||||
ipod->modelname = "ip4g";
|
ipod->modelname = "ip4g";
|
||||||
|
#ifdef WITH_BOOTOBJS
|
||||||
|
ipod->bootloader = ipod4g;
|
||||||
|
ipod->bootloader_len = LEN_ipod4g;
|
||||||
|
#endif
|
||||||
break;
|
break;
|
||||||
case 0x60:
|
case 0x60:
|
||||||
ipod->modelstr="Photo/Color";
|
ipod->modelstr="Photo/Color";
|
||||||
ipod->modelnum = 3;
|
ipod->modelnum = 3;
|
||||||
ipod->modelname = "ipco";
|
ipod->modelname = "ipco";
|
||||||
|
#ifdef WITH_BOOTOBJS
|
||||||
|
ipod->bootloader = ipodcolor;
|
||||||
|
ipod->bootloader_len = LEN_ipodcolor;
|
||||||
|
#endif
|
||||||
break;
|
break;
|
||||||
case 0x70:
|
case 0x70:
|
||||||
ipod->modelstr="2nd Generation Mini";
|
ipod->modelstr="2nd Generation Mini";
|
||||||
ipod->modelnum = 11;
|
ipod->modelnum = 11;
|
||||||
ipod->modelname = "mn2g";
|
ipod->modelname = "mn2g";
|
||||||
|
#ifdef WITH_BOOTOBJS
|
||||||
|
ipod->bootloader = ipodmini2g;
|
||||||
|
ipod->bootloader_len = LEN_ipodmini2g;
|
||||||
|
#endif
|
||||||
break;
|
break;
|
||||||
case 0xc0:
|
case 0xc0:
|
||||||
ipod->modelstr="1st Generation Nano";
|
ipod->modelstr="1st Generation Nano";
|
||||||
ipod->modelnum = 4;
|
ipod->modelnum = 4;
|
||||||
ipod->modelname = "nano";
|
ipod->modelname = "nano";
|
||||||
|
#ifdef WITH_BOOTOBJS
|
||||||
|
ipod->bootloader = ipodnano;
|
||||||
|
ipod->bootloader_len = LEN_ipodnano;
|
||||||
|
#endif
|
||||||
break;
|
break;
|
||||||
case 0xb0:
|
case 0xb0:
|
||||||
ipod->modelstr="Video (aka 5th Generation)";
|
ipod->modelstr="Video (aka 5th Generation)";
|
||||||
ipod->modelnum = 5;
|
ipod->modelnum = 5;
|
||||||
ipod->modelname = "ipvd";
|
ipod->modelname = "ipvd";
|
||||||
|
#ifdef WITH_BOOTOBJS
|
||||||
|
ipod->bootloader = ipodvideo;
|
||||||
|
ipod->bootloader_len = LEN_ipodvideo;
|
||||||
|
#endif
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
ipod->modelname = NULL;
|
ipod->modelname = NULL;
|
||||||
ipod->modelnum = 0;
|
ipod->modelnum = 0;
|
||||||
|
#ifdef WITH_BOOTOBJS
|
||||||
|
ipod->bootloader = NULL;
|
||||||
|
ipod->bootloader_len = 0;
|
||||||
|
#endif
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
|
@ -1279,6 +1331,9 @@ int ipod_scan(struct ipod_t* ipod)
|
||||||
|
|
||||||
int main(int argc, char* argv[])
|
int main(int argc, char* argv[])
|
||||||
{
|
{
|
||||||
|
#ifdef WITH_BOOTOBJS
|
||||||
|
char yesno[4];
|
||||||
|
#endif
|
||||||
int i;
|
int i;
|
||||||
int n;
|
int n;
|
||||||
int infile, outfile;
|
int infile, outfile;
|
||||||
|
|
@ -1320,18 +1375,40 @@ int main(int argc, char* argv[])
|
||||||
n = ipod_scan(&ipod);
|
n = ipod_scan(&ipod);
|
||||||
if (n==0) {
|
if (n==0) {
|
||||||
fprintf(stderr,"[ERR] No ipods found, aborting\n");
|
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) {
|
} else if (n > 1) {
|
||||||
fprintf(stderr,"[ERR] %d ipods found, aborting\n",n);
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
i = 1;
|
i = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef WITH_BOOTOBJS
|
||||||
|
action = INTERACTIVE;
|
||||||
|
#else
|
||||||
|
action = NONE;
|
||||||
|
#endif
|
||||||
|
|
||||||
while (i < argc) {
|
while (i < argc) {
|
||||||
if ((strcmp(argv[i],"-l")==0) || (strcmp(argv[i],"--list")==0)) {
|
if ((strcmp(argv[i],"-l")==0) || (strcmp(argv[i],"--list")==0)) {
|
||||||
action = LIST_IMAGES;
|
action = LIST_IMAGES;
|
||||||
i++;
|
i++;
|
||||||
|
#ifdef WITH_BOOTOBJS
|
||||||
|
} else if (strcmp(argv[i],"--install")==0) {
|
||||||
|
action = INSTALL;
|
||||||
|
i++;
|
||||||
|
#endif
|
||||||
} else if ((strcmp(argv[i],"-d")==0) ||
|
} else if ((strcmp(argv[i],"-d")==0) ||
|
||||||
(strcmp(argv[i],"--delete-bootloader")==0)) {
|
(strcmp(argv[i],"--delete-bootloader")==0)) {
|
||||||
action = DELETE_BOOTLOADER;
|
action = DELETE_BOOTLOADER;
|
||||||
|
|
@ -1339,7 +1416,7 @@ int main(int argc, char* argv[])
|
||||||
} else if ((strcmp(argv[i],"-a")==0) ||
|
} else if ((strcmp(argv[i],"-a")==0) ||
|
||||||
(strcmp(argv[i],"--add-bootloader")==0)) {
|
(strcmp(argv[i],"--add-bootloader")==0)) {
|
||||||
action = ADD_BOOTLOADER;
|
action = ADD_BOOTLOADER;
|
||||||
type = DOT_IPOD;
|
type = FILETYPE_DOT_IPOD;
|
||||||
i++;
|
i++;
|
||||||
if (i == argc) { print_usage(); return 1; }
|
if (i == argc) { print_usage(); return 1; }
|
||||||
filename=argv[i];
|
filename=argv[i];
|
||||||
|
|
@ -1347,7 +1424,7 @@ int main(int argc, char* argv[])
|
||||||
} else if ((strcmp(argv[i],"-ab")==0) ||
|
} else if ((strcmp(argv[i],"-ab")==0) ||
|
||||||
(strcmp(argv[i],"--add-bootloader-bin")==0)) {
|
(strcmp(argv[i],"--add-bootloader-bin")==0)) {
|
||||||
action = ADD_BOOTLOADER;
|
action = ADD_BOOTLOADER;
|
||||||
type = DOT_BIN;
|
type = FILETYPE_DOT_BIN;
|
||||||
i++;
|
i++;
|
||||||
if (i == argc) { print_usage(); return 1; }
|
if (i == argc) { print_usage(); return 1; }
|
||||||
filename=argv[i];
|
filename=argv[i];
|
||||||
|
|
@ -1362,7 +1439,7 @@ int main(int argc, char* argv[])
|
||||||
} else if ((strcmp(argv[i],"-wf")==0) ||
|
} else if ((strcmp(argv[i],"-wf")==0) ||
|
||||||
(strcmp(argv[i],"--write-firmware")==0)) {
|
(strcmp(argv[i],"--write-firmware")==0)) {
|
||||||
action = WRITE_FIRMWARE;
|
action = WRITE_FIRMWARE;
|
||||||
type = DOT_IPOD;
|
type = FILETYPE_DOT_IPOD;
|
||||||
i++;
|
i++;
|
||||||
if (i == argc) { print_usage(); return 1; }
|
if (i == argc) { print_usage(); return 1; }
|
||||||
filename=argv[i];
|
filename=argv[i];
|
||||||
|
|
@ -1370,7 +1447,7 @@ int main(int argc, char* argv[])
|
||||||
} else if ((strcmp(argv[i],"-wfb")==0) ||
|
} else if ((strcmp(argv[i],"-wfb")==0) ||
|
||||||
(strcmp(argv[i],"--write-firmware-bin")==0)) {
|
(strcmp(argv[i],"--write-firmware-bin")==0)) {
|
||||||
action = WRITE_FIRMWARE;
|
action = WRITE_FIRMWARE;
|
||||||
type = DOT_BIN;
|
type = FILETYPE_DOT_BIN;
|
||||||
i++;
|
i++;
|
||||||
if (i == argc) { print_usage(); return 1; }
|
if (i == argc) { print_usage(); return 1; }
|
||||||
filename=argv[i];
|
filename=argv[i];
|
||||||
|
|
@ -1444,6 +1521,26 @@ int main(int argc, char* argv[])
|
||||||
|
|
||||||
if (action==LIST_IMAGES) {
|
if (action==LIST_IMAGES) {
|
||||||
list_images(&ipod);
|
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) {
|
} else if (action==DELETE_BOOTLOADER) {
|
||||||
if (ipod_reopen_rw(&ipod) < 0) {
|
if (ipod_reopen_rw(&ipod) < 0) {
|
||||||
return 5;
|
return 5;
|
||||||
|
|
@ -1468,6 +1565,18 @@ int main(int argc, char* argv[])
|
||||||
} else {
|
} else {
|
||||||
fprintf(stderr,"[ERR] --add-bootloader failed.\n");
|
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) {
|
} else if (action==WRITE_FIRMWARE) {
|
||||||
if (ipod_reopen_rw(&ipod) < 0) {
|
if (ipod_reopen_rw(&ipod) < 0) {
|
||||||
return 5;
|
return 5;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue