kbc1126_ec_dump.c
1 /* SPDX-License-Identifier: GPL-2.0-only */ 2 3 #include <assert.h> 4 #include <stdio.h> 5 #include <stdlib.h> 6 #include <string.h> 7 8 static void usage(const char *s) 9 { 10 printf("%s <rom file>\n", s); 11 exit(1); 12 } 13 14 static void FseekEnd(FILE *fp, long o) 15 { 16 if (fseek(fp, o, SEEK_END) != 0) { 17 puts("fseek() error!\n"); 18 exit(1); 19 } 20 } 21 22 void dump_fw(FILE *dst, FILE *src, long offset) 23 { 24 static unsigned char buf[65536]; 25 26 if (offset > 0) 27 offset -= 0x1000000; 28 29 printf("Dumping firmware at -0x%lx...", -offset); 30 31 FseekEnd(src, offset); 32 unsigned short len; 33 unsigned short cksum; 34 unsigned short _cksum = 0; 35 fread(&len, 2, 1, src); 36 fread(&cksum, 2, 1, src); 37 fread(buf, len, 1, src); 38 39 for (size_t i = 0; i < len; i++) 40 _cksum += buf[i]; 41 42 if (_cksum == cksum) { 43 puts("checksum ok"); 44 } else { 45 puts("checksum fail"); 46 exit(1); 47 } 48 49 fwrite(&len, 2, 1, dst); 50 fwrite(&cksum, 2, 1, dst); 51 fwrite(buf, len, 1, dst); 52 } 53 54 int main(int argc, char *argv[]) 55 { 56 if (argc != 2) 57 usage(argv[0]); 58 59 FILE *fp = fopen(argv[1], "rb"); 60 61 if (fp == NULL) { 62 puts("Error opening file!"); 63 exit(1); 64 } 65 66 char *basename = strrchr(argv[1], '/'); 67 if (basename == NULL) 68 basename = argv[1]; 69 else 70 basename = basename + 1; 71 72 int len = strlen(basename); 73 char fn1[len + 5], fn2[len + 5]; 74 strcpy(fn1, basename); 75 strcpy(fn2, basename); 76 strcat(fn1, ".fw1"); 77 strcat(fn2, ".fw2"); 78 79 FILE *fw1 = fopen(fn1, "wb"); 80 FILE *fw2 = fopen(fn2, "wb"); 81 82 long romsz; 83 FseekEnd(fp, -1); 84 romsz = ftell(fp) + 1; 85 printf("size of %s: 0x%lx\n", argv[1], romsz); 86 87 if (romsz & 0xff) { 88 puts("The ROM size must be multiple of 0x100"); 89 exit(1); 90 } 91 92 /* read offset of fw1 and fw2 */ 93 unsigned char offs[8]; 94 FseekEnd(fp, -0x100); 95 fread(offs, 8, 1, fp); 96 97 assert(offs[0] + offs[2] == 0xff); 98 assert(offs[1] + offs[3] == 0xff); 99 assert(offs[4] + offs[6] == 0xff); 100 assert(offs[5] + offs[7] == 0xff); 101 long offw1 = (offs[0] << 16) | (offs[1] << 8); 102 long offw2 = (offs[4] << 16) | (offs[5] << 8); 103 104 dump_fw(fw1, fp, offw1); 105 dump_fw(fw2, fp, offw2); 106 107 fclose(fp); 108 fclose(fw1); 109 fclose(fw2); 110 return 0; 111 }