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

📄 jffs2_1pass.c

📁 F:worksip2440a board可启动u-boot-like.tar.gz F:worksip2440a board可启动u-boot-like.tar.gz
💻 C
📖 第 1 页 / 共 3 页
字号:
			version = jDir->version;		}		put_fl_mem(jDir);	}	/* now we found the right entry again. (shoulda returned inode*) */	if (jDirFoundType != DT_LNK)		return jDirFoundIno;	/* it's a soft link so we follow it again. */	b2 = pL->frag.listHead;	while (b2) {		jNode = (struct jffs2_raw_inode *) get_node_mem(b2->offset);		if (jNode->ino == jDirFoundIno) {			src = (unsigned char *)jNode + sizeof(struct jffs2_raw_inode);#if 0			putLabeledWord("\t\t dsize = ", jNode->dsize);			putstr("\t\t target = ");			putnstr(src, jNode->dsize);			putstr("\r\n");#endif			strncpy(tmp, src, jNode->dsize);			tmp[jNode->dsize] = '\0';			put_fl_mem(jNode);			break;		}		b2 = b2->next;		put_fl_mem(jNode);	}	/* ok so the name of the new file to find is in tmp */	/* if it starts with a slash it is root based else shared dirs */	if (tmp[0] == '/')		pino = 1;	else		pino = jDirFoundPino;	return jffs2_1pass_search_inode(pL, tmp, pino);}static u32jffs2_1pass_search_list_inodes(struct b_lists * pL, const char *fname, u32 pino){	int i;	char tmp[256];	char working_tmp[256];	char *c;	/* discard any leading slash */	i = 0;	while (fname[i] == '/')		i++;	strcpy(tmp, &fname[i]);	working_tmp[0] = '\0';	while ((c = (char *) strchr(tmp, '/')))	/* we are still dired searching */	{		strncpy(working_tmp, tmp, c - tmp);		working_tmp[c - tmp] = '\0';		for (i = 0; i < strlen(c) - 1; i++)			tmp[i] = c[i + 1];		tmp[i] = '\0';		/* only a failure if we arent looking at top level */		if (!(pino = jffs2_1pass_find_inode(pL, working_tmp, pino)) &&		    (working_tmp[0])) {			putstr("find_inode failed for name=");			putstr(working_tmp);			putstr("\r\n");			return 0;		}	}	if (tmp[0] && !(pino = jffs2_1pass_find_inode(pL, tmp, pino))) {		putstr("find_inode failed for name=");		putstr(tmp);		putstr("\r\n");		return 0;	}	/* this is for the bare filename, directories have already been mapped */	if (!(pino = jffs2_1pass_list_inodes(pL, pino))) {		putstr("find_inode failed for name=");		putstr(tmp);		putstr("\r\n");		return 0;	}	return pino;}unsigned charjffs2_1pass_rescan_needed(struct part_info *part){	struct b_node *b;	struct jffs2_unknown_node onode;	struct jffs2_unknown_node *node;	struct b_lists *pL = (struct b_lists *)part->jffs2_priv;	if (part->jffs2_priv == 0){		DEBUGF ("rescan: First time in use\n");		return 1;	}	/* if we have no list, we need to rescan */	if (pL->frag.listCount == 0) {		DEBUGF ("rescan: fraglist zero\n");		return 1;	}	/* or if we are scanning a new partition */	if (pL->partOffset != part->offset) {		DEBUGF ("rescan: different partition\n");		return 1;	}#if defined(CONFIG_JFFS2_NAND) && (CONFIG_COMMANDS & CFG_CMD_NAND)	if (nanddev != (int)part->usr_priv - 1) {		DEBUGF ("rescan: nand device changed\n");		return -1;	}#endif /* defined(CONFIG_JFFS2_NAND) && (CONFIG_COMMANDS & CFG_CMD_NAND) */	/* but suppose someone reflashed a partition at the same offset... */	b = pL->dir.listHead;	while (b) {		node = (struct jffs2_unknown_node *) get_fl_mem(b->offset,			sizeof(onode), &onode);		if (node->nodetype != JFFS2_NODETYPE_DIRENT) {			DEBUGF ("rescan: fs changed beneath me? (%lx)\n",					(unsigned long) b->offset);			return 1;		}		b = b->next;	}	return 0;}#ifdef DEBUG_FRAGMENTSstatic voiddump_fragments(struct b_lists *pL){	struct b_node *b;	struct jffs2_raw_inode ojNode;	struct jffs2_raw_inode *jNode;	putstr("\r\n\r\n******The fragment Entries******\r\n");	b = pL->frag.listHead;	while (b) {		jNode = (struct jffs2_raw_inode *) get_fl_mem(b->offset,			sizeof(ojNode), &ojNode);		putLabeledWord("\r\n\tbuild_list: FLASH_OFFSET = ", b->offset);		putLabeledWord("\tbuild_list: totlen = ", jNode->totlen);		putLabeledWord("\tbuild_list: inode = ", jNode->ino);		putLabeledWord("\tbuild_list: version = ", jNode->version);		putLabeledWord("\tbuild_list: isize = ", jNode->isize);		putLabeledWord("\tbuild_list: atime = ", jNode->atime);		putLabeledWord("\tbuild_list: offset = ", jNode->offset);		putLabeledWord("\tbuild_list: csize = ", jNode->csize);		putLabeledWord("\tbuild_list: dsize = ", jNode->dsize);		putLabeledWord("\tbuild_list: compr = ", jNode->compr);		putLabeledWord("\tbuild_list: usercompr = ", jNode->usercompr);		putLabeledWord("\tbuild_list: flags = ", jNode->flags);		putLabeledWord("\tbuild_list: offset = ", b->offset);	/* FIXME: ? [RS] */		b = b->next;	}}#endif#ifdef DEBUG_DIRENTSstatic voiddump_dirents(struct b_lists *pL){	struct b_node *b;	struct jffs2_raw_dirent *jDir;	putstr("\r\n\r\n******The directory Entries******\r\n");	b = pL->dir.listHead;	while (b) {		jDir = (struct jffs2_raw_dirent *) get_node_mem(b->offset);		putstr("\r\n");		putnstr(jDir->name, jDir->nsize);		putLabeledWord("\r\n\tbuild_list: magic = ", jDir->magic);		putLabeledWord("\tbuild_list: nodetype = ", jDir->nodetype);		putLabeledWord("\tbuild_list: hdr_crc = ", jDir->hdr_crc);		putLabeledWord("\tbuild_list: pino = ", jDir->pino);		putLabeledWord("\tbuild_list: version = ", jDir->version);		putLabeledWord("\tbuild_list: ino = ", jDir->ino);		putLabeledWord("\tbuild_list: mctime = ", jDir->mctime);		putLabeledWord("\tbuild_list: nsize = ", jDir->nsize);		putLabeledWord("\tbuild_list: type = ", jDir->type);		putLabeledWord("\tbuild_list: node_crc = ", jDir->node_crc);		putLabeledWord("\tbuild_list: name_crc = ", jDir->name_crc);		putLabeledWord("\tbuild_list: offset = ", b->offset); 	/* FIXME: ? [RS] */		b = b->next;		put_fl_mem(jDir);	}}#endifstatic u32jffs2_1pass_build_lists(struct part_info * part){	struct b_lists *pL;	struct jffs2_unknown_node *node;	u32 offset, oldoffset = 0;	u32 max = part->size - sizeof(struct jffs2_raw_inode);	u32 counter = 0;	u32 counter4 = 0;	u32 counterF = 0;	u32 counterN = 0;#if defined(CONFIG_JFFS2_NAND) && (CONFIG_COMMANDS & CFG_CMD_NAND)	nanddev = (int)part->usr_priv - 1;#endif /* defined(CONFIG_JFFS2_NAND) && (CONFIG_COMMANDS & CFG_CMD_NAND) */	/* turn off the lcd.  Refreshing the lcd adds 50% overhead to the */	/* jffs2 list building enterprise nope.  in newer versions the overhead is */	/* only about 5 %.  not enough to inconvenience people for. */	/* lcd_off(); */	/* if we are building a list we need to refresh the cache. */	jffs_init_1pass_list(part);	pL = (struct b_lists *)part->jffs2_priv;	pL->partOffset = part->offset;	offset = 0;	puts ("Scanning JFFS2 FS:   ");	/* start at the beginning of the partition */	while (offset < max) {	    	if ((oldoffset >> SPIN_BLKSIZE) != (offset >> SPIN_BLKSIZE)) {			printf("\b\b%c ", spinner[counter++ % sizeof(spinner)]);			oldoffset = offset;		}		node = (struct jffs2_unknown_node *) get_node_mem((u32)part->offset + offset);		if (node->magic == JFFS2_MAGIC_BITMASK && hdr_crc(node)) {			/* if its a fragment add it */			if (node->nodetype == JFFS2_NODETYPE_INODE &&				    inode_crc((struct jffs2_raw_inode *) node)) {				if (insert_node(&pL->frag, (u32) part->offset +						offset) == NULL) {					put_fl_mem(node);					return 0;				}			} else if (node->nodetype == JFFS2_NODETYPE_DIRENT &&				   dirent_crc((struct jffs2_raw_dirent *) node)  &&				   dirent_name_crc((struct jffs2_raw_dirent *) node)) {				if (! (counterN%100))					puts ("\b\b.  ");				if (insert_node(&pL->dir, (u32) part->offset +						offset) == NULL) {					put_fl_mem(node);					return 0;				}				counterN++;			} else if (node->nodetype == JFFS2_NODETYPE_CLEANMARKER) {				if (node->totlen != sizeof(struct jffs2_unknown_node))					printf("OOPS Cleanmarker has bad size "						"%d != %d\n", node->totlen,						sizeof(struct jffs2_unknown_node));			} else if (node->nodetype == JFFS2_NODETYPE_PADDING) {				if (node->totlen < sizeof(struct jffs2_unknown_node))					printf("OOPS Padding has bad size "						"%d < %d\n", node->totlen,						sizeof(struct jffs2_unknown_node));			} else {				printf("Unknown node type: %x len %d "					"offset 0x%x\n", node->nodetype,					node->totlen, offset);			}			offset += ((node->totlen + 3) & ~3);			counterF++;		} else if (node->magic == JFFS2_EMPTY_BITMASK &&			   node->nodetype == JFFS2_EMPTY_BITMASK) {			offset = jffs2_scan_empty(offset, part);		} else {	/* if we know nothing, we just step and look. */			offset += 4;			counter4++;		}/*             printf("unknown node magic %4.4x %4.4x @ %lx\n", node->magic, node->nodetype, (unsigned long)node); */		put_fl_mem(node);	}	putstr("\b\b done.\r\n");		/* close off the dots */	/* turn the lcd back on. */	/* splash(); */#if 0	putLabeledWord("dir entries = ", pL->dir.listCount);	putLabeledWord("frag entries = ", pL->frag.listCount);	putLabeledWord("+4 increments = ", counter4);	putLabeledWord("+file_offset increments = ", counterF);#endif#ifdef DEBUG_DIRENTS	dump_dirents(pL);#endif#ifdef DEBUG_FRAGMENTS	dump_fragments(pL);#endif	/* give visual feedback that we are done scanning the flash */	led_blink(0x0, 0x0, 0x1, 0x1);	/* off, forever, on 100ms, off 100ms */	return 1;}static u32jffs2_1pass_fill_info(struct b_lists * pL, struct b_jffs2_info * piL){	struct b_node *b;	struct jffs2_raw_inode ojNode;	struct jffs2_raw_inode *jNode;	int i;	for (i = 0; i < JFFS2_NUM_COMPR; i++) {		piL->compr_info[i].num_frags = 0;		piL->compr_info[i].compr_sum = 0;		piL->compr_info[i].decompr_sum = 0;	}	b = pL->frag.listHead;	while (b) {		jNode = (struct jffs2_raw_inode *) get_fl_mem(b->offset,			sizeof(ojNode), &ojNode);		if (jNode->compr < JFFS2_NUM_COMPR) {			piL->compr_info[jNode->compr].num_frags++;			piL->compr_info[jNode->compr].compr_sum += jNode->csize;			piL->compr_info[jNode->compr].decompr_sum += jNode->dsize;		}		b = b->next;	}	return 0;}static struct b_lists *jffs2_get_list(struct part_info * part, const char *who){	if (jffs2_1pass_rescan_needed(part)) {		if (!jffs2_1pass_build_lists(part)) {			printf("%s: Failed to scan JFFSv2 file structure\n", who);			return NULL;		}	}	return (struct b_lists *)part->jffs2_priv;}/* Print directory / file contents */u32jffs2_1pass_ls(struct part_info * part, const char *fname){	struct b_lists *pl;	long ret = 0;	u32 inode;	if (! (pl = jffs2_get_list(part, "ls")))		return 0;	if (! (inode = jffs2_1pass_search_list_inodes(pl, fname, 1))) {		putstr("ls: Failed to scan jffs2 file structure\r\n");		return 0;	}#if 0	putLabeledWord("found file at inode = ", inode);	putLabeledWord("read_inode returns = ", ret);#endif	return ret;}/* Load a file from flash into memory. fname can be a full path */u32jffs2_1pass_load(char *dest, struct part_info * part, const char *fname){	struct b_lists *pl;	long ret = 0;	u32 inode;	if (! (pl  = jffs2_get_list(part, "load")))		return 0;	if (! (inode = jffs2_1pass_search_inode(pl, fname, 1))) {		putstr("load: Failed to find inode\r\n");		return 0;	}	/* Resolve symlinks */	if (! (inode = jffs2_1pass_resolve_inode(pl, inode))) {		putstr("load: Failed to resolve inode structure\r\n");		return 0;	}	if ((ret = jffs2_1pass_read_inode(pl, inode, dest)) < 0) {		putstr("load: Failed to read inode\r\n");		return 0;	}	DEBUGF ("load: loaded '%s' to 0x%lx (%ld bytes)\n", fname,				(unsigned long) dest, ret);	return ret;}/* Return information about the fs on this partition */u32jffs2_1pass_info(struct part_info * part){	struct b_jffs2_info info;	struct b_lists *pl;	int i;	if (! (pl  = jffs2_get_list(part, "info")))		return 0;	jffs2_1pass_fill_info(pl, &info);	for (i = 0; i < JFFS2_NUM_COMPR; i++) {		printf ("Compression: %s\n"			"\tfrag count: %d\n"			"\tcompressed sum: %d\n"			"\tuncompressed sum: %d\n",			compr_names[i],			info.compr_info[i].num_frags,			info.compr_info[i].compr_sum,			info.compr_info[i].decompr_sum);	}	return 1;}#endif /* CFG_CMD_JFFS2 */

⌨️ 快捷键说明

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