diff --git a/common/mtdpart.c b/common/mtdpart.c index 60c426d..788aeda 100644 --- a/common/mtdpart.c +++ b/common/mtdpart.c @@ -5,17 +5,7 @@ #include #include #include - -struct partition { - int num; - - unsigned long offset; - - struct device_d *parent; - struct device_d device; - - char name[16]; -}; +#include static void dev_del_partitions(struct device_d *dev) { diff --git a/fs/Kconfig b/fs/Kconfig new file mode 100644 index 0000000..f12b081 --- /dev/null +++ b/fs/Kconfig @@ -0,0 +1,12 @@ + +menuconfig FS + bool "Filesystem support" + +if FS + +config FS_CRAMFS + bool + select ZLIB + prompt "cramfs support" + +endif diff --git a/fs/Makefile b/fs/Makefile index 273d90e..ceb38fc 100644 --- a/fs/Makefile +++ b/fs/Makefile @@ -1,29 +1,2 @@ -# -# (C) Copyright 2000-2006 -# Wolfgang Denk, DENX Software Engineering, wd@denx.de. -# -# See file CREDITS for list of people who contributed to this -# project. -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License as -# published by the Free Software Foundation; either version 2 of -# the License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, -# MA 02111-1307 USA -# -# - -SUBDIRS := jffs2 cramfs fdos fat reiserfs ext2 - -$(obj).depend all: - @for dir in $(SUBDIRS) ; do \ - $(MAKE) -C $$dir $@ ; done +obj-$(CONFIG_FS_CRAMFS) += cramfs/ +obj-$(CONFIG_FS) += fs.o diff --git a/fs/cramfs/Makefile b/fs/cramfs/Makefile index 13c043f..4e84a98 100644 --- a/fs/cramfs/Makefile +++ b/fs/cramfs/Makefile @@ -1,49 +1,2 @@ -# -# (C) Copyright 2000-2006 -# Wolfgang Denk, DENX Software Engineering, wd@denx.de. -# -# See file CREDITS for list of people who contributed to this -# project. -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License as -# published by the Free Software Foundation; either version 2 of -# the License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, -# MA 02111-1307 USA -# - -include $(TOPDIR)/config.mk - -LIB = $(obj)libcramfs.a - -AOBJS = -COBJS = cramfs.o uncompress.o - -SRCS := $(AOBJS:.o=.S) $(COBJS:.o=.c) -OBJS := $(addprefix $(obj),$(AOBJS) $(COBJS)) - -#CPPFLAGS += - -all: $(LIB) $(AOBJS) - -$(LIB): $(obj).depend $(OBJS) - $(AR) $(ARFLAGS) $@ $(OBJS) - - -######################################################################### - -# defines $(obj).depend target -include $(SRCTREE)/rules.mk - -sinclude $(obj).depend - -######################################################################### +obj-y += cramfs.o +obj-y += uncompress.o diff --git a/fs/cramfs/cramfs.c b/fs/cramfs/cramfs.c index 48e7f63..a5f5a58 100644 --- a/fs/cramfs/cramfs.c +++ b/fs/cramfs/cramfs.c @@ -26,8 +26,10 @@ #include #include - -#if (CONFIG_COMMANDS & CFG_CMD_JFFS2) +#include +#include +#include +#include #include #include @@ -42,22 +44,22 @@ struct cramfs_super super; -/* CPU address space offset calculation macro, struct part_info offset is - * device address space offset, so we need to shift it by a device start address. */ -extern flash_info_t flash_info[]; -#define PART_OFFSET(x) (x->offset + flash_info[x->dev->id->num].start[0]) - -static int cramfs_read_super (struct part_info *info) +static int cramfs_read_super (struct device_d *dev) { unsigned long root_offset; - /* Read the first block and get the superblock from it */ - memcpy (&super, (void *) PART_OFFSET(info), sizeof (super)); + if (read(dev, &super, sizeof (super), 0, 0) < sizeof (super)) { + printf("read superblock failed\n"); + return -EINVAL; + } /* Do sanity checks on the superblock */ if (super.magic != CRAMFS_32 (CRAMFS_MAGIC)) { /* check at 512 byte offset */ - memcpy (&super, (void *) PART_OFFSET(info) + 512, sizeof (super)); + if (read(dev, &super, sizeof (super), 512, 0) < sizeof (super)) { + printf("read superblock failed\n"); + return -EINVAL; + } if (super.magic != CRAMFS_32 (CRAMFS_MAGIC)) { printf ("cramfs: wrong magic\n"); return -1; @@ -185,29 +187,32 @@ return total_size; } -int cramfs_load (char *loadoffset, struct part_info *info, char *filename) +int cramfs_load (char *loadoffset, struct device_d *dev, const char *filename) { unsigned long offset; - - if (cramfs_read_super (info)) + char *f; + if (cramfs_read_super (dev)) return -1; - offset = cramfs_resolve (PART_OFFSET(info), + f = strdup(filename); + offset = cramfs_resolve (dev->map_base, CRAMFS_GET_OFFSET (&(super.root)) << 2, CRAMFS_24 (super.root.size), 0, - strtok (filename, "/")); + strtok (f, "/")); + + free(f); if (offset <= 0) return offset; - return cramfs_uncompress (PART_OFFSET(info), offset, + return cramfs_uncompress (dev->map_base, offset, (unsigned long) loadoffset); } -static int cramfs_list_inode (struct part_info *info, unsigned long offset) +static int cramfs_list_inode (struct device_d *dev, unsigned long offset) { struct cramfs_inode *inode = (struct cramfs_inode *) - (PART_OFFSET(info) + offset); + (dev->map_base + offset); char *name, str[20]; int namelen, nextoff; @@ -238,7 +243,7 @@ unsigned long size = CRAMFS_24 (inode->size); char *link = malloc (size); - if (link != NULL && cramfs_uncompress (PART_OFFSET(info), offset, + if (link != NULL && cramfs_uncompress (dev->map_base, offset, (unsigned long) link) == size) printf (" -> %*.*s\n", (int) size, (int) size, link); @@ -252,13 +257,16 @@ return nextoff; } -int cramfs_ls (struct part_info *info, char *filename) +int cramfs_ls (struct device_d *dev, const char *filename) { struct cramfs_inode *inode; unsigned long inodeoffset = 0, nextoffset; unsigned long offset, size; + char *f; - if (cramfs_read_super (info)) + printf("cramfs_ls: %s\n", filename); + + if (cramfs_read_super (dev)) return -1; if (strlen (filename) == 0 || !strcmp (filename, "/")) { @@ -266,20 +274,21 @@ offset = CRAMFS_GET_OFFSET (&(super.root)) << 2; size = CRAMFS_24 (super.root.size); } else { + f = strdup(filename); /* Resolve the path */ - offset = cramfs_resolve (PART_OFFSET(info), + offset = cramfs_resolve (dev->map_base, CRAMFS_GET_OFFSET (&(super.root)) << 2, CRAMFS_24 (super.root.size), 1, - strtok (filename, "/")); - + strtok (f, "/")); + free(f); if (offset <= 0) return offset; /* Resolving was successful. Examine the inode */ - inode = (struct cramfs_inode *) (PART_OFFSET(info) + offset); + inode = (struct cramfs_inode *) (dev->map_base + offset); if (!S_ISDIR (CRAMFS_16 (inode->mode))) { /* It's not a directory - list it, and that's that */ - return (cramfs_list_inode (info, offset) > 0); + return (cramfs_list_inode (dev, offset) > 0); } /* It's a directory. List files within */ @@ -289,21 +298,21 @@ /* List the given directory */ while (inodeoffset < size) { - inode = (struct cramfs_inode *) (PART_OFFSET(info) + offset + + inode = (struct cramfs_inode *) (dev->map_base + offset + inodeoffset); - nextoffset = cramfs_list_inode (info, offset + inodeoffset); + nextoffset = cramfs_list_inode (dev, offset + inodeoffset); if (nextoffset == 0) break; inodeoffset += sizeof (struct cramfs_inode) + nextoffset; } - return 1; + return 0; } -int cramfs_info (struct part_info *info) +int cramfs_info (struct device_d *dev) { - if (cramfs_read_super (info)) + if (cramfs_read_super (dev)) return 0; printf ("size: 0x%x (%u)\n", super.size, super.size); @@ -327,21 +336,30 @@ return 1; } -int cramfs_check (struct part_info *info) +int cramfs_probe(struct device_d *dev) { - struct cramfs_super *sb; - - if (info->dev->id->type != MTD_DEV_TYPE_NOR) - return 0; - - sb = (struct cramfs_super *) PART_OFFSET(info); - if (sb->magic != CRAMFS_32 (CRAMFS_MAGIC)) { - /* check at 512 byte offset */ - sb = (struct cramfs_super *) (PART_OFFSET(info) + 512); - if (sb->magic != CRAMFS_32 (CRAMFS_MAGIC)) - return 0; + if (cramfs_read_super (dev)) { + printf("no valid cramfs found on %s\n",dev->id); + return -EINVAL; } - return 1; + + return 0; } -#endif /* CFG_FS_CRAMFS */ +static struct fs_driver_d cramfs_driver = { + .type = FS_TYPE_CRAMFS, + .probe = cramfs_probe, + .ls = cramfs_ls, + .drv = { + .type = DEVICE_TYPE_FS, + .name = "cramfs", + .driver_data = &cramfs_driver, + } +}; + +int cramfs_init(void) +{ + return register_fs_driver(&cramfs_driver); +} + +device_initcall(cramfs_init); diff --git a/fs/cramfs/uncompress.c b/fs/cramfs/uncompress.c index 170832a..659869b 100644 --- a/fs/cramfs/uncompress.c +++ b/fs/cramfs/uncompress.c @@ -25,8 +25,6 @@ #include #include -#if (CONFIG_COMMANDS & CFG_CMD_JFFS2) - static z_stream stream; #define ZALLOC_ALIGNMENT 16 @@ -102,5 +100,3 @@ inflateEnd (&stream); return 0; } - -#endif /* CFG_FS_CRAMFS */ diff --git a/fs/fs.c b/fs/fs.c new file mode 100644 index 0000000..824645b --- /dev/null +++ b/fs/fs.c @@ -0,0 +1,163 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +char *mkmodestr(unsigned long mode, char *str) +{ + static const char *l = "xwr"; + int mask = 1, i; + char c; + + switch (mode & S_IFMT) { + case S_IFDIR: str[0] = 'd'; break; + case S_IFBLK: str[0] = 'b'; break; + case S_IFCHR: str[0] = 'c'; break; + case S_IFIFO: str[0] = 'f'; break; + case S_IFLNK: str[0] = 'l'; break; + case S_IFSOCK: str[0] = 's'; break; + case S_IFREG: str[0] = '-'; break; + default: str[0] = '?'; + } + + for(i = 0; i < 9; i++) { + c = l[i%3]; + str[9-i] = (mode & mask)?c:'-'; + mask = mask<<1; + } + + if(mode & S_ISUID) str[3] = (mode & S_IXUSR)?'s':'S'; + if(mode & S_ISGID) str[6] = (mode & S_IXGRP)?'s':'S'; + if(mode & S_ISVTX) str[9] = (mode & S_IXOTH)?'t':'T'; + str[10] = '\0'; + return str; +} + +static int fs_probe(struct device_d *dev) +{ + struct fs_device_d *fs_dev = dev->platform_data; + + return fs_dev->driver->probe(fs_dev->parent); +} + +int register_fs_driver(struct fs_driver_d *new_fs_drv) +{ + new_fs_drv->drv.probe = fs_probe; + new_fs_drv->drv.driver_data = new_fs_drv; + + return register_driver(&new_fs_drv->drv); +} + +int register_filesystem(struct device_d *dev, char *fsname) +{ + struct fs_device_d *new_fs_dev; + struct driver_d *drv; + struct fs_driver_d *fs_drv; + + drv = get_driver_by_name(fsname); + if (!drv) { + printf("no driver for fstype %s\n", fsname); + return -EINVAL; + } + + if (drv->type != DEVICE_TYPE_FS) { + printf("driver %s is no filesystem driver\n"); + return -EINVAL; + } + + new_fs_dev = malloc(sizeof(struct fs_device_d)); + + fs_drv = drv->driver_data; + + new_fs_dev->driver = fs_drv; + new_fs_dev->parent = dev; + new_fs_dev->dev.platform_data = new_fs_dev; + new_fs_dev->dev.type = DEVICE_TYPE_FS; + sprintf(new_fs_dev->dev.name, "%s", fsname); + sprintf(new_fs_dev->dev.id, "%s", "fs0"); + + register_device(&new_fs_dev->dev); + + if (!new_fs_dev->dev.driver) { + unregister_device(&new_fs_dev->dev); + return -ENODEV; + } + + return 0; +} + +int ls(struct device_d *dev, const char *filename) +{ + struct fs_device_d *fs_dev; + + if (!dev || dev->type != DEVICE_TYPE_FS || !dev->driver) + return -ENODEV; + + fs_dev = dev->platform_data; + + return fs_dev->driver->ls(fs_dev->parent, filename); +} + +/* addfs */ +int do_addfs ( cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +{ + struct device_d *dev; + int ret = 0; + + if (argc != 3) { + printf ("Usage:\n%s\n", cmdtp->usage); + return 1; + } + + dev = get_device_by_id(argv[1]); + if (!dev) { + printf("no such device: %s\n", argv[1]); + return -ENODEV; + } + + if ((ret = register_filesystem(dev, argv[2]))) { + perror("register_device", ret); + return 1; + } + return 0; +} + +int do_ls ( cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +{ + struct device_d *dev; + char *endp; + int ret; + + dev = device_from_spec_str(argv[1], &endp); + + ret = ls(dev, endp); + if (ret) { + perror("ls", ret); + return 1; + } + + return 0; +} + +U_BOOT_CMD( + ls, 2, 0, do_ls, + "ls - list a file or directory\n", + " list files on device" +); + +U_BOOT_CMD( + addfs, 3, 0, do_addfs, + "addfs - add a filesystem to a device\n", + " add a filesystem of type 'type' on the given device" +); +#if 0 +U_BOOT_CMD( + delfs, 2, 0, do_delfs, + "delfs - delete a filesystem from a device\n", + "" +); +#endif