summaryrefslogtreecommitdiff
path: root/utils/ipod/flashsplit
diff options
context:
space:
mode:
Diffstat (limited to 'utils/ipod/flashsplit')
-rw-r--r--utils/ipod/flashsplit/Makefile16
-rw-r--r--utils/ipod/flashsplit/README8
-rw-r--r--utils/ipod/flashsplit/flashsplit.c230
3 files changed, 254 insertions, 0 deletions
diff --git a/utils/ipod/flashsplit/Makefile b/utils/ipod/flashsplit/Makefile
new file mode 100644
index 0000000000..4283fd9c09
--- /dev/null
+++ b/utils/ipod/flashsplit/Makefile
@@ -0,0 +1,16 @@
1# __________ __ ___.
2# Open \______ \ ____ ____ | | _\_ |__ _______ ___
3# Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
4# Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
5# Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
6# \/ \/ \/ \/ \/
7# $Id$
8#
9
10all: flashsplit
11
12flashsplit: flashsplit.c
13 gcc -W -Wall -o flashsplit flashsplit.c
14
15clean:
16 rm -f flashsplit
diff --git a/utils/ipod/flashsplit/README b/utils/ipod/flashsplit/README
new file mode 100644
index 0000000000..bca13f9c04
--- /dev/null
+++ b/utils/ipod/flashsplit/README
@@ -0,0 +1,8 @@
1flashsplit
2----------
3
4A simple utility to split a dump of the NOR flash on an ipod.
5
6Should work on all PortalPlayer-based ipods.
7
8See http://www.rockbox.org/wiki/IpodFlash for more information.
diff --git a/utils/ipod/flashsplit/flashsplit.c b/utils/ipod/flashsplit/flashsplit.c
new file mode 100644
index 0000000000..c4bb3b4255
--- /dev/null
+++ b/utils/ipod/flashsplit/flashsplit.c
@@ -0,0 +1,230 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2007 Dave Chapman
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
16 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21
22#include <stdio.h>
23#include <fcntl.h>
24#include <unistd.h>
25#include <string.h>
26
27static void int2be(unsigned int val, unsigned char* addr)
28{
29 addr[0] = (val >> 24) & 0xff;
30 addr[1] = (val >> 16) & 0xff;
31 addr[2] = (val >> 8) & 0xff;
32 addr[3] = val & 0xFF;
33}
34
35static int le2int(unsigned char* buf)
36{
37 int32_t res = (buf[3] << 24) | (buf[2] << 16) | (buf[1] << 8) | buf[0];
38
39 return res;
40}
41
42static char* get_modelname(int version)
43{
44
45 switch (version >> 8) {
46 case 0x01:
47 return "1g2g";
48 break;
49 case 0x02:
50 return "ip3g";
51 break;
52 case 0x40:
53 return "mini";
54 break;
55 case 0x50:
56 return "ip4g";
57 break;
58 case 0x60:
59 return "ipco";
60 break;
61 case 0x70:
62 return "mn2g";
63 break;
64 case 0xc0:
65 return "nano";
66 break;
67 case 0xb0:
68 return "ipvd";
69 break;
70 }
71
72 return NULL;
73}
74
75static int get_modelnum(int version)
76{
77
78 switch (version >> 8) {
79 case 0x01:
80 return 19; // "1g2g";
81 break;
82 case 0x02:
83 return 7; // "ip3g";
84 break;
85 case 0x40:
86 return 9; // "mini";
87 break;
88 case 0x50:
89 return 8; // "ip4g";
90 break;
91 case 0x60:
92 return 3; // "ipco";
93 break;
94 case 0x70:
95 return 11; // "mn2g";
96 break;
97 case 0xc0:
98 return 4; // "nano";
99 break;
100 case 0xb0:
101 return 5; // "ipvd";
102 break;
103 }
104
105 return -1;
106}
107
108
109static void dump_app(char* name, unsigned char* p, unsigned char* flash)
110{
111 char filename[64];
112 unsigned char header[8];
113 unsigned int i;
114 unsigned int sum;
115 int outfile;
116
117 unsigned int unknown1;
118 unsigned int offset;
119 unsigned int length;
120 unsigned int loadaddr;
121 unsigned int unknown2;
122 unsigned int checksum;
123 unsigned int version;
124 unsigned int unknown3;
125 char* modelname;
126
127 /* Extract variables from header */
128 unknown1 = le2int(p+0x08);
129 offset = le2int(p+0x0c);
130 length = le2int(p+0x10);
131 loadaddr = le2int(p+0x14);
132 unknown2 = le2int(p+0x18);
133 checksum = le2int(p+0x1c);
134 version = le2int(p+0x20);
135 unknown3 = le2int(p+0x24);
136
137 modelname = get_modelname(version);
138 sum = 0;
139
140 for (i = offset; i < offset+length ; i++) {
141 sum += flash[i];
142 }
143
144 /* Display information: */
145 printf("Image: %s\n",name);
146 printf("unknown1: %08x\n",unknown1);
147 printf("offset: %08x\n",offset);
148 printf("length: %08x\n",length);
149 printf("loadaddr: %08x\n",loadaddr);
150 printf("unknown2: %08x\n",unknown2);
151 printf("checksum: %08x (flashsplit sum: %08x)\n",checksum,sum);
152 printf("version: %08x (ipod model: %s)\n",version,modelname);
153 printf("unknown3: %08x\n",unknown3);
154 printf("\n");
155
156 if (modelname == NULL) {
157 printf("Unknown version, not exporting to .ipod file\n");
158 return;
159 } else if (checksum != sum) {
160 printf("Checksum mismatch, not exporting to .ipod file\n");
161 } else {
162 sum += get_modelnum(version);
163 int2be(sum,header);
164 memcpy(header+4,modelname,4);
165
166 sprintf(filename,"%s.ipod",name);
167 outfile = open(filename,O_CREAT|O_TRUNC|O_WRONLY,0666);
168 if (outfile < 0) {
169 fprintf(stderr,"[ERR] Couldn't open file %s\n",filename);
170 return;
171 }
172
173 write(outfile,header,8);
174 write(outfile,flash+offset,length);
175 close(outfile);
176 }
177
178 sprintf(filename,"%s.bin",name);
179 outfile = open(filename,O_CREAT|O_TRUNC|O_WRONLY,0666);
180 if (outfile < 0) {
181 fprintf(stderr,"[ERR] Couldn't open file %s\n",filename);
182 return;
183 }
184
185 write(outfile,flash+offset,length);
186 close(outfile);
187}
188
189int main(int argc,char* argv[])
190{
191 int fd;
192 unsigned char buf[1024*1024];
193 unsigned char* p;
194
195 if (argc != 2) {
196 fprintf(stderr,"Usage: flashsplit flash.bin\n");
197 return 1;
198 }
199
200 fd=open(argv[1],O_RDONLY);
201 if (fd < 0) {
202 fprintf(stderr,"Can not open %s\n",argv[1]);
203 return 1;
204 }
205
206 read(fd,buf,sizeof(buf));
207 close(fd);
208
209
210 p = buf + 0xffe00; /* Start of flash directory */
211
212 while (le2int(p) != 0) {
213 if (memcmp(p,"hslfksid",8)==0) {
214 dump_app("diskmode",p,buf);
215 } else if (memcmp(p,"hslfgaid",8)==0) {
216 dump_app("diagmode",p,buf);
217 } else if (memcmp(p,"hslfogol",8)==0) {
218 dump_app("logo",p,buf);
219 } else if (memcmp(p,"hslfnacs",8)==0) {
220 dump_app("diskscan",p,buf);
221 } else if (memcmp(p,"hslfscmv",8)==0) {
222 dump_app("vmcs",p,buf);
223 } else {
224 printf("Unknown image type - %c%c%c%c%c%c%c%c\n",p[3],p[2],p[1],p[0],p[7],p[6],p[5],p[4]);
225 }
226 p += 0x28;
227 }
228
229 return 0;
230}