diff options
author | Marcin Bukat <marcin.bukat@gmail.com> | 2012-02-28 23:36:13 +0100 |
---|---|---|
committer | Marcin Bukat <marcin.bukat@gmail.com> | 2012-03-04 00:33:41 +0100 |
commit | f35e300304388c30fdeb6493ec5e5e5bd52e3aab (patch) | |
tree | db0bfba04e30c59dea9b94c902541c86e494dc3c | |
parent | 1c565c9c3b5005ca1f1708040718e35a0cf69e88 (diff) | |
download | rockbox-f35e300304388c30fdeb6493ec5e5e5bd52e3aab.tar.gz rockbox-f35e300304388c30fdeb6493ec5e5e5bd52e3aab.zip |
scramble: add RKW firmware file format encoder
Change-Id: I8057d6186724c3e8a319a262f45c12da7afb722e
-rw-r--r-- | tools/Makefile | 5 | ||||
-rw-r--r-- | tools/rkw.c | 166 | ||||
-rw-r--r-- | tools/rkw.h | 26 | ||||
-rw-r--r-- | tools/scramble.c | 30 | ||||
-rw-r--r-- | tools/tools.make | 4 |
5 files changed, 222 insertions, 9 deletions
diff --git a/tools/Makefile b/tools/Makefile index da0d3dfb8a..2b4b1ae88b 100644 --- a/tools/Makefile +++ b/tools/Makefile | |||
@@ -18,10 +18,10 @@ all: scramble descramble sh2d rdf2binary mkboot mkzenboot convbdf codepages \ | |||
18 | uclpack rbspeexenc voicefont mk500boot | 18 | uclpack rbspeexenc voicefont mk500boot |
19 | 19 | ||
20 | scramble: scramble.o iriver.o mi4.o gigabeat.o gigabeats.o telechips.o \ | 20 | scramble: scramble.o iriver.o mi4.o gigabeat.o gigabeats.o telechips.o \ |
21 | iaudio_bl_flash.o creative.o hmac-sha1.o | 21 | iaudio_bl_flash.o creative.o hmac-sha1.o rkw.o |
22 | descramble: descramble.o iriver.o gigabeat.o | 22 | descramble: descramble.o iriver.o gigabeat.o |
23 | scramble.o: scramble.c iriver.h mi4.h gigabeat.h telechips.h iaudio_bl_flash.h \ | 23 | scramble.o: scramble.c iriver.h mi4.h gigabeat.h telechips.h iaudio_bl_flash.h \ |
24 | creative.h | 24 | creative.h rkw.h |
25 | 25 | ||
26 | descramble.o: descramble.c iriver.h gigabeat.h | 26 | descramble.o: descramble.c iriver.h gigabeat.h |
27 | creative.o: creative.c creative.h | 27 | creative.o: creative.c creative.h |
@@ -31,6 +31,7 @@ gigabeat.o: gigabeat.c gigabeat.h | |||
31 | gigabeats.o: gigabeats.c gigabeats.h | 31 | gigabeats.o: gigabeats.c gigabeats.h |
32 | mi4.o: mi4.c mi4.h | 32 | mi4.o: mi4.c mi4.h |
33 | telechips.o: telechips.c telechips.h | 33 | telechips.o: telechips.c telechips.h |
34 | rkw.o: rkw.c rkw.h | ||
34 | iaudio_bl_flash.o: iaudio_bl_flash.c iaudio_bl_flash.h | 35 | iaudio_bl_flash.o: iaudio_bl_flash.c iaudio_bl_flash.h |
35 | iaudio_bl_flash.c iaudio_bl_flash.h: iaudio_bl_flash.bmp bmp2rb | 36 | iaudio_bl_flash.c iaudio_bl_flash.h: iaudio_bl_flash.bmp bmp2rb |
36 | $(SILENT)./bmp2rb -f 7 -h . $< >iaudio_bl_flash.c | 37 | $(SILENT)./bmp2rb -f 7 -h . $< >iaudio_bl_flash.c |
diff --git a/tools/rkw.c b/tools/rkw.c new file mode 100644 index 0000000000..db86b4f748 --- /dev/null +++ b/tools/rkw.c | |||
@@ -0,0 +1,166 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * | ||
9 | * Copyright (C) 2012 Marcin Bukat | ||
10 | * | ||
11 | * This program is free software; you can redistribute it and/or | ||
12 | * modify it under the terms of the GNU General Public License | ||
13 | * as published by the Free Software Foundation; either version 2 | ||
14 | * of the License, or (at your option) any later version. | ||
15 | * | ||
16 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
17 | * KIND, either express or implied. | ||
18 | * | ||
19 | ****************************************************************************/ | ||
20 | |||
21 | #include <stdio.h> | ||
22 | #include <stdlib.h> | ||
23 | #include <string.h> | ||
24 | #include <stdint.h> | ||
25 | |||
26 | #define RKLD_MAGIC 0x4c44524b | ||
27 | #define RKW_HEADER_SIZE 0x2c | ||
28 | |||
29 | /* slightly modified version from crc32.c in rockbox */ | ||
30 | static uint32_t rkw_crc32(const void *src, uint32_t len) | ||
31 | { | ||
32 | const unsigned char *buf = (const unsigned char *)src; | ||
33 | |||
34 | /* polynomial 0x04c10db7 */ | ||
35 | static const uint32_t crc32_lookup[16] = | ||
36 | { /* lookup table for 4 bits at a time is affordable */ | ||
37 | 0x00000000, 0x04C10DB7, 0x09821B6E, 0x0D4316D9, | ||
38 | 0x130436DC, 0x17C53B6B, 0x1A862DB2, 0x1E472005, | ||
39 | 0x26086DB8, 0x22C9600F, 0x2F8A76D6, 0x2B4B7B61, | ||
40 | 0x350C5B64, 0x31CD56D3, 0x3C8E400A, 0x384F4DBD | ||
41 | }; | ||
42 | |||
43 | uint32_t crc32 = 0; | ||
44 | unsigned char byte; | ||
45 | uint32_t t; | ||
46 | |||
47 | while (len--) | ||
48 | { | ||
49 | byte = *buf++; /* get one byte of data */ | ||
50 | |||
51 | /* upper nibble of our data */ | ||
52 | t = crc32 >> 28; /* extract the 4 most significant bits */ | ||
53 | t ^= byte >> 4; /* XOR in 4 bits of data into the extracted bits */ | ||
54 | crc32 <<= 4; /* shift the CRC register left 4 bits */ | ||
55 | crc32 ^= crc32_lookup[t]; /* do the table lookup and XOR the result */ | ||
56 | |||
57 | /* lower nibble of our data */ | ||
58 | t = crc32 >> 28; /* extract the 4 most significant bits */ | ||
59 | t ^= byte & 0x0F; /* XOR in 4 bits of data into the extracted bits */ | ||
60 | crc32 <<= 4; /* shift the CRC register left 4 bits */ | ||
61 | crc32 ^= crc32_lookup[t]; /* do the table lookup and XOR the result */ | ||
62 | } | ||
63 | |||
64 | return crc32; | ||
65 | } | ||
66 | |||
67 | static void int2le(unsigned int val, unsigned char* addr) | ||
68 | { | ||
69 | addr[0] = val & 0xFF; | ||
70 | addr[1] = (val >> 8) & 0xff; | ||
71 | addr[2] = (val >> 16) & 0xff; | ||
72 | addr[3] = (val >> 24) & 0xff; | ||
73 | } | ||
74 | |||
75 | int rkw_encode(char *iname, char *oname, unsigned long modelnum) | ||
76 | { | ||
77 | size_t len; | ||
78 | int length; | ||
79 | int rkwlength; | ||
80 | FILE *file; | ||
81 | uint32_t binary_crc, header_crc; | ||
82 | unsigned char *outbuf; | ||
83 | |||
84 | file = fopen(iname, "rb"); | ||
85 | if (!file) | ||
86 | { | ||
87 | perror(iname); | ||
88 | return -1; | ||
89 | } | ||
90 | |||
91 | fseek(file,0,SEEK_END); | ||
92 | length = ftell(file); | ||
93 | |||
94 | fseek(file,0,SEEK_SET); | ||
95 | |||
96 | /* length of the RKW header + binary length + 4 bytes of CRC */ | ||
97 | rkwlength = (length + RKW_HEADER_SIZE + 4); | ||
98 | |||
99 | outbuf = malloc(rkwlength); | ||
100 | |||
101 | if (!outbuf) | ||
102 | { | ||
103 | printf("out of memory!\n"); | ||
104 | fclose(file); | ||
105 | return -1; | ||
106 | } | ||
107 | |||
108 | /* Clear the buffer to zero */ | ||
109 | memset(outbuf, 0, rkwlength); | ||
110 | |||
111 | /* Build the RKW header */ | ||
112 | int2le(RKLD_MAGIC, outbuf); /* magic */ | ||
113 | int2le(RKW_HEADER_SIZE, outbuf+0x04); /* header size */ | ||
114 | int2le(0x60000000, outbuf+0x08); /* base address */ | ||
115 | int2le(0x60000000, outbuf+0x0c); /* load address */ | ||
116 | int2le(0x60000000+length, outbuf+0x10); /* end address */ | ||
117 | int2le(0x6035a5e4, outbuf+0x14); /* points to some unknown struct */ | ||
118 | int2le(modelnum, outbuf+0x18); /* reserved (we abuse the format | ||
119 | * to store modelnum here | ||
120 | */ | ||
121 | int2le(0, outbuf+0x1c); /* reserved */ | ||
122 | int2le(0x60000000, outbuf+0x20); /* entry point */ | ||
123 | int2le(0xe0000000, outbuf+0x24); /* flags */ | ||
124 | |||
125 | header_crc = rkw_crc32(outbuf, RKW_HEADER_SIZE - 4); | ||
126 | |||
127 | int2le(header_crc, outbuf+0x28); /* header CRC */ | ||
128 | |||
129 | /* Copy the binary */ | ||
130 | len = fread(outbuf + RKW_HEADER_SIZE, 1, length, file); | ||
131 | if(len < (size_t)length) | ||
132 | { | ||
133 | perror(iname); | ||
134 | free(outbuf); | ||
135 | fclose(file); | ||
136 | return -2; | ||
137 | } | ||
138 | fclose(file); | ||
139 | |||
140 | /* calc binary CRC and put at the end */ | ||
141 | binary_crc = rkw_crc32 (outbuf + RKW_HEADER_SIZE, length); | ||
142 | int2le(binary_crc, outbuf + rkwlength - 4); | ||
143 | |||
144 | file = fopen(oname, "wb"); | ||
145 | if (!file) | ||
146 | { | ||
147 | perror(oname); | ||
148 | free(outbuf); | ||
149 | return -3; | ||
150 | } | ||
151 | |||
152 | len = fwrite(outbuf, 1, rkwlength, file); | ||
153 | if(len < (size_t)length) | ||
154 | { | ||
155 | perror(oname); | ||
156 | fclose(file); | ||
157 | free(outbuf); | ||
158 | return -4; | ||
159 | } | ||
160 | |||
161 | fclose(file); | ||
162 | free(outbuf); | ||
163 | fprintf(stderr, "File encoded successfully\n" ); | ||
164 | |||
165 | return 0; | ||
166 | } | ||
diff --git a/tools/rkw.h b/tools/rkw.h new file mode 100644 index 0000000000..6ec77882b1 --- /dev/null +++ b/tools/rkw.h | |||
@@ -0,0 +1,26 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * | ||
9 | * Copyright (C) 2012 Marcin Bukat | ||
10 | * | ||
11 | * This program is free software; you can redistribute it and/or | ||
12 | * modify it under the terms of the GNU General Public License | ||
13 | * as published by the Free Software Foundation; either version 2 | ||
14 | * of the License, or (at your option) any later version. | ||
15 | * | ||
16 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
17 | * KIND, either express or implied. | ||
18 | * | ||
19 | ****************************************************************************/ | ||
20 | |||
21 | #ifndef _RKW_H | ||
22 | #define _RKW_H | ||
23 | |||
24 | int rkw_encode(char *iname, char *oname, unsigned long modelnum); | ||
25 | |||
26 | #endif | ||
diff --git a/tools/scramble.c b/tools/scramble.c index 7c7a847ea1..c3b200c01e 100644 --- a/tools/scramble.c +++ b/tools/scramble.c | |||
@@ -30,6 +30,7 @@ | |||
30 | #include "telechips.h" | 30 | #include "telechips.h" |
31 | #include "creative.h" | 31 | #include "creative.h" |
32 | #include "iaudio_bl_flash.h" | 32 | #include "iaudio_bl_flash.h" |
33 | #include "rkw.h" | ||
33 | 34 | ||
34 | static int iaudio_encode(char *iname, char *oname, char *idstring); | 35 | static int iaudio_encode(char *iname, char *oname, char *idstring); |
35 | static int ipod_encode(char *iname, char *oname, int fw_ver, bool fake_rsrc); | 36 | static int ipod_encode(char *iname, char *oname, int fw_ver, bool fake_rsrc); |
@@ -119,11 +120,12 @@ void usage(void) | |||
119 | "\t -type=XXXX where XXXX is a string indicating the \n" | 120 | "\t -type=XXXX where XXXX is a string indicating the \n" |
120 | "\t type of binary, eg. RBOS, RBBL\n" | 121 | "\t type of binary, eg. RBOS, RBBL\n" |
121 | "\t-tcc=X Telechips generic firmware format (X values: sum, crc)\n" | 122 | "\t-tcc=X Telechips generic firmware format (X values: sum, crc)\n" |
123 | "\t-rkw Rockchip RKW format\n" | ||
122 | "\t-add=X Rockbox generic \"add-up\" checksum format\n" | 124 | "\t-add=X Rockbox generic \"add-up\" checksum format\n" |
123 | "\t (X values: h100, h120, h140, h300, ipco, nano, ipvd, mn2g\n" | 125 | "\t (X values: h100, h120, h140, h300, ipco, nano, ipvd, mn2g\n" |
124 | "\t ip3g, ip4g, mini, iax5, iam5, iam3, h10, h10_5gb,\n" | 126 | "\t ip3g, ip4g, mini, iax5, iam5, iam3, h10, h10_5gb,\n"); |
125 | "\t tpj2, c200, e200, giga, gigs, m100, m500, d2,\n"); | 127 | printf("\t tpj2, c200, e200, giga, gigs, m100, m500, d2,\n" |
126 | printf("\t 9200, 1630, 6330, ldax, m200, c100, clip, e2v2,\n" | 128 | "\t 9200, 1630, 6330, ldax, m200, c100, clip, e2v2,\n" |
127 | "\t m2v4, fuze, c2v2, clv2, y820, y920, y925, x747,\n" | 129 | "\t m2v4, fuze, c2v2, clv2, y820, y920, y925, x747,\n" |
128 | "\t 747p, x777, nn2g, m244, cli+, fuz2, hd20, hd30,\n" | 130 | "\t 747p, x777, nn2g, m244, cli+, fuz2, hd20, hd30,\n" |
129 | "\t ip6g, rk27, clzp)\n"); | 131 | "\t ip6g, rk27, clzp)\n"); |
@@ -148,7 +150,7 @@ int main (int argc, char** argv) | |||
148 | unsigned long modelnum; | 150 | unsigned long modelnum; |
149 | char modelname[5]; | 151 | char modelname[5]; |
150 | int model_id; | 152 | int model_id; |
151 | enum { none, scramble, xor, tcc_sum, tcc_crc, add } method = scramble; | 153 | enum { none, scramble, xor, tcc_sum, tcc_crc, rkw, add } method = scramble; |
152 | bool creative_enable_ciff; | 154 | bool creative_enable_ciff; |
153 | 155 | ||
154 | model_id = ARCHOS_PLAYER; | 156 | model_id = ARCHOS_PLAYER; |
@@ -222,6 +224,24 @@ int main (int argc, char** argv) | |||
222 | return 2; | 224 | return 2; |
223 | } | 225 | } |
224 | } | 226 | } |
227 | else if(!strncmp(argv[1], "-rkw", 4)) { | ||
228 | iname = argv[3]; | ||
229 | oname = argv[4]; | ||
230 | modelnum = 0; | ||
231 | |||
232 | if(!strncmp(argv[2], "-modelnum=", 10)) { | ||
233 | modelnum = atoi(&argv[2][10]); | ||
234 | } | ||
235 | |||
236 | if (!modelnum) | ||
237 | { | ||
238 | modelnum = 73; /* rk27generic */ | ||
239 | fprintf(stderr, "modelnum not supplied." | ||
240 | " using default value for rk27generic target\n"); | ||
241 | } | ||
242 | |||
243 | return (rkw_encode(iname, oname, modelnum) != 0) ? -1 : 0; | ||
244 | } | ||
225 | else if(!strncmp(argv[1], "-add=", 5)) { | 245 | else if(!strncmp(argv[1], "-add=", 5)) { |
226 | iname = argv[2]; | 246 | iname = argv[2]; |
227 | oname = argv[3]; | 247 | oname = argv[3]; |
@@ -337,8 +357,6 @@ int main (int argc, char** argv) | |||
337 | modelnum = 71; | 357 | modelnum = 71; |
338 | else if (!strcmp(&argv[1][5], "fuz+")) /* Sansa Fuze+ */ | 358 | else if (!strcmp(&argv[1][5], "fuz+")) /* Sansa Fuze+ */ |
339 | modelnum = 72; | 359 | modelnum = 72; |
340 | else if (!strcmp(&argv[1][5], "rk27")) /* rockchip 27xx generic */ | ||
341 | modelnum = 73; | ||
342 | else if (!strcmp(&argv[1][5], "clzp")) /* Sansa Clip Zip */ | 360 | else if (!strcmp(&argv[1][5], "clzp")) /* Sansa Clip Zip */ |
343 | modelnum = 79; | 361 | modelnum = 79; |
344 | else if (!strcmp(&argv[1][5], "conn")) /* Sansa Connect */ | 362 | else if (!strcmp(&argv[1][5], "conn")) /* Sansa Connect */ |
diff --git a/tools/tools.make b/tools/tools.make index c143157dab..3350ad03bc 100644 --- a/tools/tools.make +++ b/tools/tools.make | |||
@@ -13,7 +13,9 @@ $(TOOLSDIR)/scramble: $(TOOLSDIR)/scramble.c $(TOOLSDIR)/iriver.c \ | |||
13 | $(TOOLSDIR)/mi4.c $(TOOLSDIR)/gigabeat.c \ | 13 | $(TOOLSDIR)/mi4.c $(TOOLSDIR)/gigabeat.c \ |
14 | $(TOOLSDIR)/gigabeats.c $(TOOLSDIR)/telechips.c \ | 14 | $(TOOLSDIR)/gigabeats.c $(TOOLSDIR)/telechips.c \ |
15 | $(TOOLSDIR)/iaudio_bl_flash.c \ | 15 | $(TOOLSDIR)/iaudio_bl_flash.c \ |
16 | $(TOOLSDIR)/creative.c $(TOOLSDIR)/hmac-sha1.c | 16 | $(TOOLSDIR)/creative.c $(TOOLSDIR)/hmac-sha1.c \ |
17 | $(TOOLSDIR)/rkw.c | ||
18 | |||
17 | $(TOOLSDIR)/rdf2binary: $(TOOLSDIR)/rdf2binary.c | 19 | $(TOOLSDIR)/rdf2binary: $(TOOLSDIR)/rdf2binary.c |
18 | $(TOOLSDIR)/convbdf: $(TOOLSDIR)/convbdf.c | 20 | $(TOOLSDIR)/convbdf: $(TOOLSDIR)/convbdf.c |
19 | $(TOOLSDIR)/codepages: $(TOOLSDIR)/codepages.c $(TOOLSDIR)/codepage_tables.c | 21 | $(TOOLSDIR)/codepages: $(TOOLSDIR)/codepages.c $(TOOLSDIR)/codepage_tables.c |