summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--tools/ipod_fw.c29
1 files changed, 25 insertions, 4 deletions
diff --git a/tools/ipod_fw.c b/tools/ipod_fw.c
index f5706bf783..eefe3f7db8 100644
--- a/tools/ipod_fw.c
+++ b/tools/ipod_fw.c
@@ -34,9 +34,11 @@
34 34
35#define TBL 0x4200 35#define TBL 0x4200
36 36
37int sectorsize = 512;
38
37/* Some firmwares have padding becore the actual image. */ 39/* Some firmwares have padding becore the actual image. */
38#define IMAGE_PADDING ((fw_version == 3) ? 0x200 : 0) 40#define IMAGE_PADDING ((fw_version == 3) ? sectorsize : 0)
39#define FIRST_OFFSET (TBL + 0x200 + IMAGE_PADDING) 41#define FIRST_OFFSET (TBL + ((sectorsize == 0x200) ? 0x200 : 0x600) + IMAGE_PADDING)
40 42
41int be; 43int be;
42unsigned short fw_version = 2; 44unsigned short fw_version = 2;
@@ -180,6 +182,15 @@ load_entry(image_t *image, FILE *fw, unsigned offset, int entry)
180 return -1; 182 return -1;
181 } 183 }
182 switch_endian(image); 184 switch_endian(image);
185
186 /* If we find an "osos" image with devOffset 0x4800, we have 2048-byte
187 sectors. This isn't 100% future-proof, but works as of December 2006.
188 We display this information so users can spot any false-positives that
189 may occur in the future (although this is unlikely). */
190 if ((image->id==0x6f736f73) && (image->devOffset==0x4800)) {
191 sectorsize=2048;
192 fprintf(stderr,"Detected 2048-byte sectors\n");
193 }
183 return 0; 194 return 0;
184} 195}
185 196
@@ -219,8 +230,17 @@ extract(FILE *f, int idx, FILE *out)
219 fw_version = switch_16(fw_version); 230 fw_version = switch_16(fw_version);
220 231
221 image = (image_t *)buf; 232 image = (image_t *)buf;
222 if (load_entry(image, f, TBL, idx) == -1) 233
223 return -1; 234 /* We need to detect sector size, so always load image 0 directory
235 entry first */
236 if (load_entry(image, f, TBL, 0) == -1)
237 return -1;
238
239 if (idx > 0) { /* Now read the real image (if it isn't 0) */
240 if (load_entry(image, f, TBL, idx) == -1)
241 return -1;
242 }
243
224 off = image->devOffset + IMAGE_PADDING; 244 off = image->devOffset + IMAGE_PADDING;
225 245
226 if (fseek(f, off, SEEK_SET) == -1) { 246 if (fseek(f, off, SEEK_SET) == -1) {
@@ -529,6 +549,7 @@ main(int argc, char **argv)
529 if (version) image.vers = version; 549 if (version) image.vers = version;
530 image.len = offset + len - FIRST_OFFSET; 550 image.len = offset + len - FIRST_OFFSET;
531 image.entryOffset = offset - FIRST_OFFSET; 551 image.entryOffset = offset - FIRST_OFFSET;
552 image.devOffset = (sectorsize==512 ? 0x4400 : 0x4800);
532 if ((image.chksum = copysum(out, NULL, image.len, FIRST_OFFSET)) == -1) 553 if ((image.chksum = copysum(out, NULL, image.len, FIRST_OFFSET)) == -1)
533 return 1; 554 return 1;
534 if (fseek(out, 0x0, SEEK_SET) == -1) { 555 if (fseek(out, 0x0, SEEK_SET) == -1) {