diff options
-rw-r--r-- | tools/ipod_fw.c | 29 |
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 | ||
37 | int 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 | ||
41 | int be; | 43 | int be; |
42 | unsigned short fw_version = 2; | 44 | unsigned 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) { |