parent
79bd10153a
commit
0ed157cd19
|
@ -5,17 +5,7 @@
|
|||
#include <driver.h>
|
||||
#include <malloc.h>
|
||||
#include <asm-generic/errno.h>
|
||||
|
||||
struct partition {
|
||||
int num;
|
||||
|
||||
unsigned long offset;
|
||||
|
||||
struct device_d *parent;
|
||||
struct device_d device;
|
||||
|
||||
char name[16];
|
||||
};
|
||||
#include <partition.h>
|
||||
|
||||
static void dev_del_partitions(struct device_d *dev)
|
||||
{
|
||||
|
|
|
@ -0,0 +1,12 @@
|
|||
|
||||
menuconfig FS
|
||||
bool "Filesystem support"
|
||||
|
||||
if FS
|
||||
|
||||
config FS_CRAMFS
|
||||
bool
|
||||
select ZLIB
|
||||
prompt "cramfs support"
|
||||
|
||||
endif
|
31
fs/Makefile
31
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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -26,8 +26,10 @@
|
|||
|
||||
#include <common.h>
|
||||
#include <malloc.h>
|
||||
|
||||
#if (CONFIG_COMMANDS & CFG_CMD_JFFS2)
|
||||
#include <driver.h>
|
||||
#include <init.h>
|
||||
#include <asm-generic/errno.h>
|
||||
#include <fs.h>
|
||||
|
||||
#include <asm/byteorder.h>
|
||||
#include <linux/stat.h>
|
||||
|
@ -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 @@ static int cramfs_uncompress (unsigned long begin, unsigned long offset,
|
|||
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 @@ static int cramfs_list_inode (struct part_info *info, unsigned long offset)
|
|||
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 @@ static int cramfs_list_inode (struct part_info *info, unsigned long offset)
|
|||
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 @@ int cramfs_ls (struct part_info *info, char *filename)
|
|||
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 @@ int cramfs_ls (struct part_info *info, char *filename)
|
|||
|
||||
/* 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 @@ int cramfs_info (struct part_info *info)
|
|||
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);
|
||||
|
|
|
@ -25,8 +25,6 @@
|
|||
#include <watchdog.h>
|
||||
#include <zlib.h>
|
||||
|
||||
#if (CONFIG_COMMANDS & CFG_CMD_JFFS2)
|
||||
|
||||
static z_stream stream;
|
||||
|
||||
#define ZALLOC_ALIGNMENT 16
|
||||
|
@ -102,5 +100,3 @@ int cramfs_uncompress_exit (void)
|
|||
inflateEnd (&stream);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* CFG_FS_CRAMFS */
|
||||
|
|
|
@ -0,0 +1,163 @@
|
|||
#include <common.h>
|
||||
#include <command.h>
|
||||
#include <fs.h>
|
||||
#include <driver.h>
|
||||
#include <errno.h>
|
||||
#include <asm-generic/errno.h>
|
||||
#include <malloc.h>
|
||||
#include <linux/stat.h>
|
||||
|
||||
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 <device> <fstype> */
|
||||
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",
|
||||
"<dev:path> list files on device"
|
||||
);
|
||||
|
||||
U_BOOT_CMD(
|
||||
addfs, 3, 0, do_addfs,
|
||||
"addfs - add a filesystem to a device\n",
|
||||
" <device> <type> 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
|
Loading…
Reference in New Issue