Iru Cai has uploaded a new change for review. ( https://review.coreboot.org/19071 )
Change subject: util: Add tools for dumping and inserting KBC1126 firmware images. ......................................................................
util: Add tools for dumping and inserting KBC1126 firmware images.
Change-Id: Ic521b177b9602ff042312cccaaa89371db7c5855 Signed-off-by: Iru Cai mytbk920423@gmail.com --- M .gitignore A util/kbc1126/kbc1126_ec_dump.c A util/kbc1126/kbc1126_ec_insert.c A util/kbc1126/makefile 4 files changed, 218 insertions(+), 0 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/71/19071/1
diff --git a/.gitignore b/.gitignore index 2ecbb51..ed642a3 100644 --- a/.gitignore +++ b/.gitignore @@ -115,6 +115,8 @@ util/vgabios/testbios util/viatool/viatool util/autoport/autoport +util/kbc1126/kbc1126_ec_dump +util/kbc1126/kbc1126_ec_insert
documentation/*.aux documentation/*.idx diff --git a/util/kbc1126/kbc1126_ec_dump.c b/util/kbc1126/kbc1126_ec_dump.c new file mode 100644 index 0000000..ca797bf --- /dev/null +++ b/util/kbc1126/kbc1126_ec_dump.c @@ -0,0 +1,110 @@ +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <assert.h> + +static void usage(const char *s) +{ + printf("%s <rom file>\n", s); + exit(1); +} + +static void FseekEnd(FILE *fp, long o) +{ + if (fseek(fp, o, SEEK_END)!=0) { + puts("fseek() error!\n"); + exit(1); + } +} + +void dump_fw(FILE *dst, FILE *src, long offset) +{ + static unsigned char buf[65536]; + + if (offset>0) + offset -= 0x1000000; + + printf("Dumping firmware at -0x%lx...", -offset); + + FseekEnd(src, offset); + unsigned short len; + unsigned short cksum; + unsigned short _cksum=0; + fread(&len, 2, 1, src); + fread(&cksum, 2, 1, src); + fread(buf, len, 1, src); + + for (size_t i=0; i<len; i++) { + _cksum += buf[i]; + } + if (_cksum==cksum) { + puts("checksum ok"); + } else { + puts("checksum fail"); + exit(1); + } + + fwrite(&len, 2, 1, dst); + fwrite(&cksum, 2, 1, dst); + fwrite(buf, len, 1, dst); +} + +int main(int argc, char *argv[]) +{ + if (argc!=2) { + usage(argv[0]); + } + + FILE *fp = fopen(argv[1], "rb+"); + + if (fp==NULL) { + puts("Error opening file!"); + exit(1); + } + + char *basename = strrchr(argv[1], '/'); + if (basename==NULL) + basename = argv[1]; + else + basename = basename+1; + + int len = strlen(basename); + char fn1[len+5], fn2[len+5]; + strcpy(fn1, basename); + strcpy(fn2, basename); + strcat(fn1, ".fw1"); + strcat(fn2, ".fw2"); + + FILE *fw1 = fopen(fn1, "wb+"); + FILE *fw2 = fopen(fn2, "wb+"); + + long romsz; + FseekEnd(fp, -1); + romsz = ftell(fp)+1; + printf("size of %s: 0x%lx\n", argv[1], romsz); + + if (romsz&0xff) { + puts("The ROM size must be multiple of 0x100"); + exit(1); + } + + /* read offset of fw1 and fw2 */ + char offs[8]; + FseekEnd(fp, -0x100); + fread(offs, 8, 1, fp); + + assert(offs[0]+offs[2]=='\xff'); + assert(offs[1]+offs[3]=='\xff'); + assert(offs[4]+offs[6]=='\xff'); + assert(offs[5]+offs[7]=='\xff'); + long offw1 = (offs[0]<<16)|(offs[1]<<8); + long offw2 = (offs[4]<<16)|(offs[5]<<8); + + dump_fw(fw1, fp, offw1); + dump_fw(fw2, fp, offw2); + + fclose(fp); + fclose(fw1); + fclose(fw2); + return 0; +} diff --git a/util/kbc1126/kbc1126_ec_insert.c b/util/kbc1126/kbc1126_ec_insert.c new file mode 100644 index 0000000..2c1c7d0 --- /dev/null +++ b/util/kbc1126/kbc1126_ec_insert.c @@ -0,0 +1,94 @@ +#include <stdio.h> +#include <stdlib.h> + +static void usage(const char *s) +{ + printf("%s <rom file> <fw1> <fw2> <fw1 offset> <fw2 offset>\n", s); + exit(1); +} + +static void FseekEnd(FILE *fp, long o) +{ + if (fseek(fp, o, SEEK_END)!=0) { + puts("fseek() error!\n"); + exit(1); + } +} + +int main(int argc, char *argv[]) +{ + if (argc<6) { + usage(argv[0]); + } + + FILE *fp = fopen(argv[1], "rb+"); + FILE *fw1 = fopen(argv[2], "rb"); + FILE *fw2 = fopen(argv[3], "rb"); + long offset1 = strtol(argv[4], NULL, 0); + long offset2 = strtol(argv[5], NULL, 0); + + if (fp==NULL || fw1==NULL || fw2==NULL) { + puts("Error opening file!"); + exit(1); + } + + if ((offset1&0xff) || (offset2&0xff)) { + puts("The offsets must be aligned to 0x100"); + exit(1); + } + + long romsz; + FseekEnd(fp, -1); + romsz = ftell(fp)+1; + printf("size of %s: 0x%lx\n", argv[1], romsz); + + if (romsz&0xff) { + puts("The ROM size must be multiple of 0x100"); + exit(1); + } + + if (offset1>0) + offset1 = offset1-romsz; + + if (offset2>0) + offset2 = offset2-romsz; + + /* write two offsets to $s-0x100 */ + char offs[8]; + long os; + os = 0x1000000+offset1; + offs[0] = os>>16; + offs[1] = os>>8; + offs[2] = 0xff-offs[0]; + offs[3] = 0xff-offs[1]; + os = 0x1000000+offset2; + offs[4] = os>>16; + offs[5] = os>>8; + offs[6] = 0xff-offs[4]; + offs[7] = 0xff-offs[5]; + for (size_t i=0; i<8; i++) { + printf("%02hhx ", offs[i]); + } + puts(""); + FseekEnd(fp, -0x100); + printf("writing to 0x%lx\n", ftell(fp)); + fwrite(offs, 1, 8, fp); + + /* write fw1 and fw2 */ + char c; + FseekEnd(fp, offset1); + printf("writing to 0x%lx\n", ftell(fp)); + while (fread(&c, 1, 1, fw1)==1) { + fwrite(&c, 1, 1, fp); + } + FseekEnd(fp, offset2); + printf("writing to 0x%lx\n", ftell(fp)); + while (fread(&c, 1, 1, fw2)==1) { + fwrite(&c, 1, 1, fp); + } + + fclose(fp); + fclose(fw1); + fclose(fw2); + return 0; +} diff --git a/util/kbc1126/makefile b/util/kbc1126/makefile new file mode 100644 index 0000000..4826874 --- /dev/null +++ b/util/kbc1126/makefile @@ -0,0 +1,12 @@ +obj = kbc1126_ec_dump kbc1126_ec_insert +HOSTCC := $(if $(shell type gcc 2>/dev/null),gcc,cc) + +all: $(obj) + +%: %.c + $(HOSTCC) -Wall -o $@ $< + +clean: + rm -f kbc1126_ec_dump kbc1126_ec_insert + +.PHONY: all clean