2 lzma2eva - convert lzma-compressed file to AVM EVA bootloader format
3 Copyright (C) 2007 Enrik Berkhan <Enrik.Berkhan@inka.de>
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
23 #include <zlib.h> /* crc32 */
26 #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
28 #define checksum_add32(csum, data) \
30 csum += (((data) >> 0) & 0x000000FF); \
31 csum += (((data) >> 8) & 0x000000FF); \
32 csum += (((data) >> 16) & 0x000000FF); \
33 csum += (((data) >> 24) & 0x000000FF); \
39 fprintf(stderr
, "usage: lzma2eva <loadadddr> <entry> <lzmafile> <evafile>\n");
44 pexit(const char *msg
)
50 /* Read an 8bit value */
51 static int fread_8(uint8_t *buf
, FILE *fd
)
53 return (fread(buf
, sizeof(*buf
), 1, fd
) == 1) ? 0 : -1;
56 /* Read a 32bit little endian value and convert to host endianness. */
57 static int fread_le32(uint32_t *buf
, FILE *fd
)
63 if (fread(tmp
, sizeof(tmp
), 1, fd
) != 1)
66 for (i
= 0; i
< ARRAY_SIZE(tmp
); i
++)
67 *buf
|= (uint32_t)(tmp
[i
]) << (i
* 8);
72 /* Read a 64bit little endian value and convert to host endianness. */
73 static int fread_le64(uint64_t *buf
, FILE *fd
)
79 if (fread(tmp
, sizeof(tmp
), 1, fd
) != 1)
82 for (i
= 0; i
< ARRAY_SIZE(tmp
); i
++)
83 *buf
|= (uint64_t)(tmp
[i
]) << (i
* 8);
88 /* Write an 8bit value */
89 static int fwrite_8(uint8_t buf
, FILE *fd
)
91 return (fwrite(&buf
, sizeof(buf
), 1, fd
) == 1) ? 0 : -1;
94 /* Convert to little endian and write a 32bit value */
95 static int fwrite_le32(uint32_t buf
, FILE *fd
)
101 for (i
= 0; i
< ARRAY_SIZE(tmp
); i
++)
102 tmp
[i
] = buf
>> (i
* 8);
103 if (fwrite(tmp
, sizeof(tmp
), 1, fd
) != 1)
110 main(int argc
, char *argv
[])
112 const char *infile
, *outfile
;
114 static const uint8_t buf
[4096];
121 uint32_t magic
= 0xfeed1281L
;
122 uint32_t reclength
= 0;
124 uint32_t loadaddress
= 0;
125 uint32_t type
= 0x075a0201L
; /* might be 7Z 2.1? */
126 uint32_t checksum
= 0;
128 uint32_t compsize
= 0;
130 uint32_t datasize32
= 0;
131 uint32_t datacrc32
= crc32(0, 0, 0);
138 /* "parse" command line */
139 loadaddress
= strtoul(argv
[1], 0, 0);
140 entry
= strtoul(argv
[2], 0, 0);
144 in
= fopen(infile
, "rb");
147 out
= fopen(outfile
, "w+b");
151 /* read LZMA header */
152 if (fread_8(&properties
, in
))
154 if (fread_le32(&dictsize
, in
))
156 if (fread_le64(&datasize
, in
))
159 /* write EVA header */
160 if (fwrite_le32(magic
, out
))
162 if (fgetpos(out
, &reclengthpos
))
164 if (fwrite_le32(reclength
, out
))
166 if (fwrite_le32(loadaddress
, out
))
168 if (fwrite_le32(type
, out
))
171 /* write EVA LZMA header */
172 if (fgetpos(out
, &compsizepos
))
174 if (fwrite_le32(compsize
, out
))
176 /* XXX check length */
177 datasize32
= (uint32_t)datasize
;
178 if (fwrite_le32(datasize32
, out
))
180 if (fwrite_le32(datacrc32
, out
))
183 /* write modified LZMA header */
184 if (fwrite_8(properties
, out
))
186 if (fwrite_le32(dictsize
, out
))
188 if (fwrite_le32(0, out
))
191 /* copy compressed data, calculate crc32 */
192 while (0 < (elems
= fread(&buf
, sizeof buf
[0], sizeof buf
, in
))) {
194 if (elems
!= fwrite(&buf
, sizeof buf
[0], elems
, out
))
196 datacrc32
= crc32(datacrc32
, buf
, elems
);
202 /* re-write record length */
203 reclength
= compsize
+ 24;
204 if (fsetpos(out
, &reclengthpos
))
206 if (fwrite_le32(reclength
, out
))
209 /* re-write EVA LZMA header including size and data crc */
210 if (fsetpos(out
, &compsizepos
))
212 if (fwrite_le32(compsize
, out
))
214 if (fwrite_le32(datasize32
, out
))
216 if (fwrite_le32(datacrc32
, out
))
219 /* calculate record checksum */
220 checksum
+= reclength
;
221 checksum
+= loadaddress
;
222 checksum_add32(checksum
, type
);
223 checksum_add32(checksum
, compsize
);
224 checksum_add32(checksum
, datasize32
);
225 checksum_add32(checksum
, datacrc32
);
226 if (fseek(out
, 0, SEEK_CUR
))
228 while (0 < (elems
= fread(&buf
, sizeof buf
[0], sizeof buf
, out
))) {
230 for (i
= 0; i
< elems
; ++i
)
235 if (fseek(out
, 0, SEEK_CUR
))
238 checksum
= ~checksum
+ 1;
239 if (fwrite_le32(checksum
, out
))
242 /* write entry record */
243 if (fwrite_le32(0, out
))
245 if (fwrite_le32(entry
, out
))
This page took 0.057399 seconds and 5 git commands to generate.