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

📄 jffs2_1pass.c

📁 ARM的bootloader代码.rar
💻 C
📖 第 1 页 / 共 2 页
字号:
static u32jffs2_1pass_search_inode(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]);	while ((c = (char *) strchr(tmp, '/')))	// we are still dired searching	{		strncpy(working_tmp, tmp, c - tmp);		working_tmp[c - tmp] = '\0';#if 0		putstr("search_inode: tmp = ");		putstr(tmp);		putstr("\r\n");		putstr("search_inode: wtmp = ");		putstr(working_tmp);		putstr("\r\n");		putstr("search_inode: c = ");		putstr(c);		putstr("\r\n");#endif		for (i = 0; i < strlen(c) - 1; i++)			tmp[i] = c[i + 1];		tmp[i] = '\0';#if 0		putstr("search_inode: post tmp = ");		putstr(tmp);		putstr("\r\n");#endif		if (!(pino = jffs2_1pass_find_inode(pL, working_tmp, pino))) {			putstr("find_inode failed for name=");			putstr(working_tmp);			putstr("\r\n");			return 0;		}	}	// this is for the bare filename, directories have already been mapped	if (!(pino = jffs2_1pass_find_inode(pL, tmp, pino))) {		putstr("find_inode failed for name=");		putstr(tmp);		putstr("\r\n");		return 0;	}	return pino;}static u32jffs2_1pass_resolve_inode(struct b_lists * pL, u32 ino){	struct b_node *b;	struct b_node *b2;	struct jffs2_raw_dirent *jDir;	struct jffs2_raw_inode *jNode;	struct jffs2_raw_dirent *jDirFound = NULL;	char tmp[256];	u32 version = 0;	u32 pino;	unsigned char *src;	// we need to search all and return the inode with the highest version	for(b = pL->dirListHead; b; b=b->next) {		jDir = (struct jffs2_raw_dirent *) (b->offset);		if (ino == jDir->ino) {		    	if(jDir->version < version) continue;			if(jDir->version == 0) {			    	/* Is this legal? */				putstr(" ** WARNING ** ");				putnstr(jDir->name, jDir->nsize);				putstr(" is version 0 (in resolve, ignoring)\r\n");			} else if(jDir->version == version) {			    	/* Im pretty sure this isn't ... */				putstr(" ** ERROR ** ");				putnstr(jDir->name, jDir->nsize);				putLabeledWord(" has dup version (resolve) = ",					version);			}			jDirFound = jDir;			version = jDir->version;		}	}	// now we found the right entry again. (shoulda returned inode*)	if (jDirFound->type != DT_LNK)		return jDirFound->ino;	// so its a soft link so we follow it again.	b2 = pL->fragListHead;	while (b2) {		jNode = (struct jffs2_raw_inode *) (b2->offset);		if (jNode->ino == jDirFound->ino) {			src = (unsigned char *) (b2->offset + 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';			break;		}		b2 = b2->next;	}	// 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 = jDirFound->pino;	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_lists *pL){	unsigned char ret = 0;	struct b_node *b;	struct jffs2_unknown_node *node;	// if we have no list, we need to rescan	if (pL->fragListCount == 0) {		DEBUGF ("rescan: fraglist zero\n");		return 1;	}	// or if we are scanninga new partition	if (pL->partOffset != part->offset) {		DEBUGF ("rescan: different partition\n");		return 1;	}	// but suppose someone reflashed the root partition at the same offset...	b = pL->dirListHead;	while (b) {		node = (struct jffs2_unknown_node *) (b->offset);		if (node->nodetype != JFFS2_NODETYPE_DIRENT) {			DEBUGF ("rescan: fs changed beneath me? (%lx)\n", (unsigned long) b->offset);			return 1;		}		b = b->next;	}	return ret;}static u32jffs2_1pass_build_lists(struct part_info * part, struct b_lists * pL){	struct jffs2_unknown_node *node;	u32 offset;	u32 max = part->size - sizeof(struct jffs2_raw_inode);	u32 counter = 0;	u32 counter4 = 0;	u32 counterF = 0;	u32 counterN = 0;	// 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.	// note that since we don't free our memory, eventually this will be bad.	// but we're a bootldr so what the hell.	jffs_init_1pass_list();	pL->partOffset = part->offset;	offset = 0;	printf("Scanning JFFS2 FS:   ");	/* start at the beginning of the partition */	while (offset < max) {	    	if (! (++counter%10000))			printf("\b\b%c ", spinner[(counter / 10000) % 4]);		node = (struct jffs2_unknown_node *) (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 (!(pL->fragListTail = add_node(pL->fragListTail, &(pL->fragListCount),								  &(pL->fragListMemBase)))) {					putstr("add_node failed!\r\n");					return 0;				}				pL->fragListTail->offset = (u32) (part->offset + offset);				if (!pL->fragListHead)					pL->fragListHead = pL->fragListTail;			} 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))					printf("\b\b.  ");#if 0				printf("Found DIRENT @ 0x%lx\n", offset);				putstr("\r\nbuild_lists:p&l ->");				putnstr(((struct jffs2_raw_dirent *) node)->name, ((struct jffs2_raw_dirent *) node)->nsize);				putstr("\r\n");				putLabeledWord("\tpino = ", ((struct jffs2_raw_dirent *) node)->pino);				putLabeledWord("\tnsize = ", ((struct jffs2_raw_dirent *) node)->nsize);#endif				if (!(pL->dirListTail = add_node(pL->dirListTail, &(pL->dirListCount), &(pL->dirListMemBase)))) {					putstr("add_node failed!\r\n");					return 0;				}				pL->dirListTail->offset = (u32) (part->offset + offset);#if 0				putLabeledWord("\ttail = ", (u32) pL->dirListTail);				putstr("\ttailName ->");				putnstr(((struct jffs2_raw_dirent *) (pL->dirListTail->offset))->name,					((struct jffs2_raw_dirent *) (pL->dirListTail->offset))->nsize);				putstr("\r\n");#endif				if (!pL->dirListHead)					pL->dirListHead = pL->dirListTail;				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 {				printf("Unknown node type: %x len %d offset 0x%lx\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 of the filesystem, 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);	}	putstr("\b\b done.\r\n");		// close off the dots	// turn the lcd back on.	// splash();#if 0	putLabeledWord("dir entries = ", pL->dirListCount);	putLabeledWord("frag entries = ", pL->fragListCount);	putLabeledWord("+4 increments = ", counter4);	putLabeledWord("+file_offset increments = ", counterF);#endif#undef SHOW_ALL#undef SHOW_ALL_FRAGMENTS#ifdef SHOW_ALL	{		struct b_node *b;		struct b_node *b2;		struct jffs2_raw_dirent *jDir;		struct jffs2_raw_inode *jNode;		putstr("\r\n\r\n******The directory Entries******\r\n");		b = pL->dirListHead;		while (b) {			jDir = (struct jffs2_raw_dirent *) (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);			b = b->next;		}#ifdef SHOW_ALL_FRAGMENTS		putstr("\r\n\r\n******The fragment Entries******\r\n");		b = pL->fragListHead;		while (b) {			jNode = (struct jffs2_raw_inode *) (b->offset);			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);			b = b->next;		}#endif /* SHOW_ALL_FRAGMENTS */	}#endif	/* SHOW_ALL */	// 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 *jNode;	int i;	b = pL->fragListHead;	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;	}	while (b) {		jNode = (struct jffs2_raw_inode *) (b->offset);		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){	struct b_lists *pl = &g_1PassList;	if (jffs2_1pass_rescan_needed(part, pl)) {		if (!jffs2_1pass_build_lists(part, pl)) {			printf("%s: Failed to scan JFFSv2 file structure\n", who);			return NULL;		}	}	return pl;}/* 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 = &g_1PassList;	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", compr_names[i]);		printf("\tfrag count: %ld\n", info.compr_info[i].num_frags);		printf("\tcompressed sum: %ld\n", info.compr_info[i].compr_sum);		printf("\tuncompressed sum: %ld\n", info.compr_info[i].decompr_sum);	}	return 1;}#endif /* CFG_CMD_JFFS2 */

⌨️ 快捷键说明

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