From c52ae7abe7bdcf398d4adf79b5f5bd0760fda73a Mon Sep 17 00:00:00 2001 From: Dave Chapman Date: Fri, 21 Jul 2006 16:16:48 +0000 Subject: Initial support for creating ipod firmware partition images. Only tested on an ipod photo so far, and will definitely not work on either a 3g or a 5g. If you never want to use the Apple firmware, you can create a firmware partition image containing just the Rockbox bootloader with the command "../tools/scramble -ipod bootloader/bootloader.bin bootloader.img" and then write bootloader.img to your firmware partition. git-svn-id: svn://svn.rockbox.org/rockbox/trunk@10275 a1c6a512-1295-4272-9138-f99709370657 --- tools/scramble.c | 113 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 113 insertions(+) (limited to 'tools') diff --git a/tools/scramble.c b/tools/scramble.c index 8bab41596a..8e104cc43c 100644 --- a/tools/scramble.c +++ b/tools/scramble.c @@ -23,6 +23,7 @@ #include "iriver.h" int iaudio_encode(char *iname, char *oname, char *idstring); +int ipod_encode(char *iname, char *oname, int fw_ver); enum { @@ -42,6 +43,12 @@ int size_limit[] = 0x64000 /* ARCHOS_ONDIO_FM */ }; +void short2le(unsigned short val, unsigned char* addr) +{ + addr[0] = val & 0xFF; + addr[1] = (val >> 8) & 0xff; +} + void int2le(unsigned int val, unsigned char* addr) { addr[0] = val & 0xFF; @@ -211,6 +218,11 @@ int main (int argc, char** argv) oname = argv[3]; return iaudio_encode(iname, oname, "COWON_X5V_FW"); } + else if(!strcmp(argv[1], "-ipod")) { + iname = argv[2]; + oname = argv[3]; + return ipod_encode(iname, oname, 3); /* Firmware image v3 */ + } /* open file */ file = fopen(iname,"rb"); @@ -437,3 +449,104 @@ int iaudio_encode(char *iname, char *oname, char *idstring) fclose(file); } + + +/* Create an ipod firmware partition image + + fw_ver = 2 for 3rd Gen ipods, 3 for all later ipods including 5g. + + This function doesn't yet handle the Broadcom resource image for the 5g, + so the resulting images won't be usable. + + This has also only been tested on an ipod Photo +*/ + +int ipod_encode(char *iname, char *oname, int fw_ver) +{ + static const char *apple_stop_sign = "{{~~ /-----\\ "\ + "{{~~ / \\ "\ + "{{~~| | "\ + "{{~~| S T O P | "\ + "{{~~| | "\ + "{{~~ \\ / "\ + "{{~~ \\-----/ "\ + "Copyright(C) 200"\ + "1 Apple Computer"\ + ", Inc.----------"\ + "----------------"\ + "----------------"\ + "----------------"\ + "----------------"\ + "----------------"\ + "---------------"; + size_t len; + int length; + FILE *file; + unsigned char *outbuf; + int i; + unsigned int sum = 0; + + file = fopen(iname, "rb"); + if (!file) { + perror(iname); + return -1; + } + fseek(file,0,SEEK_END); + length = ftell(file); + + fseek(file,0,SEEK_SET); + outbuf = malloc(length+0x4600); + + if ( !outbuf ) { + printf("out of memory!\n"); + return -1; + } + + len = fread(outbuf+0x4600, 1, length, file); + if(len < length) { + perror(iname); + return -2; + } + fclose(file); + + /* Calculate checksum for later use in header */ + for(i = 0x4600; i < 0x4600+length;i++) + sum += outbuf[i]; + + /* Clear the header area to zero */ + memset(outbuf, 0, 0x4600); + + /* APPLE STOP SIGN */ + strcpy((char *)outbuf, apple_stop_sign); + + /* VOLUME HEADER */ + memcpy(&outbuf[0x100],"]ih[",4); /* Magic */ + int2le(0x4000, &outbuf[0x104]); /* Firmware offset relative to 0x200 */ + short2le(0x10c, &outbuf[0x108]); /* Location of extended header */ + short2le(fw_ver, &outbuf[0x10a]); + + /* Firmware Directory - "osos" entry */ + memcpy(&outbuf[0x4200],"!ATAsoso",8); /* dev and type */ + int2le(0, &outbuf[0x4208]); /* id */ + int2le(0x4400, &outbuf[0x420c]); /* devOffset */ + int2le(length, &outbuf[0x4210]); /* Length of firmware */ + int2le(0x10000000, &outbuf[0x4214]); /* Addr */ + int2le(0, &outbuf[0x4218]); /* Entry Offset */ + int2le(sum, &outbuf[0x421c]); /* Checksum */ + int2le(0x00006012, &outbuf[0x4220]); /* vers - 0x6012 is a guess */ + int2le(0xffffffff, &outbuf[0x4224]); /* LoadAddr - for flash images */ + + file = fopen(oname, "wb"); + if (!file) { + perror(oname); + return -3; + } + + len = fwrite(outbuf, 1, length+0x4600, file); + if(len < length) { + perror(oname); + return -4; + } + + fclose(file); +} -- cgit v1.2.3