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

📄 mkzynfw.c

📁 Linux Home Server 是专门为家庭和SOHO/SMB 设计的高性价比的ISCSI 存储服务器, 具有如下的特色: 强大的iscsi 存储服务器软件; 混合iscsi 和NAS 服务;
💻 C
📖 第 1 页 / 共 2 页
字号:
	memcpy(&t.sig, ROMBIN_SIGNATURE, ROMBIN_SIG_LEN);	t.type = hdr->type;	t.flags = hdr->flags;	t.osize = HOST_TO_BE32(hdr->osize);	t.csize = HOST_TO_BE32(hdr->csize);	t.ocsum = HOST_TO_BE16(hdr->ocsum);	t.ccsum = HOST_TO_BE16(hdr->ccsum);	t.mmap_addr = HOST_TO_BE32(hdr->mmap_addr);	DBG(2, "hdr.addr      = 0x%08x", hdr->addr);	DBG(2, "hdr.type      = 0x%02x", hdr->type);	DBG(2, "hdr.osize     = 0x%08x", hdr->osize);	DBG(2, "hdr.csize     = 0x%08x", hdr->csize);	DBG(2, "hdr.flags     = 0x%02x", hdr->flags);	DBG(2, "hdr.ocsum     = 0x%04x", hdr->ocsum);	DBG(2, "hdr.ccsum     = 0x%04x", hdr->ccsum);	DBG(2, "hdr.mmap_addr = 0x%08x", hdr->mmap_addr);	return write_out_data(outfile, (uint8_t *)&t, sizeof(t), NULL);}intwrite_out_mmap(FILE *outfile, struct fw_mmap *mmap, struct csum_state *css){	struct zyn_mmt_hdr *mh;	uint8_t buf[MMAP_DATA_SIZE];	uint32_t user_size;	char *data;	int res;	memset(buf, 0, sizeof(buf));	mh = (struct zyn_mmt_hdr *)buf;	/* TODO: needs to recreate the memory map too? */	mh->count=0;	/* Build user data section */	data = buf+sizeof(*mh);	data += sprintf(data, "Vendor 1 %d", board->vendor);	*data++ = '\0';	data += sprintf(data, "Model 1 %d", BE16_TO_HOST(board->model));	*data++ = '\0';	/* TODO: make hardware version configurable? */	data += sprintf(data, "HwVerRange 2 %d %d", 0, 0);	*data++ = '\0';	user_size = (uint8_t *)data - buf;	mh->user_start= HOST_TO_BE32(mmap->addr+sizeof(*mh));	mh->user_end= HOST_TO_BE32(mmap->addr+user_size);	mh->csum = HOST_TO_BE16(csum_buf(buf+sizeof(*mh), user_size));	res = write_out_data(outfile, buf, sizeof(buf), css);	return res;}intblock_stat_file(struct fw_block *block){	struct stat st;	int res;	if (block->file_name == NULL)		return 0;	res = stat(block->file_name, &st);	if (res){		ERRS("stat failed on %s", block->file_name);		return res;	}	block->file_size = st.st_size;	return 0;}intread_magic(uint16_t *magic){	FILE *f;	int res;	errno = 0;	f = fopen(bootext_block->file_name,"r");	if (errno) {		ERRS("unable to open file: %s", bootext_block->file_name);		return -1;	}	errno = 0;	fread(magic, 2, 1, f);	if (errno != 0) {		ERRS("unable to read from file: %s", bootext_block->file_name);		res = -1;		goto err;	}	res = 0;err:	fclose(f);	return res;}intwrite_out_file(FILE *outfile, char *name, size_t len, struct csum_state *css){	char buf[FILE_BUF_LEN];	size_t buflen = sizeof(buf);	FILE *f;	int res;	DBG(2, "writing out file, name=%s, len=%d",		name, len);	errno = 0;	f = fopen(name,"r");	if (errno) {		ERRS("unable to open file: %s", name);		return -1;	}	while (len > 0) {		if (len < buflen)			buflen = len;		/* read data from source file */		errno = 0;		fread(buf, buflen, 1, f);		if (errno != 0) {			ERRS("unable to read from file: %s",name);			res = -1;			break;		}		res = write_out_data(outfile, buf, buflen, css);		if (res)			break;		len -= buflen;	}	fclose(f);	return res;}intwrite_out_block(FILE *outfile, struct fw_block *block, struct csum_state *css){	int res;	if (block == NULL)		return 0;	if (block->file_name == NULL)		return 0;	if (block->file_size == 0)		return 0;	res = write_out_file(outfile, block->file_name,			block->file_size, css);	return res;}intwrite_out_image(FILE *outfile){	struct fw_block *block;	struct fw_mmap mmap;	struct zyn_rombin_hdr hdr;	struct csum_state css;	int i, res;	uint32_t offset;	uint32_t padlen;	uint16_t csum;	uint16_t t;	/* setup header fields */	memset(&hdr, 0, sizeof(hdr));	hdr.addr = board->code_start;	hdr.type = OBJECT_TYPE_BOOTEXT;	hdr.flags = ROMBIN_FLAG_OCSUM;	offset = board->romio_offs;	res = write_out_header(outfile, &hdr);	if (res)		return res;	offset += sizeof(hdr);	csum_init(&css);	res = write_out_block(outfile, bootext_block, &css);	if (res)		return res;	offset += bootext_block->file_size;	if (offset > (board->romio_offs + board->bootext_size)) {		ERR("bootext file '%s' is too big", bootext_block->file_name);		return -1;	}	padlen = ALIGN(offset, MMAP_ALIGN) - offset;	res = write_out_padding(outfile, padlen, 0xFF, &css);	if (res)		return res;	offset += padlen;	mmap.addr = board->flash_base + offset;	res = write_out_mmap(outfile, &mmap, &css);	if (res)		return res;	offset += MMAP_DATA_SIZE;	if ((offset - board->romio_offs) < board->bootext_size) {		padlen = board->romio_offs + board->bootext_size - offset;		res = write_out_padding(outfile, padlen, 0xFF, &css);		if (res)			return res;		offset += padlen;		DBG(2, "bootext end at %08x", offset);	}	for (i = 0; i < num_blocks; i++) {		block = &blocks[i];		if (block->type == BLOCK_TYPE_BOOTEXT)			continue;		padlen = ALIGN(offset, block->align) - offset;		res = write_out_padding(outfile, padlen, 0xFF, &css);		if (res)			return res;		offset += padlen;		res = write_out_block(outfile, block, &css);		if (res)			return res;		offset += block->file_size;	}	padlen = ALIGN(offset, 4) - offset;	res = write_out_padding(outfile, padlen, 0xFF, &css);	if (res)		return res;	offset += padlen;	csum = csum_get(&css);	hdr.mmap_addr = mmap.addr;	hdr.osize = 2;	res = read_magic(&hdr.ocsum);	if (res)		return res;	hdr.ocsum = BE16_TO_HOST(hdr.ocsum);	if (csum <= hdr.ocsum)		t = hdr.ocsum - csum;	else		t = hdr.ocsum - csum - 1;	DBG(2, "ocsum=%04x, csum=%04x, fix=%04x", hdr.ocsum, csum, t);	t = HOST_TO_BE16(t);	res = write_out_data(outfile, (uint8_t *)&t, 2, NULL);	if (res)		return res;	res = write_out_header(outfile, &hdr);	return res;}struct board_info *find_board(char *name){	struct board_info *ret;	struct board_info *board;	ret = NULL;	for (board = boards; board->name != NULL; board++){		if (strcasecmp(name, board->name) == 0) {			ret = board;			break;		}	};	return ret;}intparse_opt_board(char ch, char *arg){	DBG(1,"parsing board option: -%c %s", ch, arg);	if (board != NULL) {		ERR("only one board option allowed");		return -1;	}	if (required_arg(ch, arg))		return -1;	board = find_board(arg);	if (board == NULL){		ERR("invalid/unknown board specified: %s", arg);		return -1;	}	return 0;}intparse_opt_ofname(char ch, char *arg){	if (ofname != NULL) {		ERR("only one output file allowed");		return -1;	}	if (required_arg(ch, arg))		return -1;	ofname = arg;	return 0;}intparse_opt_block(char ch, char *arg){	char buf[MAX_ARG_LEN];	char *argv[MAX_ARG_COUNT];	int argc;	char *p;	struct fw_block *block;	int i;	if ( num_blocks >= MAX_NUM_BLOCKS ) {		ERR("too many blocks specified");		return -1;	}	block = &blocks[num_blocks++];	/* setup default field values */	block->padc = 0xFF;	switch(ch) {	case 'b':		if (bootext_block) {			ERR("only one boot extension block allowed");			break;		}		block->type = BLOCK_TYPE_BOOTEXT;		bootext_block = block;		break;	case 'r':		block->type = BLOCK_TYPE_RAW;		break;	}	argc = parse_arg(arg, buf, argv);	i = 0;	p = argv[i++];	if (is_empty_arg(p)) {		ERR("no file specified in %s", arg);		return -1;	} else {		block->file_name = strdup(p);		if (block->file_name == NULL) {			ERR("not enough memory");			return -1;		}	}	if (block->type == BLOCK_TYPE_BOOTEXT)		return 0;	p = argv[i++];	if (!is_empty_arg(p)) {		if (str2u32(p, &block->align) != 0) {			ERR("invalid block align in %s", arg);			return -1;		}	}	return 0;}intcalc_block_offsets(int type, uint32_t *offset){	struct fw_block *block;	uint32_t next_offs;	uint32_t avail;	int i, res;	DBG(1,"calculating block offsets, starting with %lu",		*offset);	res = 0;	for (i = 0; i < num_blocks; i++) {		block = &blocks[i];		if (block->type != type)			continue;		next_offs = ALIGN(*offset, block->align);		avail = board->flash_size - board->romio_offs - next_offs;		if (next_offs + block->file_size > avail) {			ERR("file %s is too big, offset = %u, size=%u,"				" align = %u", block->file_name,				(unsigned)next_offs,				(unsigned)block->file_size,				(unsigned)block->align);			res = -1;			break;		}		block->padlen = next_offs - *offset;		*offset += block->file_size;	}	return res;}intprocess_blocks(void){	struct fw_block *block;	uint32_t offset;	int i;	int res;	/* collecting file stats */	for (i = 0; i < num_blocks; i++) {		block = &blocks[i];		res = block_stat_file(block);		if (res)			return res;	}	offset = board->romio_offs + bootext_block->file_size;	res = calc_block_offsets(BLOCK_TYPE_RAW, &offset);	return res;}intmain(int argc, char *argv[]){	int optinvalid = 0;   /* flag for invalid option */	int c;	int res = EXIT_FAILURE;	FILE *outfile;	progname=basename(argv[0]);	opterr = 0;  /* could not print standard getopt error messages */	while ( 1 ) {		optinvalid = 0;		c = getopt(argc, argv, "b:B:ho:r:v");		if (c == -1)			break;		switch (c) {		case 'b':		case 'r':			optinvalid = parse_opt_block(c,optarg);			break;		case 'B':			optinvalid = parse_opt_board(c,optarg);			break;		case 'o':			optinvalid = parse_opt_ofname(c,optarg);			break;		case 'v':			verblevel++;			break;		case 'h':			usage(EXIT_SUCCESS);			break;		default:			optinvalid = 1;			break;		}		if (optinvalid != 0 ) {			ERR("invalid option: -%c", optopt);			goto out;		}	}	if (board == NULL) {		ERR("no board specified");		goto out;	}	if (ofname == NULL) {		ERR("no output file specified");		goto out;	}	if (optind < argc) {		ERR("invalid option: %s", argv[optind]);		goto out;	}	if (process_blocks() != 0) {		goto out;	}	outfile = fopen(ofname, "w");	if (outfile == NULL) {		ERRS("could not open \"%s\" for writing", ofname);		goto out;	}	if (write_out_image(outfile) != 0)		goto out_flush;	DBG(1,"Image file %s completed.", ofname);	res = EXIT_SUCCESS;out_flush:	fflush(outfile);	fclose(outfile);	if (res != EXIT_SUCCESS) {		unlink(ofname);	}out:	return res;}

⌨️ 快捷键说明

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