/ util / kbc1126 / kbc1126_ec_dump.c
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  }