- fix the error caused by signed integer extension - fix fopen mode - one minor style fix Change-Id: Iacc4ea50515ea219bc1868dae0446d576e8dce0c Signed-off-by: Iru Cai <mytbk920423@gmail.com> Reviewed-on: https://review.coreboot.org/21013 Tested-by: build bot (Jenkins) <no-reply@coreboot.org> Reviewed-by: Arthur Heymans <arthur@aheymans.xyz>
		
			
				
	
	
		
			125 lines
		
	
	
		
			2.5 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			125 lines
		
	
	
		
			2.5 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| /*
 | |
|  * This file is part of the coreboot project.
 | |
|  *
 | |
|  * Copyright (C) 2017 Iru Cai <mytbk920423@gmail.com>
 | |
|  *
 | |
|  * This program is free software; you can redistribute it and/or modify
 | |
|  * it under the terms of the GNU General Public License as published by
 | |
|  * the Free Software Foundation; version 2 of the License.
 | |
|  *
 | |
|  * This program is distributed in the hope that it will be useful,
 | |
|  * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | |
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | |
|  * GNU General Public License for more details.
 | |
|  */
 | |
| 
 | |
| #include <assert.h>
 | |
| #include <stdio.h>
 | |
| #include <stdlib.h>
 | |
| #include <string.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 */
 | |
| 	unsigned char offs[8];
 | |
| 	FseekEnd(fp, -0x100);
 | |
| 	fread(offs, 8, 1, fp);
 | |
| 
 | |
| 	assert(offs[0] + offs[2] == 0xff);
 | |
| 	assert(offs[1] + offs[3] == 0xff);
 | |
| 	assert(offs[4] + offs[6] == 0xff);
 | |
| 	assert(offs[5] + offs[7] == 0xff);
 | |
| 	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;
 | |
| }
 |