]> git.kernelconcepts.de Git - karo-tx-uboot.git/commitdiff
[FS] Added support for ROMFS
authorMichal Simek <monstr@monstr.eu>
Sat, 14 Jul 2007 10:41:23 +0000 (12:41 +0200)
committerMichal Simek <monstr@monstr.eu>
Sat, 14 Jul 2007 10:41:23 +0000 (12:41 +0200)
Makefile
common/cmd_jffs2.c
fs/Makefile
fs/romfs/Makefile [new file with mode: 0644]
fs/romfs/romfs.c [new file with mode: 0644]

index bfa38460daefaa52c96d42b745b85255b273df37..2d2a68535beb09a1d3a1e79c5bc16404a9a34de8 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -199,7 +199,7 @@ LIBS += cpu/ixp/npe/libnpe.a
 endif
 LIBS += lib_$(ARCH)/lib$(ARCH).a
 LIBS += fs/cramfs/libcramfs.a fs/fat/libfat.a fs/fdos/libfdos.a fs/jffs2/libjffs2.a \
-       fs/reiserfs/libreiserfs.a fs/ext2/libext2fs.a
+       fs/reiserfs/libreiserfs.a fs/ext2/libext2fs.a fs/romfs/libromfs.a
 LIBS += net/libnet.a
 LIBS += disk/libdisk.a
 LIBS += rtc/librtc.a
@@ -316,14 +316,14 @@ depend dep:
 tags ctags:
                ctags -w -o $(OBJTREE)/ctags `find $(SUBDIRS) include \
                                lib_generic board/$(BOARDDIR) cpu/$(CPU) lib_$(ARCH) \
-                               fs/cramfs fs/fat fs/fdos fs/jffs2 \
+                               fs/cramfs fs/fat fs/fdos fs/jffs2 fs/romfs\
                                net disk rtc dtt drivers drivers/sk98lin common \
                        \( -name CVS -prune \) -o \( -name '*.[ch]' -print \)`
 
 etags:
                etags -a -o $(OBJTREE)/etags `find $(SUBDIRS) include \
                                lib_generic board/$(BOARDDIR) cpu/$(CPU) lib_$(ARCH) \
-                               fs/cramfs fs/fat fs/fdos fs/jffs2 \
+                               fs/cramfs fs/fat fs/fdos fs/jffs2 fs/romfs\
                                net disk rtc dtt drivers drivers/sk98lin common \
                        \( -name CVS -prune \) -o \( -name '*.[ch]' -print \)`
 
index 7fd1fa33daf2fbccf21880e6d53f0904af8c30cd..147ab109665fb5f9c3ccf65ef74ffd2f711f120a 100644 (file)
@@ -28,7 +28,7 @@
  *
  * 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
+ * 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
@@ -85,7 +85,7 @@
  */
 
 /*
- * JFFS2/CRAMFS support
+ * JFFS2/CRAMFS/ROMFS support
  */
 #include <common.h>
 #include <command.h>
 #define        DEBUG_JFFS
 #undef DEBUG_JFFS
 
-#ifdef  DEBUG_JFFS
+#ifdef DEBUG_JFFS
 # define DEBUGF(fmt, args...)  printf(fmt ,##args)
 #else
 # define DEBUGF(fmt, args...)
@@ -175,6 +175,11 @@ extern int cramfs_load (char *loadoffset, struct part_info *info, char *filename
 extern int cramfs_ls (struct part_info *info, char *filename);
 extern int cramfs_info (struct part_info *info);
 
+extern int romfs_check (struct part_info *info);
+extern int romfs_load (char *loadoffset, struct part_info *info, char *filename);
+extern int romfs_ls (struct part_info *info, char *filename);
+extern int romfs_info (struct part_info *info);
+
 static struct part_info* jffs2_part_info(struct mtd_device *dev, unsigned int part_num);
 
 /* command line only routines */
@@ -184,10 +189,10 @@ static struct mtdids* id_find_by_mtd_id(const char *mtd_id, unsigned int mtd_id_
 static int device_del(struct mtd_device *dev);
 
 /**
- * Parses a string into a number.  The number stored at ptr is
+ * Parses a string into a number. The number stored at ptr is
  * potentially suffixed with K (for kilobytes, or 1024 bytes),
  * M (for megabytes, or 1048576 bytes), or G (for gigabytes, or
- * 1073741824).  If the number is suffixed with K, M, or G, then
+ * 1073741824). If the number is suffixed with K, M, or G, then
  * the return value is the number multiplied by one kilobyte, one
  * megabyte, or one gigabyte, respectively.
  *
@@ -676,7 +681,7 @@ static int part_parse(const char *const partdef, const char **ret, struct part_i
                return 1;
        }
 
-       /*  allocate memory */
+       /* allocate memory */
        part = (struct part_info *)malloc(sizeof(struct part_info) + name_len);
        if (!part) {
                printf("out of memory\n");
@@ -1832,9 +1837,9 @@ static struct part_info* jffs2_part_info(struct mtd_device *dev, unsigned int pa
        return NULL;
 }
 
-/***************************************************/
-/* U-boot commands                                */
-/***************************************************/
+/*************************************************/
+/* U-boot commands                              */
+/*************************************************/
 
 /**
  * Routine implementing fsload u-boot command. This routine tries to load
@@ -1874,14 +1879,22 @@ int do_jffs2_fsload(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
 
        if ((part = jffs2_part_info(current_dev, current_partnum))){
 
-               /* check partition type for cramfs */
-               fsname = (cramfs_check(part) ? "CRAMFS" : "JFFS2");
+               /* check partition type for JFFS2, cramfs, romfs */
+               if (cramfs_check(part)) {
+                       fsname = "CRAMFS";
+               } else if (romfs_check(part)) {
+                       fsname = "ROMFS";
+               } else {
+                       fsname = "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 (romfs_check(part)){
+                       size = romfs_load ((char *) offset, part, filename);
                } else {
-                       /* if this is not cramfs assume jffs2 */
+                       /* if this is not cramfs or romfs assume jffs2 */
                        size = jffs2_1pass_load((char *)offset, part, filename);
                }
 
@@ -1928,8 +1941,10 @@ int do_jffs2_ls(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
                /* check partition type for cramfs */
                if (cramfs_check(part)) {
                        ret = cramfs_ls (part, filename);
+               } else if (romfs_check(part)) {
+                       ret = romfs_ls (part, filename);
                } else {
-                       /* if this is not cramfs assume jffs2 */
+                       /* if this is not cramfs or romfs assume jffs2 */
                        ret = jffs2_1pass_ls(part, filename);
                }
 
@@ -1951,7 +1966,6 @@ int do_jffs2_ls(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
 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 */
@@ -1961,13 +1975,17 @@ int do_jffs2_fsinfo(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
        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);
+               puts("### filesystem type is ");
 
                if (cramfs_check(part)) {
+                       puts("CRAMFS\n");
                        ret = cramfs_info (part);
+               } else if (romfs_check(part)) {
+                       puts("ROMFS\n");
+                       ret = romfs_info (part);
                } else {
-                       /* if this is not cramfs assume jffs2 */
+                       /* if this is not cramfs or romfs assume jffs2 */
+                       puts("JFFS2\n");
                        ret = jffs2_1pass_info(part);
                }
 
index 273d90e011b90afc1d32ca706abc21e11913a67a..118ae78f2d37d46f0f56f48763a7cc9aa88b59b9 100644 (file)
@@ -22,7 +22,7 @@
 #
 #
 
-SUBDIRS        := jffs2 cramfs fdos fat reiserfs ext2
+SUBDIRS        := romfs jffs2 cramfs fdos fat reiserfs ext2
 
 $(obj).depend all:
        @for dir in $(SUBDIRS) ; do \
diff --git a/fs/romfs/Makefile b/fs/romfs/Makefile
new file mode 100644 (file)
index 0000000..937d755
--- /dev/null
@@ -0,0 +1,49 @@
+#
+# (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)libromfs.a
+
+AOBJS  =
+COBJS  = romfs.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
+
+#########################################################################
diff --git a/fs/romfs/romfs.c b/fs/romfs/romfs.c
new file mode 100644 (file)
index 0000000..b7d9696
--- /dev/null
@@ -0,0 +1,270 @@
+/*
+ * (C) Copyright 2007 Michal Simek
+ *
+ * Michal SIMEK <monstr@monstr.eu>
+ *
+ * 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 <common.h>
+#include <malloc.h>
+#include <command.h>
+
+#if (CONFIG_COMMANDS & CFG_CMD_JFFS2)
+
+#include <asm/byteorder.h>
+#include <linux/stat.h>
+#include <jffs2/jffs2.h>
+#include <jffs2/load_kernel.h>
+
+#undef DEBUG_ROMFS
+
+/* ROMFS superblock */
+struct romfs_super {
+       u32 word0;
+       u32 word1;
+       u32 size;
+       u32 checksum;
+       char name[0];
+};
+
+struct romfs_inode {
+       u32 next;
+       u32 spec;
+       u32 size;
+       u32 checksum;
+       char name[0];
+};
+
+extern flash_info_t flash_info[];
+#define PART_OFFSET(x) (x->offset + flash_info[x->dev->id->num].start[0])
+#define ALIGN(x)       (((x) & 0xfffffff0))
+#define HEADERSIZE(name)       (0x20 + ALIGN(strlen(name)))
+
+static unsigned long romfs_resolve (unsigned long begin, unsigned long offset,
+                               unsigned long size, int raw, char *filename)
+{
+       unsigned long inodeoffset = 0, nextoffset;
+       struct romfs_inode *inode;
+#ifdef DEBUG_ROMFS
+       printf ("ROMFS_resolve: begin 0x%x, offset 0x%x, size 0x%x, raw 0x%x, \
+               filename %s\n", begin, offset, size, raw, filename);
+#endif
+
+       while (inodeoffset < size) {
+               inode = (struct romfs_inode *)(begin + offset + inodeoffset);
+               offset = 0;
+               nextoffset = ALIGN (inode->next);
+#ifdef DEBUG_ROMFS
+               printf("inode 0x%x, name %s - len 0x%x, next inode 0x%x, \
+                       compare names 0x%x\n",
+                       inode, inode->name, strlen (inode->name), nextoffset,
+                       strncmp (filename, inode->name, strlen (filename)));
+#endif
+               if (!strncmp (filename, inode->name, strlen (inode->name))) {
+                       char *p = strtok (NULL, "/");
+                       if (raw && (p == NULL || *p == '\0')) {
+                               return offset + inodeoffset;
+                       }
+                       return romfs_resolve (begin,
+                                       inodeoffset + HEADERSIZE (inode->name),
+                                       size, raw, p);
+               }
+               inodeoffset = nextoffset;
+       }
+
+       printf ("can't find corresponding entry\n");
+       return 0;
+}
+
+int romfs_load (char *loadoffset, struct part_info *info, char *filename)
+{
+       struct romfs_inode *inode;
+       struct romfs_super *sb;
+       char *data;
+       int pocet;
+       sb = (struct romfs_super *) PART_OFFSET (info);
+
+       unsigned long offset;
+
+       offset = romfs_resolve (PART_OFFSET (info), HEADERSIZE (sb->name),
+                               sb->size, 1, strtok (filename, "/"));
+       if (offset <= 0)
+               return offset;
+
+       inode = (struct romfs_inode *)(PART_OFFSET (info) + offset);
+       data = (char *)((int)inode + HEADERSIZE (inode->name));
+       pocet = inode->size;
+       while (pocet--) {
+               *loadoffset++ = *data++;
+       }
+       return inode->size;
+}
+
+static int romfs_list_inode (struct part_info *info, unsigned long offset)
+{
+       struct romfs_inode *inode =
+                       (struct romfs_inode *)(PART_OFFSET (info) + offset);
+       struct romfs_inode *hardlink = NULL;
+       char str[3], *data;
+
+/*     mapping         spec.info means
+ * 0   hard link       link destination [file header]
+ * 1   directory       first file's header
+ * 2   regular file    unused, must be zero [MBZ]
+ * 3   symbolic link   unused, MBZ (file data is the link content)
+ * 4   block device    16/16 bits major/minor number
+ * 5   char device             - " -
+ * 6   socket          unused, MBZ
+ * 7   fifo            unused, MBZ
+ */
+       switch (inode->next & 0x7) {
+       case 0:
+               str[0] = 'h';
+               break;
+       case 1:
+               str[0] = 'd';
+               break;
+       case 2:
+               str[0] = 'f';
+               break;
+       case 3:
+               str[0] = 'l';
+               break;
+       case 4:
+               str[0] = 'b';
+               break;
+       case 5:
+               str[0] = 'c';
+               break;
+       case 6:
+               str[0] = 's';
+               break;
+       case 7:
+               str[0] = 'p';
+               break;
+       default:
+               str[0] = '?';
+       }
+
+       if (inode->next & 0x8) {
+               str[1] = 'x';
+       } else {
+               str[1] = '-';
+       }
+       str[2] = '\0';
+
+       if ((str[0] == 'b') || (str[0] == 'c')) {
+#ifdef DEBUG_ROMFS
+               printf (" %s  %3d,%3d %12s 0x%08x 0x%08x", str,
+                       (inode->spec & 0xffff0000) >> 16,
+                       inode->spec & 0x0000ffff, inode->name, inode,
+                       inode->spec);
+#else
+               printf (" %s  %3d,%3d %12s", str,
+                       (inode->spec & 0xffff0000) >> 16,
+                       inode->spec & 0x0000ffff);
+#endif
+       } else {
+#ifdef DEBUG_ROMFS
+               printf (" %s  %7d %12s 0x%08x 0x%08x", str, inode->size,
+                       inode->name, inode, inode->spec);
+#else
+               printf (" %s  %7d %12s", str, inode->size, inode->name);
+#endif
+               if (str[0] == 'l') {
+                       data = (char *)((int)inode + HEADERSIZE (inode->name));
+                       puts (" -> ");
+                       puts (data);
+               }
+               if (str[0] == 'h') {
+                       hardlink = (struct romfs_inode *)(PART_OFFSET (info) +
+                                               inode->spec);
+                       puts (" -> ");
+                       puts (hardlink->name);
+               }
+       }
+       puts ("\n");
+       return ALIGN (inode->next);
+}
+
+int romfs_ls (struct part_info *info, char *filename)
+{
+       struct romfs_inode *inode;
+       unsigned long inodeoffset = 0, nextoffset;
+       unsigned long offset, size;
+       struct romfs_super *sb;
+       sb = (struct romfs_super *)PART_OFFSET (info);
+
+       if (strlen (filename) == 0 || !strcmp (filename, "/")) {
+               offset = HEADERSIZE (sb->name);
+               size = sb->size;
+       } else {
+               offset = romfs_resolve (PART_OFFSET (info),
+                       HEADERSIZE (sb->name), sb->size, 1,
+                       strtok (filename, "/"));
+
+               if (offset == 0) {
+                       return offset;
+               }
+               inode = (struct romfs_inode *)(PART_OFFSET (info) + offset);
+               if ((inode->next & 0x7) != 1) {
+                       return (romfs_list_inode (info, offset) > 0);
+               }
+
+               size = sb->size;
+               offset = offset + HEADERSIZE (inode->name);
+       }
+
+       inodeoffset = offset + inodeoffset;
+       while (inodeoffset < size) {
+               nextoffset = romfs_list_inode (info, inodeoffset);
+               if (nextoffset == 0)
+                       break;
+               inodeoffset = nextoffset;
+       }
+       return 1;
+}
+
+int romfs_info (struct part_info *info)
+{
+       struct romfs_super *sb;
+       sb = (struct romfs_super *)PART_OFFSET (info);
+
+       printf ("name: \t\t%s, len %d B\n", sb->name, strlen (sb->name));
+       printf ("size of SB:\t%d B\n", HEADERSIZE (sb->name));
+       printf ("full size:\t%d B\n", sb->size);
+       printf ("checksum:\t0x%x\n", sb->checksum);
+       return 0;
+}
+
+int romfs_check (struct part_info *info)
+{
+       struct romfs_super *sb;
+       if (info->dev->id->type != MTD_DEV_TYPE_NOR)
+               return 0;
+
+       sb = (struct romfs_super *)PART_OFFSET (info);
+       if ((sb->word0 != 0x2D726F6D) || (sb->word1 != 0x3166732D)) {
+               return 0;
+       }
+       return 1;
+}
+
+#endif