diff options
Diffstat (limited to 'tools')
-rw-r--r-- | tools/Makefile | 5 | ||||
-rw-r--r-- | tools/mi4.c | 188 | ||||
-rw-r--r-- | tools/mi4.h | 25 | ||||
-rw-r--r-- | tools/scramble.c | 13 |
4 files changed, 229 insertions, 2 deletions
diff --git a/tools/Makefile b/tools/Makefile index 68fcd4b6bc..53b1200fce 100644 --- a/tools/Makefile +++ b/tools/Makefile | |||
@@ -10,17 +10,18 @@ CFLAGS := -O -ansi -g | |||
10 | LDFLAGS := -g | 10 | LDFLAGS := -g |
11 | 11 | ||
12 | CLEANALL := scramble descramble iriver sh2d bmp2rb rdf2binary convbdf \ | 12 | CLEANALL := scramble descramble iriver sh2d bmp2rb rdf2binary convbdf \ |
13 | generate_rocklatin mkboot ipod_fw codepages uclpack | 13 | generate_rocklatin mkboot ipod_fw codepages uclpack mi4 |
14 | 14 | ||
15 | all: | 15 | all: |
16 | @echo "Run make in your build directory!" | 16 | @echo "Run make in your build directory!" |
17 | 17 | ||
18 | scramble: scramble.o iriver.o | 18 | scramble: scramble.o iriver.o mi4.o |
19 | descramble: descramble.o iriver.o | 19 | descramble: descramble.o iriver.o |
20 | 20 | ||
21 | scramble.o: scramble.c iriver.h | 21 | scramble.o: scramble.c iriver.h |
22 | descramble.o: descramble.c iriver.h | 22 | descramble.o: descramble.c iriver.h |
23 | iriver.o: iriver.c iriver.h | 23 | iriver.o: iriver.c iriver.h |
24 | mi4.o: mi4.c mi4.h | ||
24 | 25 | ||
25 | sh2d: sh2d.c | 26 | sh2d: sh2d.c |
26 | 27 | ||
diff --git a/tools/mi4.c b/tools/mi4.c new file mode 100644 index 0000000000..b0fff98e1c --- /dev/null +++ b/tools/mi4.c | |||
@@ -0,0 +1,188 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Copyright (C) 2006 Dave Chapman | ||
11 | * | ||
12 | * All files in this archive are subject to the GNU General Public License. | ||
13 | * See the file COPYING in the source tree root for full license agreement. | ||
14 | * | ||
15 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
16 | * KIND, either express or implied. | ||
17 | * | ||
18 | ****************************************************************************/ | ||
19 | |||
20 | #include <stdio.h> | ||
21 | #include <stdlib.h> | ||
22 | #include <string.h> | ||
23 | |||
24 | /* | ||
25 | * CRC32 implementation taken from: | ||
26 | * | ||
27 | * efone - Distributed internet phone system. | ||
28 | * | ||
29 | * (c) 1999,2000 Krzysztof Dabrowski | ||
30 | * (c) 1999,2000 ElysiuM deeZine | ||
31 | * | ||
32 | * This program is free software; you can redistribute it and/or | ||
33 | * modify it under the terms of the GNU General Public License | ||
34 | * as published by the Free Software Foundation; either version | ||
35 | * 2 of the License, or (at your option) any later version. | ||
36 | * | ||
37 | */ | ||
38 | |||
39 | /* based on implementation by Finn Yannick Jacobs */ | ||
40 | |||
41 | #include <stdio.h> | ||
42 | #include <stdlib.h> | ||
43 | |||
44 | /* crc_tab[] -- this crcTable is being build by chksum_crc32GenTab(). | ||
45 | * so make sure, you call it before using the other | ||
46 | * functions! | ||
47 | */ | ||
48 | static unsigned int crc_tab[256]; | ||
49 | |||
50 | /* chksum_crc() -- to a given block, this one calculates the | ||
51 | * crc32-checksum until the length is | ||
52 | * reached. the crc32-checksum will be | ||
53 | * the result. | ||
54 | */ | ||
55 | static unsigned int chksum_crc32 (unsigned char *block, unsigned int length) | ||
56 | { | ||
57 | register unsigned long crc; | ||
58 | unsigned long i; | ||
59 | |||
60 | crc = 0; | ||
61 | for (i = 0; i < length; i++) | ||
62 | { | ||
63 | crc = ((crc >> 8) & 0x00FFFFFF) ^ crc_tab[(crc ^ *block++) & 0xFF]; | ||
64 | } | ||
65 | return (crc); | ||
66 | } | ||
67 | |||
68 | /* chksum_crc32gentab() -- to a global crc_tab[256], this one will | ||
69 | * calculate the crcTable for crc32-checksums. | ||
70 | * it is generated to the polynom [..] | ||
71 | */ | ||
72 | |||
73 | static void chksum_crc32gentab (void) | ||
74 | { | ||
75 | unsigned long crc, poly; | ||
76 | int i, j; | ||
77 | |||
78 | poly = 0xEDB88320L; | ||
79 | for (i = 0; i < 256; i++) | ||
80 | { | ||
81 | crc = i; | ||
82 | for (j = 8; j > 0; j--) | ||
83 | { | ||
84 | if (crc & 1) | ||
85 | { | ||
86 | crc = (crc >> 1) ^ poly; | ||
87 | } | ||
88 | else | ||
89 | { | ||
90 | crc >>= 1; | ||
91 | } | ||
92 | } | ||
93 | crc_tab[i] = crc; | ||
94 | } | ||
95 | } | ||
96 | |||
97 | static void int2le(unsigned int val, unsigned char* addr) | ||
98 | { | ||
99 | addr[0] = val & 0xFF; | ||
100 | addr[1] = (val >> 8) & 0xff; | ||
101 | addr[2] = (val >> 16) & 0xff; | ||
102 | addr[3] = (val >> 24) & 0xff; | ||
103 | } | ||
104 | |||
105 | int mi4_encode(char *iname, char *oname, int version) | ||
106 | { | ||
107 | size_t len; | ||
108 | int length; | ||
109 | int mi4length; | ||
110 | FILE *file; | ||
111 | unsigned int crc = 0; | ||
112 | unsigned char *outbuf; | ||
113 | |||
114 | file = fopen(iname, "rb"); | ||
115 | if (!file) { | ||
116 | perror(iname); | ||
117 | return -1; | ||
118 | } | ||
119 | fseek(file,0,SEEK_END); | ||
120 | length = ftell(file); | ||
121 | |||
122 | fseek(file,0,SEEK_SET); | ||
123 | |||
124 | /* Add 4 bytes to length (for magic), the 0x200 byte header and | ||
125 | then round to an even 0x400 bytes | ||
126 | */ | ||
127 | mi4length = (length+4+0x200+0x3ff)&~0x3ff; | ||
128 | |||
129 | outbuf = malloc(mi4length); | ||
130 | |||
131 | if ( !outbuf ) { | ||
132 | printf("out of memory!\n"); | ||
133 | return -1; | ||
134 | } | ||
135 | |||
136 | /* Clear the buffer to zero */ | ||
137 | memset(outbuf, 0, mi4length); | ||
138 | |||
139 | len = fread(outbuf+0x200, 1, length, file); | ||
140 | if(len < length) { | ||
141 | perror(iname); | ||
142 | return -2; | ||
143 | } | ||
144 | fclose(file); | ||
145 | |||
146 | /* We need to write some data into the actual image - before calculating | ||
147 | the CRC. */ | ||
148 | int2le(0x00000100, &outbuf[0x2e0]); /* magic */ | ||
149 | int2le(0x000000ec, &outbuf[0x2e4]); /* magic */ | ||
150 | int2le(length+4, &outbuf[0x2e8]); /* length plus 0xaa55aa55 */ | ||
151 | |||
152 | int2le(0xaa55aa55, &outbuf[0x200+length]); /* More Magic */ | ||
153 | |||
154 | /* Calculate CRC32 checksum */ | ||
155 | chksum_crc32gentab (); | ||
156 | crc = chksum_crc32 (outbuf+28,mi4length-28); | ||
157 | |||
158 | strncpy((char *)outbuf, "PPOS", 4); /* Magic */ | ||
159 | int2le(version, &outbuf[0x04]); /* .mi4 version */ | ||
160 | int2le(length+4, &outbuf[0x08]); /* Length of firmware plus magic */ | ||
161 | int2le(crc, &outbuf[0x0c]); /* CRC32 of mi4 file */ | ||
162 | int2le(0x00000002, &outbuf[0x10]); /* Encryption type: 2 = TEA */ | ||
163 | int2le(mi4length, &outbuf[0x14]); /* Total .mi4 length */ | ||
164 | int2le(mi4length-0x200, &outbuf[0x18]); /* Length of plaintext part */ | ||
165 | |||
166 | /* v3 files require a dummy DSA signature */ | ||
167 | if (version == 0x00010301) { | ||
168 | outbuf[0x2f]=0x01; | ||
169 | } | ||
170 | |||
171 | file = fopen(oname, "wb"); | ||
172 | if (!file) { | ||
173 | perror(oname); | ||
174 | return -3; | ||
175 | } | ||
176 | |||
177 | len = fwrite(outbuf, 1, mi4length, file); | ||
178 | if(len < length) { | ||
179 | perror(oname); | ||
180 | return -4; | ||
181 | } | ||
182 | |||
183 | fclose(file); | ||
184 | |||
185 | fprintf(stderr, "File encoded successfully\n" ); | ||
186 | |||
187 | return 0; | ||
188 | } | ||
diff --git a/tools/mi4.h b/tools/mi4.h new file mode 100644 index 0000000000..ec3a7342d0 --- /dev/null +++ b/tools/mi4.h | |||
@@ -0,0 +1,25 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Copyright (C) 2006 Dave Chapman | ||
11 | * | ||
12 | * All files in this archive are subject to the GNU General Public License. | ||
13 | * See the file COPYING in the source tree root for full license agreement. | ||
14 | * | ||
15 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
16 | * KIND, either express or implied. | ||
17 | * | ||
18 | ****************************************************************************/ | ||
19 | |||
20 | #ifndef _MI4_H | ||
21 | #define _MI4_H | ||
22 | |||
23 | int mi4_encode(char *iname, char *oname, int version); | ||
24 | |||
25 | #endif | ||
diff --git a/tools/scramble.c b/tools/scramble.c index c3eb1782af..d1e3d1d341 100644 --- a/tools/scramble.c +++ b/tools/scramble.c | |||
@@ -22,6 +22,7 @@ | |||
22 | #include <stdbool.h> | 22 | #include <stdbool.h> |
23 | #include <string.h> | 23 | #include <string.h> |
24 | #include "iriver.h" | 24 | #include "iriver.h" |
25 | #include "mi4.h" | ||
25 | 26 | ||
26 | int iaudio_encode(char *iname, char *oname, char *idstring); | 27 | int iaudio_encode(char *iname, char *oname, char *idstring); |
27 | int ipod_encode(char *iname, char *oname, int fw_ver, bool fake_rsrc); | 28 | int ipod_encode(char *iname, char *oname, int fw_ver, bool fake_rsrc); |
@@ -82,6 +83,8 @@ void usage(void) | |||
82 | "\t-ipod3g ipod firmware partition format (3rd Gen)\n" | 83 | "\t-ipod3g ipod firmware partition format (3rd Gen)\n" |
83 | "\t-ipod4g ipod firmware partition format (4th Gen, Mini, Nano, Photo/Color)\n" | 84 | "\t-ipod4g ipod firmware partition format (4th Gen, Mini, Nano, Photo/Color)\n" |
84 | "\t-ipod5g ipod firmware partition format (5th Gen - aka Video)\n" | 85 | "\t-ipod5g ipod firmware partition format (5th Gen - aka Video)\n" |
86 | "\t-mi4v2 PortalPlayer .mi4 format (revision 010201)\n" | ||
87 | "\t-mi4v3 PortalPlayer .mi4 format (revision 010301)\n" | ||
85 | "\t-add=X Rockbox generic \"add-up\" checksum format\n" | 88 | "\t-add=X Rockbox generic \"add-up\" checksum format\n" |
86 | "\t (X values: h100, h120, h140, h300, ipco, nano, ipvd\n" | 89 | "\t (X values: h100, h120, h140, h300, ipco, nano, ipvd\n" |
87 | "\t ip3g, ip4g, mini, x5, h10, h10_5gb)\n" | 90 | "\t ip3g, ip4g, mini, x5, h10, h10_5gb)\n" |
@@ -241,6 +244,16 @@ int main (int argc, char** argv) | |||
241 | oname = argv[3]; | 244 | oname = argv[3]; |
242 | return ipod_encode(iname, oname, 3, true); /* Firmware image v3 */ | 245 | return ipod_encode(iname, oname, 3, true); /* Firmware image v3 */ |
243 | } | 246 | } |
247 | else if(!strcmp(argv[1], "-mi4v2")) { | ||
248 | iname = argv[2]; | ||
249 | oname = argv[3]; | ||
250 | return mi4_encode(iname, oname, 0x00010201); | ||
251 | } | ||
252 | else if(!strcmp(argv[1], "-mi4v3")) { | ||
253 | iname = argv[2]; | ||
254 | oname = argv[3]; | ||
255 | return mi4_encode(iname, oname, 0x00010301); | ||
256 | } | ||
244 | 257 | ||
245 | /* open file */ | 258 | /* open file */ |
246 | file = fopen(iname,"rb"); | 259 | file = fopen(iname,"rb"); |