arm2hpdl.c

来自「Linux下的无线网卡通用驱动程序」· C语言 代码 · 共 252 行

C
252
字号
#include <stdio.h>#include <stdlib.h>#include <stdarg.h>#include <string.h>#include <sys/types.h>#include <sys/stat.h>#include <unistd.h>/* * Global option flags */int	Debug = 0;voiddebug(int level, char *fmt, ...){	va_list ap;	if (Debug < level)		return;	va_start(ap, fmt);	vfprintf(stderr, fmt, ap);	va_end(ap);}interror(int fatal, char *fmt, ...){	va_list ap;	if (fatal)	    fprintf(stderr, "Error: ");	else	    fprintf(stderr, "Warning: ");	va_start(ap, fmt);	vfprintf(stderr, fmt, ap);	va_end(ap);	if (fatal > 0)	    exit(fatal);	else	    return (fatal);}voidusage(void){	fprintf(stderr,"Usage:\n""	arm2hpdl [options] sihp1005.img > sihp1005.dl\n""\n""	Add HP download header/trailer to an ARM ELF binary.\n""	If the file already has an HP header, just copy it to stdout.\n""\n""Options:\n""       -D lvl      Set Debug level [%d]\n"	, Debug	);	exit(1);}/* * Compute HP-style checksum */longdocheck(long check, unsigned char *buf, int len){    int	i;    if (len & 1)	error(1, "We should never see an odd number of bytes in this app.\n");    for (i = 0; i < len; i += 2)	check += (buf[i]<<0) | (buf[i+1]<<8);    return check;}intmain(int argc, char *argv[]){	extern int	optind;	extern char	*optarg;	int		c;	int		rc;	unsigned char	buf[BUFSIZ];	int		len;	FILE		*fp;	struct stat	stats;	int		size;	unsigned char	elf[4];	long		check;	int		iself;	int		ispjl;	while ( (c = getopt(argc, argv, "D:?h")) != EOF)		switch (c)		{		case 'D':			Debug = atoi(optarg);			break;		default:			usage();			exit(1);		}	argc -= optind;	argv += optind;	if (argc != 1)	    usage();	/*	 * Open the file and figure out if its an ELF file	 * by reading the first 4 bytes.	 */	fp = fopen(argv[0], "r");	if (!fp)	    error(1, "Can't open '%s'\n", argv[0]);	len = fread(elf, 1, sizeof(elf), fp);	if (len != 4)	    error(1, "Premature EOF on '%s'\n", argv[0]);	iself = 0;	ispjl = 0;	check = 0;	if (memcmp(elf, "\177ELF", 4) == 0)	{	    /*	     * Its an ELF executable file	     */	    unsigned char	filhdr[17] =	    {		0xbe, 0xef, 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H',		0, 0, 0, 0,	/* size goes here */		0, 0, 0,	    };	    unsigned char	sechdr[12] =	    {		0xc0, 0xde, 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 0, 0	    };	    iself = 1;	    /*	     * Create and write the file header	     */	    rc = stat(argv[0], &stats);	    if (rc < 0)		error(1, "Can't stat '%s'\n", argv[0]);	    size = stats.st_size + 12 + 4;	    filhdr[10] = size>>24;	    filhdr[11] = size>>16;	    filhdr[12] = size>> 8;	    filhdr[13] = size>> 0;	    fwrite(filhdr, 1, sizeof(filhdr), stdout);	    /*	     * Create and write the section header	     */	    //memset(sechdr+2, 0, sizeof(sechdr)-2);	    check = docheck(check, sechdr, sizeof(sechdr));	    fwrite(sechdr, 1, sizeof(sechdr), stdout);	}	else if (memcmp(elf, "\276\357AB", 4) == 0)	{	    /*	     * This file already has an HP download header.	     * Don't change it.	     */	    if (Debug)		error(0, "This file already has an HP header.  "		    "I will just copy it to stdout.\n");	}	else if (memcmp(elf, "20", 2) == 0)	{	    unsigned char hdr[8];	    	    ispjl = 1;	    printf("\033%%-12345X@PJL ENTER LANGUAGE=ACL\r\n");	    rc = stat(argv[0], &stats);	    if (rc < 0)		error(1, "Can't stat '%s'\n", argv[0]);	    size = stats.st_size - 8;	    hdr[0] = 0x00;	    hdr[1] = 0xac;	    hdr[2] = 0xc0;	    hdr[3] = 0xde;	    hdr[4] = size>>24;	    hdr[5] = size>>16;	    hdr[6] = size>> 8;	    hdr[7] = size>> 0;	    fwrite(hdr, 1, sizeof(hdr), stdout);	}	else	{	    error(1, "I don't understand this file at all!\n");	}	/*	 * Write out the 4 bytes we read earlier	 */	if (iself)	    check = docheck(check, elf, sizeof(elf));	fwrite(elf, 1, sizeof(elf), stdout);	/*	 * Write out the remainder of the file	 */	while ( (len = fread(buf, 1, sizeof(buf), fp)) )	{	    if (iself)		check = docheck(check, buf, len);	    fwrite(buf, 1, len, stdout);	}	fclose(fp);	/*	 * Add the file trailer	 */	if (iself)	{	    /*	     * Add in the checksum carries and complement it	     */	    while (check >> 16)		check = (check&0xffff) + (check>>16);	    check = ~check;	    putchar(0xff);	    putchar(0xff);	    putchar((check >> 0) & 0xff);	    putchar((check >> 8) & 0xff);	    debug(1, "checksum = %lx\n", check);	}	if (ispjl)	    printf("\033%%-12345X");	exit(0);}

⌨️ 快捷键说明

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