[U-Boot-Users] [PATCH 4/4] romfs

Michal Simek monstr at seznam.cz
Sun Aug 5 20:56:31 CEST 2007


Signed-off-by: Michal Simek <monstr at monstr.eu>

Romfs support.

diff --git a/common/cmd_jffs2.c b/common/cmd_jffs2.c
index 7fd1fa3..147ab10 100644
--- a/common/cmd_jffs2.c
+++ b/common/cmd_jffs2.c
@@ -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>
@@ -110,7 +110,7 @@
 #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);
   }

diff --git a/fs/romfs/Makefile b/fs/romfs/Makefile
index e69de29..937d755 100644
--- a/fs/romfs/Makefile
+++ b/fs/romfs/Makefile
@@ -0,0 +1,49 @@
+#
+# (C) Copyright 2000-2006
+# Wolfgang Denk, DENX Software Engineering, wd at 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/Makefile b/fs/Makefile
index 273d90e..118ae78 100644
--- a/fs/Makefile
+++ b/fs/Makefile
@@ -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/romfs.c b/fs/romfs/romfs.c
index e69de29..b7d9696 100644
--- a/fs/romfs/romfs.c
+++ b/fs/romfs/romfs.c
@@ -0,0 +1,270 @@
+/*
+ * (C) Copyright 2007 Michal Simek
+ *
+ * Michal SIMEK <monstr at 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








More information about the U-Boot mailing list