1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160
|
/*
gcc -Wall ttpci-firmware.c -o ttpci-firmware
*/
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <netinet/in.h>
#include <string.h>
/* crc stuff shamelessly stolen from linux-2.6.0/lib/crc32.c */
/*
* There are multiple 16-bit CRC polynomials in common use, but this is
* *the* standard CRC-32 polynomial, first popularized by Ethernet.
* x^32+x^26+x^23+x^22+x^16+x^12+x^11+x^10+x^8+x^7+x^5+x^4+x^2+x^1+x^0
*/
#define CRCPOLY_LE 0xedb88320
#define CRCPOLY_BE 0x04c11db7
uint32_t crc32_le(uint32_t crc, unsigned char const *p, size_t len)
{
int i;
while (len--) {
crc ^= *p++;
for (i = 0; i < 8; i++)
crc = (crc >> 1) ^ ((crc & 1) ? CRCPOLY_LE : 0);
}
return crc;
}
uint32_t crc32_be(uint32_t crc, unsigned char const *p, size_t len)
{
int i;
while (len--) {
crc ^= *p++ << 24;
for (i = 0; i < 8; i++)
crc = (crc << 1) ^ ((crc & 0x80000000) ? CRCPOLY_BE : 0);
}
return crc;
}
int convert(const char *filename, FILE * out)
{
uint32_t crc = 0, len = 0;
long size = 0;
unsigned char *mem = NULL;
FILE *f = NULL;
int ret = 0;
f = fopen(filename, "rb");
if (NULL == f) {
fprintf(stderr, "cannot open input file '%s'\n", filename);
ret = -1;
goto out;
}
fseek(f, 0, SEEK_END);
size = ftell(f);
fseek(f, 0, SEEK_SET);
if (0 == size) {
fprintf(stderr, "file size is 0\n");
ret = -1;
goto out;
}
mem = (unsigned char *) malloc(size);
if (NULL == mem) {
fprintf(stderr, "out of memory.\n");
ret = -1;
goto out;
}
if (1 != fread(mem, size, 1, f)) {
fprintf(stderr, "cannot read from input file.\n");
ret = -1;
goto out;
}
crc = crc32_le(0, mem, size);
crc = htonl(crc);
if (4 != fwrite((unsigned char *) &crc, 1, 4, out)) {
fprintf(stderr, "cannot write to output file #1.\n");
ret = -1;
goto out;
}
len = htonl(size);
if (4 != fwrite((unsigned char *) &len, 1, 4, out)) {
fprintf(stderr, "cannot write to output file #2.\n");
ret = -1;
goto out;
}
if (1 != fwrite(mem, size, 1, out)) {
fprintf(stderr, "cannot write to output file #3.\n");
ret = -1;
goto out;
}
fprintf(stderr, "file: '%s', crc32: 0x%08x, size:%ld\n", filename, ntohl(crc), size);
ret = 0;
out:
if (NULL != mem)
free(mem);
if (NULL != f)
fclose(f);
return ret;
}
int main(int argc, char *argv[])
{
char fn[256];
FILE *f = NULL;
const char *magic = "AVFW";
if (argc < 4) {
fprintf(stderr, "usage: %s dpram root version [output]\n", argv[0]);
return 1;
}
if (argc >= 4) {
snprintf(fn, 255, "dvb-ttpci-%s.fw",argv[3]);
} else {
snprintf(fn, 255, "dvb-ttpci-unknown.fw");
}
f = fopen(fn, "wb+");
if (NULL == f) {
fprintf(stderr, "cannot open output file '%s'\n", fn);
return -1;
}
if (4 != fwrite(magic, 1, 4, f)) {
fprintf(stderr, "cannot write magic bytes to output file.\n");
fclose(f);
return -1;
}
if (0 != convert(argv[1], f)) {
fprintf(stderr, "cannot write dpram stuff output file.\n");
fclose(f);
return -1;
}
if (0 != convert(argv[2], f)) {
fprintf(stderr, "cannot write root stuff output file.\n");
fclose(f);
return -1;
}
fclose(f);
fprintf(stderr, "ok, firmware written to '%s'\n",fn);
return 0;
}
|