1 // SPDX-License-Identifier: GPL-2.0-or-later 2 /* 3 lzma2eva - convert lzma-compressed file to AVM EVA bootloader format 4 Copyright (C) 2007 Enrik Berkhan <Enrik.Berkhan@inka.de> 5 */ 6 7 #include <stdint.h> 8 #include <stdio.h> 9 #include <stdlib.h> 10 #include <zlib.h> /* crc32 */ 11 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]; 17 18 void 19 usage(void) 20 { 21 fprintf(stderr, "usage: lzma2eva <loadadddr> <entry> <lzmafile> <evafile>\n"); 22 exit(1); 23 } 24 25 void 26 pexit(const char *msg) 27 { 28 perror(msg); 29 exit(1); 30 } 31 32 int 33 main(int argc, char *argv[]) 34 { 35 36 const char *infile, *outfile; 37 FILE *in, *out; 38 static uint8_t buf[4096]; 39 size_t elems; 40 41 uint8_t properties; 42 uint32_t dictsize; 43 uint64_t datasize; 44 45 uint32_t magic = 0xfeed1281L; 46 uint32_t reclength = 0; 47 fpos_t reclengthpos; 48 uint32_t loadaddress = 0; 49 uint32_t type = 0x075a0201L; /* might be 7Z 2.1? */ 50 uint32_t checksum = 0; 51 52 uint32_t compsize = 0; 53 fpos_t compsizepos; 54 uint32_t datasize32 = 0; 55 uint32_t datacrc32 = crc32(0, 0, 0); 56 57 uint32_t zero = 0; 58 uint32_t entry = 0; 59 60 if (argc != 5) 61 usage(); 62 63 /* "parse" command line */ 64 loadaddress = strtoul(argv[1], 0, 0); 65 entry = strtoul(argv[2], 0, 0); 66 infile = argv[3]; 67 outfile = argv[4]; 68 69 in = fopen(infile, "rb"); 70 if (!in) 71 pexit("fopen"); 72 out = fopen(outfile, "w+b"); 73 if (!out) 74 pexit("fopen"); 75 76 /* read LZMA header */ 77 if (1 != fread(&properties, sizeof properties, 1, in)) 78 pexit("fread"); 79 if (1 != fread(&dictsize, sizeof dictsize, 1, in)) 80 pexit("fread"); 81 if (1 != fread(&datasize, sizeof datasize, 1, in)) 82 pexit("fread"); 83 84 /* write EVA header */ 85 if (1 != fwrite(&magic, sizeof magic, 1, out)) 86 pexit("fwrite"); 87 if (fgetpos(out, &reclengthpos)) 88 pexit("fgetpos"); 89 if (1 != fwrite(&reclength, sizeof reclength, 1, out)) 90 pexit("fwrite"); 91 if (1 != fwrite(&loadaddress, sizeof loadaddress, 1, out)) 92 pexit("fwrite"); 93 if (1 != fwrite(&type, sizeof type, 1, out)) 94 pexit("fwrite"); 95 96 /* write EVA LZMA header */ 97 if (fgetpos(out, &compsizepos)) 98 pexit("fgetpos"); 99 if (1 != fwrite(&compsize, sizeof compsize, 1, out)) 100 pexit("fwrite"); 101 /* XXX check length */ 102 datasize32 = (uint32_t)datasize; 103 if (1 != fwrite(&datasize32, sizeof datasize32, 1, out)) 104 pexit("fwrite"); 105 if (1 != fwrite(&datacrc32, sizeof datacrc32, 1, out)) 106 pexit("fwrite"); 107 108 /* write modified LZMA header */ 109 if (1 != fwrite(&properties, sizeof properties, 1, out)) 110 pexit("fwrite"); 111 if (1 != fwrite(&dictsize, sizeof dictsize, 1, out)) 112 pexit("fwrite"); 113 if (1 != fwrite(&zero, 3, 1, out)) 114 pexit("fwrite"); 115 116 /* copy compressed data, calculate crc32 */ 117 while (0 < (elems = fread(&buf, sizeof buf[0], sizeof buf, in))) { 118 compsize += elems; 119 if (elems != fwrite(&buf, sizeof buf[0], elems, out)) 120 pexit("fwrite"); 121 datacrc32 = crc32(datacrc32, buf, elems); 122 } 123 if (ferror(in)) 124 pexit("fread"); 125 fclose(in); 126 127 /* re-write record length */ 128 reclength = compsize + 24; 129 if (fsetpos(out, &reclengthpos)) 130 pexit("fsetpos"); 131 if (1 != fwrite(&reclength, sizeof reclength, 1, out)) 132 pexit("fwrite"); 133 134 /* re-write EVA LZMA header including size and data crc */ 135 if (fsetpos(out, &compsizepos)) 136 pexit("fsetpos"); 137 if (1 != fwrite(&compsize, sizeof compsize, 1, out)) 138 pexit("fwrite"); 139 if (1 != fwrite(&datasize32, sizeof datasize32, 1, out)) 140 pexit("fwrite"); 141 if (1 != fwrite(&datacrc32, sizeof datacrc32, 1, out)) 142 pexit("fwrite"); 143 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)) 152 pexit("fseek"); 153 while (0 < (elems = fread(&buf, sizeof buf[0], sizeof buf, out))) { 154 size_t i; 155 for (i = 0; i < elems; ++i) 156 checksum += buf[i]; 157 } 158 if (ferror(out)) 159 pexit("fread"); 160 if (fseek(out, 0, SEEK_CUR)) 161 pexit("fseek"); 162 163 checksum = ~checksum + 1; 164 if (1 != fwrite(&checksum, sizeof checksum, 1, out)) 165 pexit("fwrite"); 166 167 /* write entry record */ 168 if (1 != fwrite(&zero, sizeof zero, 1, out)) 169 pexit("fwrite"); 170 if (1 != fwrite(&entry, sizeof entry, 1, out)) 171 pexit("fwrite"); 172 173 if (fclose(out)) 174 pexit("fclose"); 175 176 return 0; 177 } 178
This page was automatically generated by LXR 0.3.1. • OpenWrt