Skip to content
Snippets Groups Projects
cmd_jffs2.c 57.8 KiB
Newer Older
  • Learn to ignore specific revisions
  • /***************************************************/
    /* 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[])
    
    Wolfgang Denk's avatar
    Wolfgang Denk committed
    {
    
    	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";
    	}
    
    
    Wolfgang Denk's avatar
    Wolfgang Denk committed
    	if (argc == 2) {
    		filename = argv[1];
    	}
    	if (argc == 3) {
    		offset = simple_strtoul(argv[1], NULL, 16);
    
    		load_addr = offset;
    
    Wolfgang Denk's avatar
    Wolfgang Denk committed
    		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))){
    
    Wolfgang Denk's avatar
    Wolfgang Denk committed
    
    
    		/* 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);
    		}
    
    Wolfgang Denk's avatar
    Wolfgang Denk committed
    
    		if (size > 0) {
    			char buf[10];
    
    			printf("### %s load complete: %d bytes loaded to 0x%lx\n",
    				fsname, size, offset);
    
    Wolfgang Denk's avatar
    Wolfgang Denk committed
    			sprintf(buf, "%x", size);
    			setenv("filesize", buf);
    		} else {
    
    			printf("### %s LOAD ERROR<%x> for %s!\n", fsname, size, filename);
    
    Wolfgang Denk's avatar
    Wolfgang Denk committed
    		}
    
    		return !(size > 0);
    	}
    
    /**
     * 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[])
    
    Wolfgang Denk's avatar
    Wolfgang Denk committed
    {
    
    	char *filename = "/";
    
    Wolfgang Denk's avatar
    Wolfgang Denk committed
    	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))){
    
    Wolfgang Denk's avatar
    Wolfgang Denk committed
    
    
    		/* 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);
    		}
    
    Wolfgang Denk's avatar
    Wolfgang Denk committed
    
    
    Wolfgang Denk's avatar
    Wolfgang Denk committed
    	}
    
    /**
     * 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[])
    
    Wolfgang Denk's avatar
    Wolfgang Denk committed
    {
    	struct part_info *part;
    
    	char *fsname;
    
    Wolfgang Denk's avatar
    Wolfgang Denk committed
    
    
    	/* 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);
    
    Wolfgang Denk's avatar
    Wolfgang Denk committed
    
    
    		if (cramfs_check(part)) {
    			ret = cramfs_info (part);
    		} else {
    
    			/* if this is not cramfs assume jffs2 */
    
    			ret = jffs2_1pass_info(part);
    		}
    
    Wolfgang Denk's avatar
    Wolfgang Denk committed
    
    
    Wolfgang Denk's avatar
    Wolfgang Denk committed
    	}
    
    /* 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[])
    
    Wolfgang Denk's avatar
    Wolfgang Denk committed
    {
    
    /* command line only */
    	struct mtd_device *dev;
    	struct part_info *part;
    	u8 pnum;
    
    Wolfgang Denk's avatar
    Wolfgang Denk committed
    
    
    	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);
    
    Wolfgang Denk's avatar
    Wolfgang Denk committed
    
    
    			/* jffs2_devices_init() calls current_save() */
    			return jffs2_devices_init();
    
    	/* make sure we are in sync with env variables */
    	if (mtdparts_init() != 0)
    		return 1;
    
    	if (argc == 1) {
    		list_partitions();
    
    Wolfgang Denk's avatar
    Wolfgang Denk committed
    		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;
    
    Wolfgang Denk's avatar
    Wolfgang Denk committed
    
    
    		if (id_parse(argv[2], NULL, &type, &num) != 0)
    			return 1;
    
    Wolfgang Denk's avatar
    Wolfgang Denk committed
    
    
    		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' */
    
    Wolfgang Denk's avatar
    Wolfgang Denk committed
    
    
    		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;
    
    Wolfgang Denk's avatar
    Wolfgang Denk committed
    
    
    		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]);
    	}
    
    
    	return 1;
    }
    #endif /* #ifdef CONFIG_JFFS2_CMDLINE */
    
    /***************************************************/
    
    U_BOOT_CMD(
    	fsload,	3,	0,	do_jffs2_fsload,
    
    Peter Tyser's avatar
    Peter Tyser committed
    	"load binary file from a filesystem image",
    
    Wolfgang Denk's avatar
    Wolfgang Denk committed
    	"[ off ] [ filename ]\n"
    	"    - load binary file from flash bank\n"
    	"      with offset 'off'\n"
    );
    
    Peter Tyser's avatar
    Peter Tyser committed
    	"list files in a directory (default /)",
    
    	"[ directory ]\n"
    	"    - list files in a directory.\n"
    );
    
    Wolfgang Denk's avatar
    Wolfgang Denk committed
    
    
    U_BOOT_CMD(
    	fsinfo,	1,	1,	do_jffs2_fsinfo,
    
    Peter Tyser's avatar
    Peter Tyser committed
    	"print information about filesystems",
    
    Wolfgang Denk's avatar
    Wolfgang Denk committed
    	"    - print information about filesystems\n"
    );
    
    
    Peter Tyser's avatar
    Peter Tyser committed
    	"change active partition",
    
    	"part-id\n"
    	"    - change active partition (e.g. part-id = nand0,1)\n"
    );
    
    U_BOOT_CMD(
    	mtdparts,	6,	0,	do_jffs2_mtdparts,
    
    Peter Tyser's avatar
    Peter Tyser committed
    	"define flash/nand partitions",
    
    	"\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'|'onenand'<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"
    
    Wolfgang Denk's avatar
    Wolfgang Denk committed
    );
    
    #endif /* #ifdef CONFIG_JFFS2_CMDLINE */
    
    /***************************************************/