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

📄 cmd_jffs2.c

📁 u-boot-1.1.6 源码包
💻 C
📖 第 1 页 / 共 4 页
字号:
/** * Process all devices and generate corresponding mtdparts string describing * all partitions on all devices. * * @param buf output buffer holding generated mtdparts string (output) * @param buflen buffer size * @return 0 on success, 1 otherwise */static int generate_mtdparts(char *buf, u32 buflen){	struct list_head *pentry, *dentry;	struct mtd_device *dev;	struct part_info *part, *prev_part;	char *p = buf;	char tmpbuf[32];	u32 size, offset, len, part_cnt;	u32 maxlen = buflen - 1;	DEBUGF("--- generate_mtdparts ---\n");	if (list_empty(&devices)) {		buf[0] = '\0';		return 0;	}	sprintf(p, "mtdparts=");	p += 9;	list_for_each(dentry, &devices) {		dev = list_entry(dentry, struct mtd_device, link);		/* copy mtd_id */		len = strlen(dev->id->mtd_id) + 1;		if (len > maxlen)			goto cleanup;		memcpy(p, dev->id->mtd_id, len - 1);		p += len - 1;		*(p++) = ':';		maxlen -= len;		/* format partitions */		prev_part = NULL;		part_cnt = 0;		list_for_each(pentry, &dev->parts) {			part = list_entry(pentry, struct part_info, link);			size = part->size;			offset = part->offset;			part_cnt++;			/* partition size */			memsize_format(tmpbuf, size);			len = strlen(tmpbuf);			if (len > maxlen)				goto cleanup;			memcpy(p, tmpbuf, len);			p += len;			maxlen -= len;			/* add offset only when there is a gap between			 * partitions */			if ((!prev_part && (offset != 0)) ||					(prev_part && ((prev_part->offset + prev_part->size) != part->offset))) {				memsize_format(tmpbuf, offset);				len = strlen(tmpbuf) + 1;				if (len > maxlen)					goto cleanup;				*(p++) = '@';				memcpy(p, tmpbuf, len - 1);				p += len - 1;				maxlen -= len;			}			/* copy name only if user supplied */			if(!part->auto_name) {				len = strlen(part->name) + 2;				if (len > maxlen)					goto cleanup;				*(p++) = '(';				memcpy(p, part->name, len - 2);				p += len - 2;				*(p++) = ')';				maxlen -= len;			}			/* ro mask flag */			if (part->mask_flags && MTD_WRITEABLE_CMD) {				len = 2;				if (len > maxlen)					goto cleanup;				*(p++) = 'r';				*(p++) = 'o';				maxlen -= 2;			}			/* print ',' separator if there are other partitions			 * following */			if (dev->num_parts > part_cnt) {				if (1 > maxlen)					goto cleanup;				*(p++) = ',';				maxlen--;			}			prev_part = part;		}		/* print ';' separator if there are other devices following */		if (dentry->next != &devices) {			if (1 > maxlen)				goto cleanup;			*(p++) = ';';			maxlen--;		}	}	/* we still have at least one char left, as we decremented maxlen at	 * the begining */	*p = '\0';	return 0;cleanup:	last_parts[0] = '\0';	return 1;}/** * Call generate_mtdparts to process all devices and generate corresponding * mtdparts string, save it in mtdparts environment variable. * * @param buf output buffer holding generated mtdparts string (output) * @param buflen buffer size * @return 0 on success, 1 otherwise */static int generate_mtdparts_save(char *buf, u32 buflen){	int ret;	ret = generate_mtdparts(buf, buflen);	if ((buf[0] != '\0') && (ret == 0))		setenv("mtdparts", buf);	else		setenv("mtdparts", NULL);	return ret;}/** * Format and print out a partition list for each device from global device * list. */static void list_partitions(void){	struct list_head *dentry, *pentry;	struct part_info *part;	struct mtd_device *dev;	int part_num;	DEBUGF("\n---list_partitions---\n");	list_for_each(dentry, &devices) {		dev = list_entry(dentry, struct mtd_device, link);		printf("\ndevice %s%d <%s>, # parts = %d\n",				MTD_DEV_TYPE(dev->id->type), dev->id->num,				dev->id->mtd_id, dev->num_parts);		printf(" #: name\t\t\tsize\t\toffset\t\tmask_flags\n");		/* list partitions for given device */		part_num = 0;		list_for_each(pentry, &dev->parts) {			part = list_entry(pentry, struct part_info, link);			printf("%2d: %-20s0x%08x\t0x%08x\t%d\n",					part_num, part->name, part->size,					part->offset, part->mask_flags);			part_num++;		}	}	if (list_empty(&devices))		printf("no partitions defined\n");	/* current_dev is not NULL only when we have non empty device list */	if (current_dev) {		part = jffs2_part_info(current_dev, current_partnum);		if (part) {			printf("\nactive partition: %s%d,%d - (%s) 0x%08lx @ 0x%08lx\n",					MTD_DEV_TYPE(current_dev->id->type),					current_dev->id->num, current_partnum,					part->name, part->size, part->offset);		} else {			printf("could not get current partition info\n\n");		}	}	printf("\ndefaults:\n");	printf("mtdids  : %s\n", mtdids_default);	printf("mtdparts: %s\n", mtdparts_default);}/** * Given partition identifier in form of <dev_type><dev_num>,<part_num> find * corresponding device and verify partition number. * * @param id string describing device and partition or partition name * @param dev pointer to the requested device (output) * @param part_num verified partition number (output) * @param part pointer to requested partition (output) * @return 0 on success, 1 otherwise */int find_dev_and_part(const char *id, struct mtd_device **dev,		u8 *part_num, struct part_info **part){	struct list_head *dentry, *pentry;	u8 type, dnum, pnum;	const char *p;	DEBUGF("--- find_dev_and_part ---\nid = %s\n", id);	list_for_each(dentry, &devices) {		*part_num = 0;		*dev = list_entry(dentry, struct mtd_device, link);		list_for_each(pentry, &(*dev)->parts) {			*part = list_entry(pentry, struct part_info, link);			if (strcmp((*part)->name, id) == 0)				return 0;			(*part_num)++;		}	}	p = id;	*dev = NULL;	*part = NULL;	*part_num = 0;	if (id_parse(p, &p, &type, &dnum) != 0)		return 1;	if ((*p++ != ',') || (*p == '\0')) {		printf("no partition number specified\n");		return 1;	}	pnum = simple_strtoul(p, (char **)&p, 0);	if (*p != '\0') {		printf("unexpected trailing character '%c'\n", *p);		return 1;	}	if ((*dev = device_find(type, dnum)) == NULL) {		printf("no such device %s%d\n", MTD_DEV_TYPE(type), dnum);		return 1;	}	if ((*part = jffs2_part_info(*dev, pnum)) == NULL) {		printf("no such partition\n");		*dev = NULL;		return 1;	}	*part_num = pnum;	return 0;}/** * Find and delete partition. For partition id format see find_dev_and_part(). * * @param id string describing device and partition * @return 0 on success, 1 otherwise */static int delete_partition(const char *id){	u8 pnum;	struct mtd_device *dev;	struct part_info *part;	if (find_dev_and_part(id, &dev, &pnum, &part) == 0) {		DEBUGF("delete_partition: device = %s%d, partition %d = (%s) 0x%08lx@0x%08lx\n",				MTD_DEV_TYPE(dev->id->type), dev->id->num, pnum,				part->name, part->size, part->offset);		if (part_del(dev, part) != 0)			return 1;		if (generate_mtdparts_save(last_parts, MTDPARTS_MAXLEN) != 0) {			printf("generated mtdparts too long, reseting to null\n");			return 1;		}		return 0;	}	printf("partition %s not found\n", id);	return 1;}/** * Accept character string describing mtd partitions and call device_parse() * for each entry. Add created devices to the global devices list. * * @param mtdparts string specifing mtd partitions * @return 0 on success, 1 otherwise */static int parse_mtdparts(const char *const mtdparts){	const char *p = mtdparts;	struct mtd_device *dev;	int err = 1;	DEBUGF("\n---parse_mtdparts---\nmtdparts = %s\n\n", p);	/* delete all devices and partitions */	if (devices_init() != 0) {		printf("could not initialise device list\n");		return err;	}	/* re-read 'mtdparts' variable, devices_init may be updating env */	p = getenv("mtdparts");	if (strncmp(p, "mtdparts=", 9) != 0) {		printf("mtdparts variable doesn't start with 'mtdparts='\n");		return err;	}	p += 9;	while (p && (*p != '\0')) {		err = 1;		if ((device_parse(p, &p, &dev) != 0) || (!dev))			break;		DEBUGF("+ device: %s\t%d\t%s\n", MTD_DEV_TYPE(dev->id->type),				dev->id->num, dev->id->mtd_id);		/* check if parsed device is already on the list */		if (device_find(dev->id->type, dev->id->num) != NULL) {			printf("device %s%d redefined, please correct mtdparts variable\n",					MTD_DEV_TYPE(dev->id->type), dev->id->num);			break;		}		list_add_tail(&dev->link, &devices);		err = 0;	}	if (err == 1) {		device_delall(&devices);		return 1;	}	return 0;}/** * Parse provided string describing mtdids mapping (see file header for mtdids * variable format). Allocate memory for each entry and add all found entries * to the global mtdids list. * * @param ids mapping string * @return 0 on success, 1 otherwise */static int parse_mtdids(const char *const ids){	const char *p = ids;	const char *mtd_id;	int mtd_id_len;	struct mtdids *id;	struct list_head *entry, *n;	struct mtdids *id_tmp;	u8 type, num;	u32 size;	int ret = 1;	DEBUGF("\n---parse_mtdids---\nmtdids = %s\n\n", ids);	/* clean global mtdids list */	list_for_each_safe(entry, n, &mtdids) {		id_tmp = list_entry(entry, struct mtdids, link);		DEBUGF("mtdids del: %d %d\n", id_tmp->type, id_tmp->num);		list_del(entry);		free(id_tmp);	}	last_ids[0] = '\0';	INIT_LIST_HEAD(&mtdids);	while(p && (*p != '\0')) {		ret = 1;		/* parse 'nor'|'nand'<dev-num> */		if (id_parse(p, &p, &type, &num) != 0)			break;		if (*p != '=') {			printf("mtdids: incorrect <dev-num>\n");			break;		}		p++;		/* check if requested device exists */		if (device_validate(type, num, &size) != 0)			return 1;		/* locate <mtd-id> */		mtd_id = p;		if ((p = strchr(mtd_id, ',')) != NULL) {			mtd_id_len = p - mtd_id + 1;			p++;		} else {			mtd_id_len = strlen(mtd_id) + 1;		}		if (mtd_id_len == 0) {			printf("mtdids: no <mtd-id> identifier\n");			break;		}		/* check if this id is already on the list */		int double_entry = 0;		list_for_each(entry, &mtdids) {			id_tmp = list_entry(entry, struct mtdids, link);			if ((id_tmp->type == type) && (id_tmp->num == num)) {				double_entry = 1;				break;			}		}		if (double_entry) {			printf("device id %s%d redefined, please correct mtdids variable\n",					MTD_DEV_TYPE(type), num);			break;		}		/* allocate mtdids structure */		if (!(id = (struct mtdids *)malloc(sizeof(struct mtdids) + mtd_id_len))) {			printf("out of memory\n");			break;		}		memset(id, 0, sizeof(struct mtdids) + mtd_id_len);		id->num = num;		id->type = type;		id->size = size;		id->mtd_id = (char *)(id + 1);		strncpy(id->mtd_id, mtd_id, mtd_id_len - 1);		id->mtd_id[mtd_id_len - 1] = '\0';		INIT_LIST_HEAD(&id->link);		DEBUGF("+ id %s%d\t%16d bytes\t%s\n",				MTD_DEV_TYPE(id->type), id->num,				id->size, id->mtd_id);		list_add_tail(&id->link, &mtdids);		ret = 0;	}	if (ret == 1) {		/* clean mtdids list and free allocated memory */		list_for_each_safe(entry, n, &mtdids) {			id_tmp = list_entry(entry, struct mtdids, link);			list_del(entry);			free(id_tmp);		}		return 1;	}	return 0;}/** * Parse and initialize global mtdids mapping and create global * device/partition list. * * @return 0 on success, 1 otherwise */int mtdparts_init(void){	static int initialized = 0;	const char *ids, *parts;	const char *current_partition;	int ids_changed;	char tmp_ep[PARTITION_MAXLEN];	DEBUGF("\n---mtdparts_init---\n");	if (!initialized) {		INIT_LIST_HEAD(&mtdids);		INIT_LIST_HEAD(&devices);		memset(last_ids, 0, MTDIDS_MAXLEN);		memset(last_parts, 0, MTDPARTS_MAXLEN);		memset(last_partition, 0, PARTITION_MAXLEN);		initialized = 1;	}	/* get variables */	ids = getenv("mtdids");	parts = getenv("mtdparts");	current_partition = getenv("partition");	/* save it for later parsing, cannot rely on current partition pointer	 * as 'partition' variable may be updated during init */	tmp_ep[0] = '\0';	if (current_partition)		strncpy(tmp_ep, current_partition, PARTITION_MAXLEN);	DEBUGF("last_ids  : %s\n", last_ids);	DEBUGF("env_ids   : %s\n", ids);	DEBUGF("last_parts: %s\n", last_parts);	DEBUGF("env_parts : %s\n\n", parts);	DEBUGF("last_partition : %s\n", last_partition);	DEBUGF("env_partition  : %s\n", current_partition);	/* if mtdids varible is empty try to use defaults */	if (!ids) {		if (mtdids_default) {			DEBUGF("mtdids variable not defined, using default\n");			ids = mtdids_default;			setenv("mtdids", (char *)ids);		} else {			printf("mtdids not defined, no default present\n");			return 1;		}	}	if (strlen(ids) > MTDIDS_MAXLEN - 1) {		printf("mtdids too long (> %d)\n", MTDIDS_MAXLEN);		return 1;	}	/* do no try to use defaults when mtdparts variable is not defined,	 * just check the length */	if (!parts)		printf("mtdparts variable not set, see 'help mtdparts'\n");	if (parts && (strlen(parts) > MTDPARTS_MAXLEN - 1)) {		printf("mtdparts too long (> %d)\n", MTDPARTS_MAXLEN);		return 1;	}	/* check if we have already parsed those mtdids */	if ((last_ids[0] != '\0') && (strcmp(last_ids, ids) == 0)) {		ids_changed = 0;	} else {		ids_changed = 1;		if (parse_mtdids(ids) != 0) {			devices_init();			return 1;		}		/* ok it's good, save new ids */		strncpy(last_ids, ids, MTDIDS_MAXLEN);	}	/* parse partitions if either mtdparts or mtdids were updated */	if (parts && ((last_parts[0] == '\0') || ((strcmp(last_parts, parts) != 0)) || ids_changed)) {

⌨️ 快捷键说明

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