⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 firmware-tool.c

📁 trident tm5600的linux驱动
💻 C
📖 第 1 页 / 共 2 页
字号:
/*   Xceive XC2028/3028 tuner module firmware manipulation tool   Copyright (C) 2007 Michel Ludwig <michel.ludwig@gmail.com>   Copyright (C) 2007, 2008 Mauro Carvalho Chehab <mchehab@infradead.org>	- Improve --list command	- Add --seek command   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   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.   You should have received a copy of the GNU General Public License   along with this program; if not, write to the Free Software   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */#include <sys/stat.h>#include <fcntl.h>#include <stdio.h>#include <stdlib.h>#define __USE_GNU#include <string.h>#include <getopt.h>#include <string.h>#include <unistd.h>#include <asm/byteorder.h>#include <asm/types.h>#include "../../../linux/drivers/media/video/tuner-xc2028-types.h"#include "../../../linux/include/linux/videodev2.h"#include "extract_head.h"#include "standards.h"#define LIST_ACTION		(1<<0)#define ADD_ACTION		(1<<1)#define DELETE_ACTION		(1<<2)#define SET_TYPE_ACTION		(1<<3)#define SET_ID_ACTION		(1<<4)#define SEEK_FIRM_ACTION	(1<<5)struct firmware_description {	__u32 type;	__u64 id;	unsigned char *data;	__u16 int_freq;	__u32 size;};struct firmware {	char* name;	struct firmware_description* desc;	__u16 version;	__u16 nr_desc;};struct firmware_description* alloc_firmware_description(void) {	struct firmware_description *d = malloc(sizeof(*d));	d->type = 0;	d->id = 0;	d->data = NULL;	d->size = 0;	return d;}void free_firmware_description(struct firmware_description *d) {	free(d->data);	free(d);}struct firmware* alloc_firmware(void) {	struct firmware *f = malloc(sizeof(*f));	f->name = NULL;	f->desc = NULL;	f->nr_desc = 0;	return f;}void free_firmware(struct firmware *f) {	free(f->name);	free(f->desc);	if(f->desc) {		unsigned int i = 0;		for(i = 0; i < f->nr_desc; ++ i) {			free(f->desc[i].data);		}	}	free(f);}void add_firmware_description(struct firmware *f,			      struct firmware_description *d) {	struct firmware_description* new_desc;	new_desc = malloc((f->nr_desc + 1) * sizeof(*new_desc));	memcpy(new_desc, f->desc, f->nr_desc * sizeof(*new_desc));	memcpy(new_desc + f->nr_desc, d, sizeof(*d));	free(f->desc);	f->desc = new_desc;	++f->nr_desc;}void delete_firmware_description(struct firmware *f, __u16 i) {	struct firmware_description* new_desc;	if(f->nr_desc == 0 || i >= f->nr_desc) {		return;	}	new_desc = malloc((f->nr_desc - 1) * sizeof(*new_desc));	memcpy(new_desc, f->desc, i * sizeof(*f->desc));	memcpy(new_desc + i, f->desc + i + 1, (f->nr_desc - i - 1) * sizeof(*f->desc));	free(f->desc);	f->desc = new_desc;	--f->nr_desc;}/* name[32] + version[2] + nr_desc[2] */#define HEADER_LENGTH (32 + 2 + 2)/* description header: 4 + 8 + 4.*/#define DESC_HEADER_LENGTH (4 + 8 + 4)int read_firmware(unsigned char* data, off_t size, struct firmware** f_res) {	char *name = malloc(33);	unsigned char *p = data;	struct firmware* f = alloc_firmware();	unsigned int i;	if(size < HEADER_LENGTH) {		printf("Invalid firmware header length.\n");		free_firmware(f);		return -1;	}	name[32] = 0;	memcpy(name, data, 32);	f->name = name;	p += 32;	f->version = __le16_to_cpu(*(__u16*)p);	p += sizeof(f->version);	f->nr_desc = __le16_to_cpu(*(__u16*)p);	p += sizeof(f->nr_desc);	f->desc = malloc(f->nr_desc * sizeof(*(f->desc)));	for(i = 0; i < f->nr_desc; ++i) {		if(p + DESC_HEADER_LENGTH > data + size) {			printf("Invalid description header length.\n");			free_firmware(f);			return -1;		}		f->desc[i].type = __le32_to_cpu(*(__u32*) p);		p += sizeof(f->desc[i].type);		f->desc[i].id = __le64_to_cpu(*(__u64*) p);		p += sizeof(f->desc[i].id);		if (f->desc[i].type & HAS_IF) {			f->desc[i].int_freq = __le16_to_cpu(*(__u16 *) p);			p += sizeof(f->desc[i].int_freq);		}		f->desc[i].size = __le32_to_cpu(*(__u32*) p);		p += sizeof(f->desc[i].size);		if(p + f->desc[i].size > data + size) {			printf("Invalid firmware standard length.\n");			f->nr_desc = (f->nr_desc == 0) ? 0 : f->nr_desc -1;			free_firmware(f);			return -1;		}		f->desc[i].data = malloc(f->desc[i].size);		memcpy(f->desc[i].data, p, f->desc[i].size);		p += f->desc[i].size;	}	*f_res = f;	return 0;}void write_firmware(struct firmware *f, unsigned char** r_data, off_t *r_size) {	off_t size;	unsigned int i = 0;	unsigned char* data;	unsigned char* p;	size = HEADER_LENGTH + f->nr_desc * DESC_HEADER_LENGTH;	for(i = 0; i < f->nr_desc; ++i) {		size += f->desc[i].size;	}	data = malloc(size);	p = data;	memcpy(p, f->name, 32);	p += 32;	*(__u16*)p = __cpu_to_le16(f->version);	p += sizeof(f->version);	*(__u16*)p = __cpu_to_le16(f->nr_desc);	p += sizeof(f->nr_desc);	for(i = 0; i < f->nr_desc; ++i) {		*(__u32*) p = __cpu_to_le32(f->desc[i].type);		p += sizeof(f->desc[i].type);		*(__u64*) p = __cpu_to_le64(f->desc[i].id);		p += sizeof(f->desc[i].id);		*(__u32*) p = __cpu_to_le32(f->desc[i].size);		p += sizeof(f->desc[i].size);		memcpy(p, f->desc[i].data, f->desc[i].size);		p += f->desc[i].size;	}	*r_data = data;	*r_size = size;}struct firmware* read_firmware_file(const char* filename) {	struct stat buf;	unsigned char *ptr;	struct firmware *f;	int fd;	if(stat(filename, &buf) < 0) {		perror("Error during stat");		return NULL;	}	fd = open(filename, O_RDONLY);	if(fd < 0) {		perror("Error while opening the firmware file");		free_firmware(f);		return NULL;	}	/* allocate firmware buffer*/	ptr = malloc(buf.st_size);	if(read(fd, ptr, buf.st_size) < 0) {		perror("Error while reading the firmware file");		free(ptr);		close(fd);		return NULL;	}	if(read_firmware(ptr, buf.st_size, &f) < 0) {		printf("Invalid firmware file!\n");		free(ptr);		close(fd);		return NULL;	}	close(fd);	free(ptr);	return f;}void write_firmware_file(const char* filename, struct firmware *f) {	int fd;	unsigned char* data;	off_t size = 0;	fd = open(filename, O_WRONLY | O_CREAT);	if(fd < 0) {		perror("Error while opening the firmware file");		return;	}	if(ftruncate(fd, 0) < 0) {		perror("Error while deleting the firmware file");		close(fd);		return;	}	write_firmware(f, &data, &size);	if(write(fd, data, size) < 0) {		perror("Error while writing the firmware file");		close(fd);		return;	}	free(data);	close(fd);}void dump_firm_type(FILE *fp, unsigned int type){	if (type & SCODE)		fprintf(fp, "SCODE FW  ");	else if (type & BASE)		fprintf(fp, "BASE FW   ");	else		fprintf(fp, "STD FW    ");	if (type & F8MHZ)		fprintf(fp, "F8MHZ ");	if (type & MTS)		fprintf(fp, "MTS ");	if (type & D2620)		fprintf(fp, "D2620 ");	if (type & D2633)		fprintf(fp, "D2633 ");	if (type & DTV6)		fprintf(fp, "DTV6 ");	if (type & QAM)		fprintf(fp, "QAM ");	if (type & DTV7)		fprintf(fp, "DTV7 ");	if (type & DTV78)		fprintf(fp, "DTV78 ");	if (type & DTV8)		fprintf(fp, "DTV8 ");	if (type & FM)		fprintf(fp, "FM ");	if (type & INPUT1)		fprintf(fp, "INPUT1 ");	if (type & LCD)		fprintf(fp, "LCD ");	if (type & NOGD)		fprintf(fp, "NOGD ");	if (type & MONO)		fprintf(fp, "MONO ");	if (type & ATSC)		fprintf(fp, "ATSC ");	if (type & IF)		fprintf(fp, "IF ");	if (type & LG60)		fprintf(fp, "LG60 ");	if (type & ATI638)		fprintf(fp, "ATI638 ");	if (type & OREN538)		fprintf(fp, "OREN538 ");	if (type & OREN36)		fprintf(fp, "OREN36 ");	if (type & TOYOTA388)		fprintf(fp, "TOYOTA388 ");	if (type & TOYOTA794)		fprintf(fp, "TOYOTA794 ");	if (type & DIBCOM52)		fprintf(fp, "DIBCOM52 ");	if (type & ZARLINK456)		fprintf(fp, "ZARLINK456 ");	if (type & CHINA)		fprintf(fp, "CHINA ");	if (type & F6MHZ)		fprintf(fp, "F6MHZ ");	if (type & INPUT2)		fprintf(fp, "INPUT2 ");	if (type & HAS_IF)		fprintf(fp, "HAS IF ");}void dump_firm_std(FILE *fp, v4l2_std_id id){	v4l2_std_id old=-1, curr_id;	/* Dumps video standards */	while (old!=id) {		old=id;		if ( (id & V4L2_STD_PAL) == V4L2_STD_PAL) {			fprintf (fp, "PAL ");			curr_id = V4L2_STD_PAL;		} else if ( (id & V4L2_STD_MN) == V4L2_STD_MN) {			fprintf (fp, "NTSC PAL/M PAL/N ");			curr_id = V4L2_STD_PAL;		} else if ( (id & V4L2_STD_PAL_BG) == V4L2_STD_PAL_BG) {			fprintf (fp, "PAL/BG ");			curr_id = V4L2_STD_PAL_BG;		} else if ( (id & V4L2_STD_PAL_DK) == V4L2_STD_PAL_DK) {			fprintf (fp, "PAL/DK ");			curr_id = V4L2_STD_PAL_DK;		} else if ( (id & V4L2_STD_PAL_B) == V4L2_STD_PAL_B) {			fprintf (fp, "PAL/B ");			curr_id = V4L2_STD_PAL_B;		} else if ( (id & V4L2_STD_PAL_B1) == V4L2_STD_PAL_B1) {			fprintf (fp, "PAL/B1 ");			curr_id = V4L2_STD_PAL_B1;		} else if ( (id & V4L2_STD_PAL_G) == V4L2_STD_PAL_G) {			fprintf (fp, "PAL/G ");			curr_id = V4L2_STD_PAL_G;		} else if ( (id & V4L2_STD_PAL_H) == V4L2_STD_PAL_H) {			fprintf (fp, "PAL/H ");			curr_id = V4L2_STD_PAL_H;		} else if ( (id & V4L2_STD_PAL_I) == V4L2_STD_PAL_I) {			fprintf (fp, "PAL/I ");			curr_id = V4L2_STD_PAL_I;		} else if ( (id & V4L2_STD_PAL_D) == V4L2_STD_PAL_D) {			fprintf (fp, "PAL/D ");			curr_id = V4L2_STD_PAL_D;		} else if ( (id & V4L2_STD_PAL_D1) == V4L2_STD_PAL_D1) {			fprintf (fp, "PAL/D1 ");			curr_id = V4L2_STD_PAL_D1;		} else if ( (id & V4L2_STD_PAL_K) == V4L2_STD_PAL_K) {			fprintf (fp, "PAL/K ");			curr_id = V4L2_STD_PAL_K;		} else if ( (id & V4L2_STD_PAL_M) == V4L2_STD_PAL_M) {			fprintf (fp, "PAL/M ");			curr_id = V4L2_STD_PAL_M;		} else if ( (id & V4L2_STD_PAL_N) == V4L2_STD_PAL_N) {			fprintf (fp, "PAL/N ");			curr_id = V4L2_STD_PAL_N;		} else if ( (id & V4L2_STD_PAL_Nc) == V4L2_STD_PAL_Nc) {			fprintf (fp, "PAL/Nc ");			curr_id = V4L2_STD_PAL_Nc;		} else if ( (id & V4L2_STD_PAL_60) == V4L2_STD_PAL_60) {			fprintf (fp, "PAL/60 ");			curr_id = V4L2_STD_PAL_60;		} else if ( (id & V4L2_STD_NTSC) == V4L2_STD_NTSC) {			fprintf (fp, "NTSC ");			curr_id = V4L2_STD_NTSC;		} else if ( (id & V4L2_STD_NTSC_M) == V4L2_STD_NTSC_M) {			fprintf (fp, "NTSC/M ");			curr_id = V4L2_STD_NTSC_M;		} else if ( (id & V4L2_STD_NTSC_M_JP) == V4L2_STD_NTSC_M_JP) {			fprintf (fp, "NTSC/M Jp ");			curr_id = V4L2_STD_NTSC_M_JP;		} else if ( (id & V4L2_STD_NTSC_443) == V4L2_STD_NTSC_443) {			fprintf (fp, "NTSC 443 ");			curr_id = V4L2_STD_NTSC_443;		} else if ( (id & V4L2_STD_NTSC_M_KR) == V4L2_STD_NTSC_M_KR) {			fprintf (fp, "NTSC/M Kr ");			curr_id = V4L2_STD_NTSC_M_KR;		} else if ( (id & V4L2_STD_SECAM) == V4L2_STD_SECAM) {			fprintf (fp, "SECAM ");			curr_id = V4L2_STD_SECAM;		} else if ( (id & V4L2_STD_SECAM_DK) == V4L2_STD_SECAM_DK) {			fprintf (fp, "SECAM/DK ");			curr_id = V4L2_STD_SECAM_DK;		} else if ( (id & V4L2_STD_SECAM_B) == V4L2_STD_SECAM_B) {			fprintf (fp, "SECAM/B ");			curr_id = V4L2_STD_SECAM_B;		} else if ( (id & V4L2_STD_SECAM_D) == V4L2_STD_SECAM_D) {			fprintf (fp, "SECAM/D ");			curr_id = V4L2_STD_SECAM_D;		} else if ( (id & V4L2_STD_SECAM_G) == V4L2_STD_SECAM_G) {			fprintf (fp, "SECAM/G ");			curr_id = V4L2_STD_SECAM_G;		} else if ( (id & V4L2_STD_SECAM_H) == V4L2_STD_SECAM_H) {			fprintf (fp, "SECAM/H ");			curr_id = V4L2_STD_SECAM_H;		} else if ( (id & V4L2_STD_SECAM_K) == V4L2_STD_SECAM_K) {			fprintf (fp, "SECAM/K ");			curr_id = V4L2_STD_SECAM_K;		} else if ( (id & V4L2_STD_SECAM_K1) == V4L2_STD_SECAM_K1) {			fprintf (fp, "SECAM/K1 ");			curr_id = V4L2_STD_SECAM_K1;		} else if ( (id & V4L2_STD_SECAM_K3) == V4L2_STD_SECAM_K3) {			fprintf (fp, "SECAM/K3 ");			curr_id = V4L2_STD_SECAM_K3;		} else if ( (id & V4L2_STD_SECAM_L) == V4L2_STD_SECAM_L) {			fprintf (fp, "SECAM/L ");			curr_id = V4L2_STD_SECAM_L;		} else if ( (id & V4L2_STD_SECAM_LC) == V4L2_STD_SECAM_LC) {			fprintf (fp, "SECAM/Lc ");			curr_id = V4L2_STD_SECAM_LC;		} else if ( (id & V4L2_STD_A2) == V4L2_STD_A2) {			fprintf (fp, "A2 ");			curr_id = V4L2_STD_A2;		} else if ( (id & V4L2_STD_A2_A) == V4L2_STD_A2_A) {			fprintf (fp, "A2/A ");			curr_id = V4L2_STD_A2_A;		} else if ( (id & V4L2_STD_A2_B) == V4L2_STD_A2_B) {			fprintf (fp, "A2/B ");			curr_id = V4L2_STD_A2_B;		} else if ( (id & V4L2_STD_NICAM) == V4L2_STD_NICAM) {			fprintf (fp, "NICAM ");			curr_id = V4L2_STD_NICAM;		} else if ( (id & V4L2_STD_NICAM_A) == V4L2_STD_NICAM_A) {			fprintf (fp, "NICAM/A ");			curr_id = V4L2_STD_NICAM_A;		} else if ( (id & V4L2_STD_NICAM_B) == V4L2_STD_NICAM_B) {			fprintf (fp, "NICAM/B ");			curr_id = V4L2_STD_NICAM_B;		} else if ( (id & V4L2_STD_AM) == V4L2_STD_AM) {			fprintf (fp, "AM ");			curr_id = V4L2_STD_AM;		} else if ( (id & V4L2_STD_BTSC) == V4L2_STD_BTSC) {			fprintf (fp, "BTSC ");			curr_id = V4L2_STD_BTSC;		} else if ( (id & V4L2_STD_EIAJ) == V4L2_STD_EIAJ) {			fprintf (fp, "EIAJ ");			curr_id = V4L2_STD_EIAJ;		} else {			curr_id = 0;			break;		}		id &= ~curr_id;	}}void list_firmware_desc(FILE *fp, struct firmware_description *desc){	fprintf(fp, "type: ");	dump_firm_type(fp, desc->type);	fprintf(fp, "(0x%08x), ", desc->type);	if (desc->type & HAS_IF)		fprintf(fp, "IF = %.2f MHz ", desc->int_freq/1000.0);	fprintf(fp, "id: ");	dump_firm_std(fp, desc->id);	fprintf(fp, "(%016llx), ", desc->id);	fprintf(fp, "size: %u\n", desc->size);}void list_firmware(struct firmware *f, unsigned int dump, char *binfile){	unsigned int i = 0;	printf("firmware name:\t%s\n", f->name);	printf("version:\t%d.%d (%u)\n", f->version >> 8, f->version & 0xff,					  f->version);	printf("standards:\t%u\n", f->nr_desc);	for(i = 0; i < f->nr_desc; ++i) {		printf("Firmware %2u, ", i);		list_firmware_desc(stdout, &f->desc[i]);		if (dump) {			printf("\t");			unsigned j, k = 0;			for (j = 0; j < f->desc[i].size; j++) {				printf("%02x", f->desc[i].data[j]);				k++;				if (k >= 32) {					printf("\n\t");					k = 0;				} else if (!(k % 2))					printf(" ");			}			printf("\n");		}		if (binfile) {			char name[strlen(binfile)+4], *p;			p = strrchr(binfile,'.');			if (p) {				int n = p - binfile;				strncpy(name, binfile, n);				sprintf(name + n, "%03i", i);				strcat(name, p);			} else {				strcpy(name, binfile);				sprintf(name + strlen(name), "%03i", i);			}			FILE *fp;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -