/* * Linksys e8350 v1 firmware header generator */ #include #include #include #include #include #include #include #include #include #include #include #include "cyg_crc.h" #define AC2350 20 #define CYBERTAN_VERSION "v1.0.03" #define SERIAL_NUMBER "003" #define MINOR_VERSION "" #define BUILD_KEYWORD " B" #define BUILD_NUMBER SERIAL_NUMBER #define BETA_VERSION " " #define CYBERTAN_UBOOT_VERSION "v1.0" /* add for AC2350 F/W header */ #define FWHDR_MAGIC_STR "CHDR" #define FWHDR_MAGIC 0X52444843 struct cbt_fw_header { unsigned int magic; /* "CHDR" */ unsigned int len; /* Length of file including header */ unsigned int crc32; /* 32-bit CRC */ unsigned int res; }; #define MAX_BUF 1024 /* Initial CRC32 checksum value */ #define CRC32_INIT_VALUE 0xffffffff int fd, fd_w; void die(const char * str, ...) { va_list args; va_start(args, str); vfprintf(stderr, str, args); fputc('\n', stderr); exit(1); } int fill_null0(int size) { unsigned char buf[1]; int i; fprintf(stderr,"Fill null\n"); buf[0] = 0xff; for (i = 0 ; i < size; i++) if (write(fd_w, buf, 1) != 1) return 0; return 1; } long file_open(const char *name) { struct stat sb; if ((fd = open(name, O_RDONLY, 0)) < 0) die("Unable to open `%s' : %m", name); if (fstat (fd, &sb)) die("Unable to stat `%s' : %m", name); return sb.st_size; } void usage(void) { die("Usage: addfwhdr [-i|--input] sysupgrade.o [-o|--output] code.bin\n"); } int main(int argc, char ** argv) { char *input_file = NULL, *output_file = NULL; extern int optind, opterr, optopt; unsigned int input_size,c; int option_index = 0; extern char *optarg; char *buf = NULL; int garbage = 0; int opt; struct cbt_fw_header *fwhdr; unsigned int crc; static struct option long_options[] = { {"input", 1, 0, 'i'}, {"output", 1, 0, 'o'}, {"garbage", 0, 0, 'g'}, {0, 0, 0, 0} }; while(true) { opt = getopt_long(argc, argv, "i:o:g",long_options, &option_index); if (opt == -1) break; switch(opt){ case 'h' : usage(); break; case 'i' : input_file = optarg; printf("input file is [%s]\n", input_file); break; case 'o' : output_file = optarg; printf("output file is [%s]\n", output_file); break; case 'g' : garbage = 1; break; default : usage(); } } if (!input_file || !output_file) { printf("You must specify the input and output file!\n"); usage(); } unlink(output_file); if ((fd_w = open(output_file, O_RDWR|O_CREAT, S_IREAD | S_IWRITE)) < 0) die("Unable to open `%s' : %m", output_file); printf("\n---------- add fw header --------\n"); fwhdr = calloc(1, sizeof(struct cbt_fw_header)); memcpy((char *)&fwhdr->magic, FWHDR_MAGIC_STR, sizeof(fwhdr->magic)); input_size = file_open(input_file); if (!(buf = malloc(input_size))){ perror("malloc"); goto fail; } c = read(fd, buf, input_size); fwhdr->len = input_size + sizeof(struct cbt_fw_header); fwhdr->res = fwhdr->res | 0x1; crc = cyg_crc32_accumulate(CRC32_INIT_VALUE, (uint8_t *)&fwhdr->res, 4); crc = cyg_crc32_accumulate(crc, (uint8_t *)&buf[0], input_size); fwhdr->crc32 = crc; /* write code pattern header */ write(fd_w, fwhdr, sizeof(struct cbt_fw_header)); if (write(fd_w, buf, c) != c) die("Write call failed!\n"); fail: free(fwhdr); if (buf) free(buf); close(fd); close(fd_w); return 0; }