#include <sys/types.h>
#include <sys/mman.h>
#include <sys/param.h>
#include <sys/stat.h>
#include <err.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
const uint8_t decoder_magic[] = {
0xa7, 0x03, 0x00, 0x00, 0x66, 0xbb, 0x55, 0xaa
};
const uint8_t encoder_magic[] = {
0xa7, 0x0d, 0x00, 0x00, 0x66, 0xbb, 0x55, 0xaa
};
static int
save_firmware(const char *name, const uint8_t *buf, size_t nbytes)
{
FILE *ofp;
char outfile[MAXPATHLEN];
size_t i;
if (nbytes > (256 * 1024))
nbytes = 256 * 1024;
if ((size_t)snprintf(outfile, sizeof(outfile), "%s.c", name) >=
sizeof(outfile))
errx(1, "save_firmware -- firmware name is too long");
if (!(ofp = fopen(outfile, "w")))
err(1, "save_firmware -- can't open output file <%s>",
outfile);
fprintf(ofp, "#include <sys/types.h>\n"
"\n"
"const uint8_t %s[] __attribute__ ((aligned(4))) = {",
name);
for (i = 0; i < nbytes; i++) {
if (i)
fputc(',', ofp);
if ((i % 8) == 0)
fputs("\n\t", ofp);
else
fputc(' ', ofp);
fprintf(ofp, "0x%.2x", buf[i]);
}
fprintf(ofp, "\n};\n");
if (ferror(ofp)) {
fclose(ofp);
return -1;
}
fclose(ofp);
return 0;
}
int
main(int argc, char **argv)
{
uint8_t *end;
uint8_t *ptr;
uint8_t *start;
int decoder_fw_saved = 0;
int encoder_fw_saved = 0;
int fd, i;
struct stat statbuf;
if (argc != 2) {
fprintf(stderr, "usage: cxm_extract_fw file\n");
exit(1);
}
for (i = 1; i <= (argc - 1); i++) {
if ((fd = open(argv[i], O_RDONLY)) < 0)
err(1, "can't open %s for reading", argv[i]);
if (fstat(fd, &statbuf) < 0) {
close(fd);
err(1, "can't fstat %s", argv[i]);
}
if (!(start = (uint8_t *)mmap(NULL, (size_t) statbuf.st_size,
PROT_READ, MAP_SHARED, fd, (off_t) 0))) {
close(fd);
err(1, "can't mmap %s", argv[i]);
}
end = start + statbuf.st_size;
close(fd);
if (statbuf.st_size > 100000) {
for (ptr = start; ptr != end; ptr++) {
if ((size_t)(end - ptr) >= sizeof(decoder_magic) &&
memcmp(ptr, decoder_magic, sizeof(decoder_magic)) == 0) {
if (!decoder_fw_saved) {
if (save_firmware("cxm_dec_fw", ptr, end - ptr) < 0)
errx(1, "save_firmware failed");
decoder_fw_saved = 1;
} else {
errx(1, "multiple decoder images present");
}
}
if ((size_t)(end - ptr) >= sizeof(encoder_magic) &&
memcmp(ptr, encoder_magic, sizeof(encoder_magic)) == 0) {
if (!encoder_fw_saved) {
if (save_firmware("cxm_enc_fw", ptr, end - ptr) < 0)
errx(1, "save_firmware failed");
encoder_fw_saved = 1;
} else {
errx(1, "multiple encoder images present");
}
}
}
} else {
errx(1, "save_firmware failed");
}
munmap((caddr_t)start, (size_t)statbuf.st_size);
if (!decoder_fw_saved)
errx(1, "decoder image not present");
if (!encoder_fw_saved)
errx(1, "encoder image not present");
if (!decoder_fw_saved || !encoder_fw_saved)
exit(1);
}
exit(0);
}