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

📄 mkzynfw.c

📁 Linux Home Server 是专门为家庭和SOHO/SMB 设计的高性价比的ISCSI 存储服务器, 具有如下的特色: 强大的iscsi 存储服务器软件; 混合iscsi 和NAS 服务;
💻 C
📖 第 1 页 / 共 2 页
字号:
/* *  $Id: mkzynfw.c 11559 2008-06-22 19:02:42Z juhosg $ * *  Copyright (C) 2007-2008 OpenWrt.org *  Copyright (C) 2007-2008 Gabor Juhos <juhosg at openwrt.org> * *  This code was based on the information of the ZyXEL's firmware *  image format written by Kolja Waschk, can be found at: *  http://www.ixo.de/info/zyxel_uclinux * *  This program is free software; you can redistribute it and/or modify it *  under the terms of the GNU General Public License version 2 as published *  by the Free Software Foundation. * */#include <stdio.h>#include <stdlib.h>#include <stdint.h>#include <string.h>#include <unistd.h>	/* for unlink() */#include <libgen.h>#include <getopt.h>	/* for getopt() */#include <stdarg.h>#include <errno.h>#include <sys/stat.h>#include <endian.h>	/* for __BYTE_ORDER */#if defined(__CYGWIN__)#  include <byteswap.h>#endif#include "zynos.h"#if (__BYTE_ORDER == __LITTLE_ENDIAN)#  define HOST_TO_LE16(x)	(x)#  define HOST_TO_LE32(x)	(x)#  define LE16_TO_HOST(x)	(x)#  define LE32_TO_HOST(x)	(x)#  define HOST_TO_BE16(x)	bswap_16(x)#  define HOST_TO_BE32(x)	bswap_32(x)#  define BE16_TO_HOST(x)	bswap_16(x)#  define BE32_TO_HOST(x)	bswap_32(x)#else#  define HOST_TO_BE16(x)	(x)#  define HOST_TO_BE32(x)	(x)#  define BE16_TO_HOST(x)	(x)#  define BE32_TO_HOST(x)	(x)#  define HOST_TO_LE16(x)	bswap_16(x)#  define HOST_TO_LE32(x)	bswap_32(x)#  define LE16_TO_HOST(x)	bswap_16(x)#  define LE32_TO_HOST(x)	bswap_32(x)#endif#define ALIGN(x,y)	(((x)+((y)-1)) & ~((y)-1))#define MAX_NUM_BLOCKS	8#define MAX_ARG_COUNT	32#define MAX_ARG_LEN	1024#define FILE_BUF_LEN	(16*1024)struct csum_state{	int		odd;	uint32_t	sum;	uint32_t	tmp;};struct fw_block {	uint32_t	align;		/* alignment of this block */	char		*file_name;	/* name of the file */	uint32_t	file_size;	/* length of the file */	char		*mmap_name;	/* name in the MMAP table */	int		type;		/* block type */	uint32_t	padlen;	uint8_t		padc;};#define BLOCK_TYPE_BOOTEXT	0#define BLOCK_TYPE_RAW		1struct fw_mmap {	uint32_t	addr;	uint32_t	size;	uint32_t	user_addr;	uint32_t	user_size;};#define MMAP_DATA_SIZE	1024#define MMAP_ALIGN	16struct board_info {	char *name;		/* model name */	char *desc;		/* description */	uint16_t vendor;	/* vendor id */	uint16_t model;		/* model id */	uint32_t flash_base;	/* flash base address */	uint32_t flash_size;	/* board flash size */	uint32_t code_start;	/* code start address */	uint32_t romio_offs;	/* offset of the firmware within the flash */	uint32_t bootext_size;	/* maximum size of bootext block */};/* * Globals */char *progname;char *ofname = NULL;int verblevel = 0;struct board_info *board = NULL;struct fw_block blocks[MAX_NUM_BLOCKS];struct fw_block *bootext_block = NULL;int num_blocks = 0;#define ADM5120_FLASH_BASE	0xBFC00000#define ADM5120_CODE_START	0x80008000/* TODO: check values for AR7 */#define AR7_FLASH_BASE		0xB0000000#define AR7_CODE_START		0x94008000#define ATHEROS_FLASH_BASE	0xBFC00000#define ATHEROS_CODE_START	0x80e00000#define BOARD(n, d, v, m, fb, fs, cs, fo) {		\	.name = (n), .desc=(d),				\	.vendor = (v), .model = (m),			\	.flash_base = (fb), .flash_size = (fs)<<20,	\	.code_start = (cs), .romio_offs = (fo),		\	.bootext_size = BOOTEXT_DEF_SIZE		\	}#define ADMBOARD1(n, d, m, fs) BOARD(n, d, ZYNOS_VENDOR_ID_ZYXEL, m, \	ADM5120_FLASH_BASE, fs, ADM5120_CODE_START, 0x8000)#define ADMBOARD2(n, d, m, fs) BOARD(n, d, ZYNOS_VENDOR_ID_ZYXEL, m, \	ADM5120_FLASH_BASE, fs, ADM5120_CODE_START, 0x10000)#define AR7BOARD1(n, d, m, fs) BOARD(n, d, ZYNOS_VENDOR_ID_ZYXEL, m, \	AR7_FLASH_BASE, fs, AR7_CODE_START, 0x8000)#define ATHEROSBOARD1(n, d, m, fs) BOARD(n, d, ZYNOS_VENDOR_ID_ZYXEL, m, \	ATHEROS_FLASH_BASE, fs, ATHEROS_CODE_START, 0x30000)static struct board_info boards[] = {	/*	 * Infineon/ADMtek ADM5120 based boards	 */	ADMBOARD2("ES-2024A",	"ZyXEL ES-2024A", ZYNOS_MODEL_ES_2024A, 4),	ADMBOARD2("ES-2024PWR",	"ZyXEL ES-2024PWR", ZYNOS_MODEL_ES_2024PWR, 4),	ADMBOARD2("ES-2108",	"ZyXEL ES-2108", ZYNOS_MODEL_ES_2108, 4),	ADMBOARD2("ES-2108-F",	"ZyXEL ES-2108-F", ZYNOS_MODEL_ES_2108_F, 4),	ADMBOARD2("ES-2108-G",	"ZyXEL ES-2108-G", ZYNOS_MODEL_ES_2108_G, 4),	ADMBOARD2("ES-2108-LC",	"ZyXEL ES-2108-LC", ZYNOS_MODEL_ES_2108_LC, 4),	ADMBOARD2("ES-2108PWR",	"ZyXEL ES-2108PWR", ZYNOS_MODEL_ES_2108PWR, 4),	ADMBOARD1("HS-100",	"ZyXEL HomeSafe 100", ZYNOS_MODEL_HS_100, 2),	ADMBOARD1("HS-100W",	"ZyXEL HomeSafe 100W", ZYNOS_MODEL_HS_100W, 2),	ADMBOARD1("P-334",	"ZyXEL Prestige 334", ZYNOS_MODEL_P_334, 2),	ADMBOARD1("P-334U",	"ZyXEL Prestige 334U", ZYNOS_MODEL_P_334U, 4),	ADMBOARD1("P-334W",	"ZyXEL Prestige 334W", ZYNOS_MODEL_P_334W, 2),	ADMBOARD1("P-334WH",	"ZyXEL Prestige 334WH", ZYNOS_MODEL_P_334WH, 4),	ADMBOARD1("P-334WHD",	"ZyXEL Prestige 334WHD", ZYNOS_MODEL_P_334WHD, 4),	ADMBOARD1("P-334WT",	"ZyXEL Prestige 334WT", ZYNOS_MODEL_P_334WT, 4),	ADMBOARD1("P-335",	"ZyXEL Prestige 335", ZYNOS_MODEL_P_335, 4),	ADMBOARD1("P-335Plus",	"ZyXEL Prestige 335Plus", ZYNOS_MODEL_P_335PLUS, 4),	ADMBOARD1("P-335U",	"ZyXEL Prestige 335U", ZYNOS_MODEL_P_335U, 4),	ADMBOARD1("P-335WT",	"ZyXEL Prestige 335WT", ZYNOS_MODEL_P_335WT, 4),	{		.name		= "P-2602HW-D1A",		.desc		= "ZyXEL P-2602HW-D1A",		.vendor		= ZYNOS_VENDOR_ID_ZYXEL,		.model		= ZYNOS_MODEL_P_2602HW_D1A,		.flash_base	= AR7_FLASH_BASE,		.flash_size	= 4*1024*1024,		.code_start	= 0x94008000,		.romio_offs	= 0x20000,		.bootext_size	= BOOTEXT_DEF_SIZE,	},#if 0	/*	 * Texas Instruments AR7 based boards	 */	AR7BOARD1("P-660H-61",  "ZyXEL P-660H-61", ZYNOS_MODEL_P_660H_61, 2),	AR7BOARD1("P-660H-63",  "ZyXEL P-660H-63", ZYNOS_MODEL_P_660H_63, 2),	AR7BOARD1("P-660H-D1",  "ZyXEL P-660H-D1", ZYNOS_MODEL_P_660H_D1, 2),	AR7BOARD1("P-660H-D3",  "ZyXEL P-660H-D3", ZYNOS_MODEL_P_660H_D3, 2),	AR7BOARD1("P-660HW-61", "ZyXEL P-660HW-61", ZYNOS_MODEL_P_660HW_61, 2),	AR7BOARD1("P-660HW-63", "ZyXEL P-660HW-63", ZYNOS_MODEL_P_660HW_63, 2),	AR7BOARD1("P-660HW-67", "ZyXEL P-660HW-67", ZYNOS_MODEL_P_660HW_67, 2),	AR7BOARD1("P-660HW-D1", "ZyXEL P-660HW-D1", ZYNOS_MODEL_P_660HW_D1, 2),	AR7BOARD1("P-660HW-D3", "ZyXEL P-660HW-D3", ZYNOS_MODEL_P_660HW_D3, 2),	AR7BOARD1("P-660R-61",  "ZyXEL P-660R-61", ZYNOS_MODEL_P_660R_61, 2),	AR7BOARD1("P-660R-61C", "ZyXEL P-660R-61C", ZYNOS_MODEL_P_660R_61C, 2),	AR7BOARD1("P-660R-63",  "ZyXEL P-660R-63", ZYNOS_MODEL_P_660R_63, 2),	AR7BOARD1("P-660R-63C", "ZyXEL P-660R-63C", ZYNOS_MODEL_P_660R_63C, 2),	AR7BOARD1("P-660R-67",  "ZyXEL P-660R-67", ZYNOS_MODEL_P_660R_67, 2),	AR7BOARD1("P-660R-D1",  "ZyXEL P-660R-D1", ZYNOS_MODEL_P_660R_D1, 2),	AR7BOARD1("P-660R-D3",  "ZyXEL P-660R-D3", ZYNOS_MODEL_P_660R_D3, 2),#endif	{		.name		= "O2SURF",		.desc		= "O2 DSL Surf & Phone",		.vendor		= ZYNOS_VENDOR_ID_O2,		.model		= ZYNOS_MODEL_O2SURF,		.flash_base	= AR7_FLASH_BASE,		.flash_size	= 8*1024*1024,		.code_start	= 0x94014000,		.romio_offs	= 0x40000,		.bootext_size	= BOOTEXT_DEF_SIZE,	},	/*:x	 */	ATHEROSBOARD1("NBG-318S", "ZyXEL NBG-318S", ZYNOS_MODEL_NBG_318S, 4),	{.name = NULL}};/* * Message macros */#define ERR(fmt, ...) do { \	fflush(0); \	fprintf(stderr, "[%s] *** error: " fmt "\n", \			progname, ## __VA_ARGS__ ); \} while (0)#define ERRS(fmt, ...) do { \	int save = errno; \	fflush(0); \	fprintf(stderr, "[%s] *** error: " fmt ", %s\n", \			progname, ## __VA_ARGS__, strerror(save)); \} while (0)#define WARN(fmt, ...) do { \	fprintf(stderr, "[%s] *** warning: " fmt "\n", \			progname, ## __VA_ARGS__ ); \} while (0)#define DBG(lev, fmt, ...) do { \	if (verblevel < lev) \		break;\	fprintf(stderr, "[%s] " fmt "\n", progname, ## __VA_ARGS__ ); \} while (0)#define ERR_FATAL		-1#define ERR_INVALID_IMAGE	-2/* * Helper routines */voidusage(int status){	FILE *stream = (status != EXIT_SUCCESS) ? stderr : stdout;	struct board_info *board;	fprintf(stream, "Usage: %s [OPTIONS...]\n", progname);	fprintf(stream,"\n""Options:\n""  -B <board>      create image for the board specified with <board>.\n""                  valid <board> values:\n"	);	for (board = boards; board->name != NULL; board++){		fprintf(stream,"                    %-12s= %s\n",		 board->name, board->desc);	};	fprintf(stream,"  -b <file>[:<align>]\n""                  add boot extension block to the image\n""  -r <file>[:<align>]\n""                  add raw block to the image\n""  -o <file>       write output to the file <file>\n""  -h              show this screen\n"	);	exit(status);}/* * argument parsing */intstr2u32(char *arg, uint32_t *val){	char *err = NULL;	uint32_t t;	errno=0;	t = strtoul(arg, &err, 0);	if (errno || (err==arg) || ((err != NULL) && *err)) {		return -1;	}	*val = t;	return 0;}intstr2u16(char *arg, uint16_t *val){	char *err = NULL;	uint32_t t;	errno=0;	t = strtoul(arg, &err, 0);	if (errno || (err==arg) || ((err != NULL) && *err) || (t >= 0x10000)) {		return -1;	}	*val = t & 0xFFFF;	return 0;}intstr2u8(char *arg, uint8_t *val){	char *err = NULL;	uint32_t t;	errno=0;	t = strtoul(arg, &err, 0);	if (errno || (err==arg) || ((err != NULL) && *err) || (t >= 0x100)) {		return -1;	}	*val = t & 0xFF;	return 0;}intstr2sig(char *arg, uint32_t *sig){	if (strlen(arg) != 4)		return -1;	*sig = arg[0] | (arg[1] << 8) | (arg[2] << 16) | (arg[3] << 24);	return 0;}intparse_arg(char *arg, char *buf, char *argv[]){	int res = 0;	size_t argl;	char *tok;	char **ap = &buf;	int i;	memset(argv, 0, MAX_ARG_COUNT * sizeof(void *));	if ((arg == NULL)) {		/* no arguments */		return 0;	}	argl = strlen(arg);	if (argl == 0) {		/* no arguments */		return 0;	}	if (argl >= MAX_ARG_LEN) {		/* argument is too long */		argl = MAX_ARG_LEN-1;	}	memcpy(buf, arg, argl);	buf[argl] = '\0';	for (i = 0; i < MAX_ARG_COUNT; i++) {		tok = strsep(ap, ":");		if (tok == NULL) {			break;		}#if 0		else if (tok[0] == '\0') {			break;		}#endif		argv[i] = tok;		res++;	}	return res;}intrequired_arg(char c, char *arg){	if (arg == NULL || *arg != '-')		return 0;	ERR("option -%c requires an argument\n", c);	return -1;}intis_empty_arg(char *arg){	int ret = 1;	if (arg != NULL) {		if (*arg) ret = 0;	};	return ret;}voidcsum_init(struct csum_state *css){	css->odd = 0;	css->sum = 0;	css->tmp = 0;}voidcsum_update(uint8_t *p, uint32_t len, struct csum_state *css){	if (len == 0)		return;	if (css->odd) {		css->sum += (css->tmp << 8) + p[0];		if (css->sum > 0xFFFF) {			css->sum += 1;			css->sum &= 0xFFFF;		}		css->odd = 0;		len--;		p++;	}	for ( ; len > 1; len -= 2, p +=2 ) {		css->sum  += (p[0] << 8) + p[1];		if (css->sum > 0xFFFF) {			css->sum += 1;			css->sum &= 0xFFFF;		}	}	if (len == 1){		css->tmp = p[0];		css->odd = 1;	}}uint16_tcsum_get(struct csum_state *css){	char pad = 0;	csum_update(&pad, 1, css);	return css->sum;}uint16_tcsum_buf(uint8_t *p, uint32_t len){	struct csum_state css;	csum_init(&css);	csum_update(p, len, &css);	return csum_get(&css);}/* * routines to write data to the output file */intwrite_out_data(FILE *outfile, uint8_t *data, size_t len,		struct csum_state *css){	errno = 0;	fwrite(data, len, 1, outfile);	if (errno) {		ERR("unable to write output file");		return -1;	}	if (css) {		csum_update(data, len, css);	}	return 0;}intwrite_out_padding(FILE *outfile, size_t len, uint8_t padc,		 struct csum_state *css){	uint8_t buf[512];	size_t buflen = sizeof(buf);	memset(buf, padc, buflen);	while (len > 0) {		if (len < buflen)			buflen = len;		if (write_out_data(outfile, buf, buflen, css))			return -1;		len -= buflen;	}	return 0;}intwrite_out_data_align(FILE *outfile, uint8_t *data, size_t len, size_t align,		struct csum_state *css){	size_t padlen;	int res;	res = write_out_data(outfile, data, len, css);	if (res)		return res;	padlen = ALIGN(len,align) - len;	res = write_out_padding(outfile, padlen, 0xFF, css);	return res;}intwrite_out_header(FILE *outfile, struct zyn_rombin_hdr *hdr){	struct zyn_rombin_hdr t;	errno = 0;	if (fseek(outfile, 0, SEEK_SET) != 0) {		ERRS("fseek failed on output file");		return -1;	}	/* setup temporary header fields */	memset(&t, 0, sizeof(t));	t.addr = HOST_TO_BE32(hdr->addr);

⌨️ 快捷键说明

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