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 */
25 #define checksum_add32(csum, data) \
26 csum += ((uint8_t *)&data)[0]; \
27 csum += ((uint8_t *)&data)[1]; \
28 csum += ((uint8_t *)&data)[2]; \
29 csum += ((uint8_t *)&data)[3];
34 fprintf(stderr
, "usage: lzma2eva <loadadddr> <entry> <lzmafile> <evafile>\n");
39 pexit(const char *msg
)
46 main(int argc
, char *argv
[])
49 const char *infile
, *outfile
;
51 static const uint8_t buf
[4096];
58 uint32_t magic
= 0xfeed1281L
;
59 uint32_t reclength
= 0;
61 uint32_t loadaddress
= 0;
62 uint32_t type
= 0x075a0201L
; /* might be 7Z 2.1? */
63 uint32_t checksum
= 0;
65 uint32_t compsize
= 0;
67 uint32_t datasize32
= 0;
68 uint32_t datacrc32
= crc32(0, 0, 0);
76 /* "parse" command line */
77 loadaddress
= strtoul(argv
[1], 0, 0);
78 entry
= strtoul(argv
[2], 0, 0);
82 in
= fopen(infile
, "rb");
85 out
= fopen(outfile
, "w+b");
89 /* read LZMA header */
90 if (1 != fread(&properties
, sizeof properties
, 1, in
))
92 if (1 != fread(&dictsize
, sizeof dictsize
, 1, in
))
94 if (1 != fread(&datasize
, sizeof datasize
, 1, in
))
97 /* write EVA header */
98 if (1 != fwrite(&magic
, sizeof magic
, 1, out
))
100 if (fgetpos(out
, &reclengthpos
))
102 if (1 != fwrite(&reclength
, sizeof reclength
, 1, out
))
104 if (1 != fwrite(&loadaddress
, sizeof loadaddress
, 1, out
))
106 if (1 != fwrite(&type
, sizeof type
, 1, out
))
109 /* write EVA LZMA header */
110 if (fgetpos(out
, &compsizepos
))
112 if (1 != fwrite(&compsize
, sizeof compsize
, 1, out
))
114 /* XXX check length */
115 datasize32
= (uint32_t)datasize
;
116 if (1 != fwrite(&datasize32
, sizeof datasize32
, 1, out
))
118 if (1 != fwrite(&datacrc32
, sizeof datacrc32
, 1, out
))
121 /* write modified LZMA header */
122 if (1 != fwrite(&properties
, sizeof properties
, 1, out
))
124 if (1 != fwrite(&dictsize
, sizeof dictsize
, 1, out
))
126 if (1 != fwrite(&zero
, 3, 1, out
))
129 /* copy compressed data, calculate crc32 */
130 while (0 < (elems
= fread(&buf
, sizeof buf
[0], sizeof buf
, in
))) {
132 if (elems
!= fwrite(&buf
, sizeof buf
[0], elems
, out
))
134 datacrc32
= crc32(datacrc32
, buf
, elems
);
140 /* re-write record length */
141 reclength
= compsize
+ 24;
142 if (fsetpos(out
, &reclengthpos
))
144 if (1 != fwrite(&reclength
, sizeof reclength
, 1, out
))
147 /* re-write EVA LZMA header including size and data crc */
148 if (fsetpos(out
, &compsizepos
))
150 if (1 != fwrite(&compsize
, sizeof compsize
, 1, out
))
152 if (1 != fwrite(&datasize32
, sizeof datasize32
, 1, out
))
154 if (1 != fwrite(&datacrc32
, sizeof datacrc32
, 1, out
))
157 /* calculate record checksum */
158 checksum
+= reclength
;
159 checksum
+= loadaddress
;
160 checksum_add32(checksum
, type
);
161 checksum_add32(checksum
, compsize
);
162 checksum_add32(checksum
, datasize32
);
163 checksum_add32(checksum
, datacrc32
);
164 if (fseek(out
, 0, SEEK_CUR
))
166 while (0 < (elems
= fread(&buf
, sizeof buf
[0], sizeof buf
, out
))) {
168 for (i
= 0; i
< elems
; ++i
)
173 if (fseek(out
, 0, SEEK_CUR
))
176 checksum
= ~checksum
+ 1;
177 if (1 != fwrite(&checksum
, sizeof checksum
, 1, out
))
180 /* write entry record */
181 if (1 != fwrite(&zero
, sizeof zero
, 1, out
))
183 if (1 != fwrite(&entry
, sizeof entry
, 1, out
))
This page took 0.051152 seconds and 5 git commands to generate.