📄 cmd_jffs2.c
字号:
if (parse_mtdparts(parts) != 0) return 1; if (list_empty(&devices)) { printf("mtdparts_init: no valid partitions\n"); return 1; } /* ok it's good, save new parts */ strncpy(last_parts, parts, MTDPARTS_MAXLEN); /* reset first partition from first dev from the list as current */ current_dev = list_entry(devices.next, struct mtd_device, link); current_partnum = 0; current_save(); DEBUGF("mtdparts_init: current_dev = %s%d, current_partnum = %d\n", MTD_DEV_TYPE(current_dev->id->type), current_dev->id->num, current_partnum); } /* mtdparts variable was reset to NULL, delete all devices/partitions */ if (!parts && (last_parts[0] != '\0')) return devices_init(); /* do not process current partition if mtdparts variable is null */ if (!parts) return 0; /* is current partition set in environment? if so, use it */ if ((tmp_ep[0] != '\0') && (strcmp(tmp_ep, last_partition) != 0)) { struct part_info *p; struct mtd_device *cdev; u8 pnum; DEBUGF("--- getting current partition: %s\n", tmp_ep); if (find_dev_and_part(tmp_ep, &cdev, &pnum, &p) == 0) { current_dev = cdev; current_partnum = pnum; current_save(); } } else if (getenv("partition") == NULL) { DEBUGF("no partition variable set, setting...\n"); current_save(); } return 0;}#else /* #ifdef CONFIG_JFFS2_CMDLINE *//* * 'Static' version of command line mtdparts_init() routine. Single partition on * a single device configuration. *//** * 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; u32 size; char *dev_name; DEBUGF("\n---mtdparts_init---\n"); if (!initialized) { struct mtdids *id; struct part_info *part; initialized = 1; current_dev = (struct mtd_device *) malloc(sizeof(struct mtd_device) + sizeof(struct part_info) + sizeof(struct mtdids)); if (!current_dev) { printf("out of memory\n"); return 1; } memset(current_dev, 0, sizeof(struct mtd_device) + sizeof(struct part_info) + sizeof(struct mtdids)); id = (struct mtdids *)(current_dev + 1); part = (struct part_info *)(id + 1); /* id */ id->mtd_id = "single part";#if defined(CONFIG_JFFS2_DEV) dev_name = CONFIG_JFFS2_DEV;#else dev_name = "nor0";#endif if ((id_parse(dev_name, NULL, &id->type, &id->num) != 0) || (device_validate(id->type, id->num, &size) != 0)) { printf("incorrect device: %s%d\n", MTD_DEV_TYPE(id->type), id->num); free(current_dev); return 1; } id->size = size; INIT_LIST_HEAD(&id->link); DEBUGF("dev id: type = %d, num = %d, size = 0x%08lx, mtd_id = %s\n", id->type, id->num, id->size, id->mtd_id); /* partition */ part->name = "static"; part->auto_name = 0;#if defined(CONFIG_JFFS2_PART_SIZE) part->size = CONFIG_JFFS2_PART_SIZE;#else part->size = SIZE_REMAINING;#endif#if defined(CONFIG_JFFS2_PART_OFFSET) part->offset = CONFIG_JFFS2_PART_OFFSET;#else part->offset = 0x00000000;#endif part->dev = current_dev; INIT_LIST_HEAD(&part->link); /* recalculate size if needed */ if (part->size == SIZE_REMAINING) part->size = id->size - part->offset; DEBUGF("part : name = %s, size = 0x%08lx, offset = 0x%08lx\n", part->name, part->size, part->offset); /* device */ current_dev->id = id; INIT_LIST_HEAD(¤t_dev->link); current_dev->num_parts = 1; INIT_LIST_HEAD(¤t_dev->parts); list_add(&part->link, ¤t_dev->parts); } return 0;}#endif /* #ifdef CONFIG_JFFS2_CMDLINE *//** * Return pointer to the partition of a requested number from a requested * device. * * @param dev device that is to be searched for a partition * @param part_num requested partition number * @return pointer to the part_info, NULL otherwise */static struct part_info* jffs2_part_info(struct mtd_device *dev, unsigned int part_num){ struct list_head *entry; struct part_info *part; int num; if (!dev) return NULL; DEBUGF("\n--- jffs2_part_info: partition number %d for device %s%d (%s)\n", part_num, MTD_DEV_TYPE(dev->id->type), dev->id->num, dev->id->mtd_id); if (part_num >= dev->num_parts) { printf("invalid partition number %d for device %s%d (%s)\n", part_num, MTD_DEV_TYPE(dev->id->type), dev->id->num, dev->id->mtd_id); return NULL; } /* locate partition number, return it */ num = 0; list_for_each(entry, &dev->parts) { part = list_entry(entry, struct part_info, link); if (part_num == num++) { return part; } } return NULL;}/***************************************************//* U-boot commands *//***************************************************//** * Routine implementing fsload u-boot command. This routine tries to load * a requested file from jffs2/cramfs filesystem on a current partition. * * @param cmdtp command internal data * @param flag command flag * @param argc number of arguments supplied to the command * @param argv arguments list * @return 0 on success, 1 otherwise */int do_jffs2_fsload(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]){ char *fsname; char *filename; int size; struct part_info *part; ulong offset = load_addr; /* pre-set Boot file name */ if ((filename = getenv("bootfile")) == NULL) { filename = "uImage"; } if (argc == 2) { filename = argv[1]; } if (argc == 3) { offset = simple_strtoul(argv[1], NULL, 16); load_addr = offset; filename = argv[2]; } /* make sure we are in sync with env variables */ if (mtdparts_init() !=0) return 1; if ((part = jffs2_part_info(current_dev, current_partnum))){ /* check partition type for cramfs */ fsname = (cramfs_check(part) ? "CRAMFS" : "JFFS2"); printf("### %s loading '%s' to 0x%lx\n", fsname, filename, offset); if (cramfs_check(part)) { size = cramfs_load ((char *) offset, part, filename); } else { /* if this is not cramfs assume jffs2 */ size = jffs2_1pass_load((char *)offset, part, filename); } if (size > 0) { char buf[10]; printf("### %s load complete: %d bytes loaded to 0x%lx\n", fsname, size, offset); sprintf(buf, "%x", size); setenv("filesize", buf); } else { printf("### %s LOAD ERROR<%x> for %s!\n", fsname, size, filename); } return !(size > 0); } return 1;}/** * Routine implementing u-boot ls command which lists content of a given * directory on a current partition. * * @param cmdtp command internal data * @param flag command flag * @param argc number of arguments supplied to the command * @param argv arguments list * @return 0 on success, 1 otherwise */int do_jffs2_ls(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]){ char *filename = "/"; int ret; struct part_info *part; if (argc == 2) filename = argv[1]; /* make sure we are in sync with env variables */ if (mtdparts_init() !=0) return 1; if ((part = jffs2_part_info(current_dev, current_partnum))){ /* check partition type for cramfs */ if (cramfs_check(part)) { ret = cramfs_ls (part, filename); } else { /* if this is not cramfs assume jffs2 */ ret = jffs2_1pass_ls(part, filename); } return ret ? 0 : 1; } return 1;}/** * Routine implementing u-boot fsinfo command. This routine prints out * miscellaneous filesystem informations/statistics. * * @param cmdtp command internal data * @param flag command flag * @param argc number of arguments supplied to the command * @param argv arguments list * @return 0 on success, 1 otherwise */int do_jffs2_fsinfo(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]){ struct part_info *part; char *fsname; int ret; /* make sure we are in sync with env variables */ if (mtdparts_init() !=0) return 1; if ((part = jffs2_part_info(current_dev, current_partnum))){ /* check partition type for cramfs */ fsname = (cramfs_check(part) ? "CRAMFS" : "JFFS2"); printf("### filesystem type is %s\n", fsname); if (cramfs_check(part)) { ret = cramfs_info (part); } else { /* if this is not cramfs assume jffs2 */ ret = jffs2_1pass_info(part); } return ret ? 0 : 1; } return 1;}/* command line only */#ifdef CONFIG_JFFS2_CMDLINE/** * Routine implementing u-boot chpart command. Sets new current partition based * on the user supplied partition id. For partition id format see find_dev_and_part(). * * @param cmdtp command internal data * @param flag command flag * @param argc number of arguments supplied to the command * @param argv arguments list * @return 0 on success, 1 otherwise */int do_jffs2_chpart(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]){/* command line only */ struct mtd_device *dev; struct part_info *part; u8 pnum; if (mtdparts_init() !=0) return 1; if (argc < 2) { printf("no partition id specified\n"); return 1; } if (find_dev_and_part(argv[1], &dev, &pnum, &part) != 0) return 1; current_dev = dev; current_partnum = pnum; current_save(); printf("partition changed to %s%d,%d\n", MTD_DEV_TYPE(dev->id->type), dev->id->num, pnum); return 0;}/** * Routine implementing u-boot mtdparts command. Initialize/update default global * partition list and process user partition request (list, add, del). * * @param cmdtp command internal data * @param flag command flag * @param argc number of arguments supplied to the command * @param argv arguments list * @return 0 on success, 1 otherwise */int do_jffs2_mtdparts(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]){ if (argc == 2) { if (strcmp(argv[1], "default") == 0) { setenv("mtdids", (char *)mtdids_default); setenv("mtdparts", (char *)mtdparts_default); setenv("partition", NULL); mtdparts_init(); return 0; } else if (strcmp(argv[1], "delall") == 0) { /* this may be the first run, initialize lists if needed */ mtdparts_init(); setenv("mtdparts", NULL); /* devices_init() calls current_save() */ return devices_init(); } } /* make sure we are in sync with env variables */ if (mtdparts_init() != 0) return 1; if (argc == 1) { list_partitions(); return 0; } /* mtdparts add <mtd-dev> <size>[@<offset>] <name> [ro] */ if (((argc == 5) || (argc == 6)) && (strcmp(argv[1], "add") == 0)) {#define PART_ADD_DESC_MAXLEN 64 char tmpbuf[PART_ADD_DESC_MAXLEN]; u8 type, num, len; struct mtd_device *dev; struct mtd_device *dev_tmp; struct mtdids *id; struct part_info *p; if (id_parse(argv[2], NULL, &type, &num) != 0) return 1; if ((id = id_find(type, num)) == NULL) { printf("no such device %s defined in mtdids variable\n", argv[2]); return 1; } len = strlen(id->mtd_id) + 1; /* 'mtd_id:' */ len += strlen(argv[3]); /* size@offset */ len += strlen(argv[4]) + 2; /* '(' name ')' */ if (argv[5] && (strlen(argv[5]) == 2)) len += 2; /* 'ro' */ if (len >= PART_ADD_DESC_MAXLEN) { printf("too long partition description\n"); return 1; } sprintf(tmpbuf, "%s:%s(%s)%s", id->mtd_id, argv[3], argv[4], argv[5] ? argv[5] : ""); DEBUGF("add tmpbuf: %s\n", tmpbuf); if ((device_parse(tmpbuf, NULL, &dev) != 0) || (!dev)) return 1; DEBUGF("+ %s\t%d\t%s\n", MTD_DEV_TYPE(dev->id->type), dev->id->num, dev->id->mtd_id); if ((dev_tmp = device_find(dev->id->type, dev->id->num)) == NULL) { device_add(dev); } else { /* merge new partition with existing ones*/ p = list_entry(dev->parts.next, struct part_info, link); if (part_add(dev_tmp, p) != 0) { device_del(dev); return 1; } } if (generate_mtdparts_save(last_parts, MTDPARTS_MAXLEN) != 0) { printf("generated mtdparts too long, reseting to null\n"); return 1; } return 0; } /* mtdparts del part-id */ if ((argc == 3) && (strcmp(argv[1], "del") == 0)) { DEBUGF("del: part-id = %s\n", argv[2]); return delete_partition(argv[2]); } printf ("Usage:\n%s\n", cmdtp->usage); return 1;}#endif /* #ifdef CONFIG_JFFS2_CMDLINE *//***************************************************/U_BOOT_CMD( fsload, 3, 0, do_jffs2_fsload, "fsload\t- load binary file from a filesystem image\n", "[ off ] [ filename ]\n" " - load binary file from flash bank\n" " with offset 'off'\n");U_BOOT_CMD( ls, 2, 1, do_jffs2_ls, "ls\t- list files in a directory (default /)\n", "[ directory ]\n" " - list files in a directory.\n");U_BOOT_CMD( fsinfo, 1, 1, do_jffs2_fsinfo, "fsinfo\t- print information about filesystems\n", " - print information about filesystems\n");#ifdef CONFIG_JFFS2_CMDLINEU_BOOT_CMD( chpart, 2, 0, do_jffs2_chpart, "chpart\t- change active partition\n", "part-id\n" " - change active partition (e.g. part-id = nand0,1)\n");U_BOOT_CMD( mtdparts, 6, 0, do_jffs2_mtdparts, "mtdparts- define flash/nand partitions\n", "\n" " - list partition table\n" "mtdparts delall\n" " - delete all partitions\n" "mtdparts del part-id\n" " - delete partition (e.g. part-id = nand0,1)\n" "mtdparts add <mtd-dev> <size>[@<offset>] [<name>] [ro]\n" " - add partition\n" "mtdparts default\n" " - reset partition table to defaults\n\n" "-----\n\n" "this command uses three environment variables:\n\n" "'partition' - keeps current partition identifier\n\n" "partition := <part-id>\n" "<part-id> := <dev-id>,part_num\n\n" "'mtdids' - linux kernel mtd device id <-> u-boot device id mapping\n\n" "mtdids=<idmap>[,<idmap>,...]\n\n" "<idmap> := <dev-id>=<mtd-id>\n" "<dev-id> := 'nand'|'nor'<dev-num>\n" "<dev-num> := mtd device number, 0...\n" "<mtd-id> := unique device tag used by linux kernel to find mtd device (mtd->name)\n\n" "'mtdparts' - partition list\n\n" "mtdparts=mtdparts=<mtd-def>[;<mtd-def>...]\n\n" "<mtd-def> := <mtd-id>:<part-def>[,<part-def>...]\n" "<mtd-id> := unique device tag used by linux kernel to find mtd device (mtd->name)\n" "<part-def> := <size>[@<offset>][<name>][<ro-flag>]\n" "<size> := standard linux memsize OR '-' to denote all remaining space\n" "<offset> := partition start offset within the device\n" "<name> := '(' NAME ')'\n" "<ro-flag> := when set to 'ro' makes partition read-only (not used, passed to kernel)\n");#endif /* #ifdef CONFIG_JFFS2_CMDLINE *//***************************************************/#endif /* CFG_CMD_JFFS2 */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -