1 // SPDX-License-Identifier: GPL-2.0-or-later
3 lzma2eva - convert lzma-compressed file to AVM EVA bootloader format
4 Copyright (C) 2007 Enrik Berkhan <Enrik.Berkhan@inka.de>
10 #include <zlib.h> /* crc32 */
12 #define checksum_add32(csum, data) \
13 csum += ((uint8_t *)&data)[0]; \
14 csum += ((uint8_t *)&data)[1]; \
15 csum += ((uint8_t *)&data)[2]; \
16 csum += ((uint8_t *)&data)[3];
21 fprintf(stderr
, "usage: lzma2eva <loadadddr> <entry> <lzmafile> <evafile>\n");
26 pexit(const char *msg
)
33 main(int argc
, char *argv
[])
36 const char *infile
, *outfile
;
38 static uint8_t buf
[4096];
45 uint32_t magic
= 0xfeed1281L
;
46 uint32_t reclength
= 0;
48 uint32_t loadaddress
= 0;
49 uint32_t type
= 0x075a0201L
; /* might be 7Z 2.1? */
50 uint32_t checksum
= 0;
52 uint32_t compsize
= 0;
54 uint32_t datasize32
= 0;
55 uint32_t datacrc32
= crc32(0, 0, 0);
63 /* "parse" command line */
64 loadaddress
= strtoul(argv
[1], 0, 0);
65 entry
= strtoul(argv
[2], 0, 0);
69 in
= fopen(infile
, "rb");
72 out
= fopen(outfile
, "w+b");
76 /* read LZMA header */
77 if (1 != fread(&properties
, sizeof properties
, 1, in
))
79 if (1 != fread(&dictsize
, sizeof dictsize
, 1, in
))
81 if (1 != fread(&datasize
, sizeof datasize
, 1, in
))
84 /* write EVA header */
85 if (1 != fwrite(&magic
, sizeof magic
, 1, out
))
87 if (fgetpos(out
, &reclengthpos
))
89 if (1 != fwrite(&reclength
, sizeof reclength
, 1, out
))
91 if (1 != fwrite(&loadaddress
, sizeof loadaddress
, 1, out
))
93 if (1 != fwrite(&type
, sizeof type
, 1, out
))
96 /* write EVA LZMA header */
97 if (fgetpos(out
, &compsizepos
))
99 if (1 != fwrite(&compsize
, sizeof compsize
, 1, out
))
101 /* XXX check length */
102 datasize32
= (uint32_t)datasize
;
103 if (1 != fwrite(&datasize32
, sizeof datasize32
, 1, out
))
105 if (1 != fwrite(&datacrc32
, sizeof datacrc32
, 1, out
))
108 /* write modified LZMA header */
109 if (1 != fwrite(&properties
, sizeof properties
, 1, out
))
111 if (1 != fwrite(&dictsize
, sizeof dictsize
, 1, out
))
113 if (1 != fwrite(&zero
, 3, 1, out
))
116 /* copy compressed data, calculate crc32 */
117 while (0 < (elems
= fread(&buf
, sizeof buf
[0], sizeof buf
, in
))) {
119 if (elems
!= fwrite(&buf
, sizeof buf
[0], elems
, out
))
121 datacrc32
= crc32(datacrc32
, buf
, elems
);
127 /* re-write record length */
128 reclength
= compsize
+ 24;
129 if (fsetpos(out
, &reclengthpos
))
131 if (1 != fwrite(&reclength
, sizeof reclength
, 1, out
))
134 /* re-write EVA LZMA header including size and data crc */
135 if (fsetpos(out
, &compsizepos
))
137 if (1 != fwrite(&compsize
, sizeof compsize
, 1, out
))
139 if (1 != fwrite(&datasize32
, sizeof datasize32
, 1, out
))
141 if (1 != fwrite(&datacrc32
, sizeof datacrc32
, 1, out
))
144 /* calculate record checksum */
145 checksum
+= reclength
;
146 checksum
+= loadaddress
;
147 checksum_add32(checksum
, type
);
148 checksum_add32(checksum
, compsize
);
149 checksum_add32(checksum
, datasize32
);
150 checksum_add32(checksum
, datacrc32
);
151 if (fseek(out
, 0, SEEK_CUR
))
153 while (0 < (elems
= fread(&buf
, sizeof buf
[0], sizeof buf
, out
))) {
155 for (i
= 0; i
< elems
; ++i
)
160 if (fseek(out
, 0, SEEK_CUR
))
163 checksum
= ~checksum
+ 1;
164 if (1 != fwrite(&checksum
, sizeof checksum
, 1, out
))
167 /* write entry record */
168 if (1 != fwrite(&zero
, sizeof zero
, 1, out
))
170 if (1 != fwrite(&entry
, sizeof entry
, 1, out
))