ltib
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Ltib] Adding YAFFS2 deployment to LTIB (as well as elf file generat


From: Stuart Hughes
Subject: Re: [Ltib] Adding YAFFS2 deployment to LTIB (as well as elf file generation of result)
Date: Sat, 07 Nov 2009 10:03:52 +0000
User-agent: Thunderbird 2.0.0.16 (X11/20080707)

Hi Peter,

Before checking this in and uploading the yaffs patch to the GPP I wanted to let you check some changes I made. I've attached the modified patches. Here's some comments:

* In both your patches I stripped the \r from the line endings, so that they are now just \n. For future patches please try to avoid \r as for C code in particular if they get in they can cause problems.

* In your patches I removed real tabs in favour of spaces (just a preference, I wanted to stay consistent).

* I've added a comment out section in .ltibrc to show how to use the use_localtime feature.

* I bumped up the host_wait_warning number in .ltibrc to force a re-evaluation of host packages (so people who update will build the updated yaffs).

* In deployment.lkc I made the date-stamping of the elf image optional (DEPLOYMENT_ELF_DATESTAMP), I reflected this in Ltibutils.pm

* In yaffs-utils.spec I bumped up the revision number in case people already have BSPs with yaffs enabled, this will make sure the newer versions supersedes the old and gets installed.

* In yaffs_utils-20060418-mkyaffs2image.patch I removed the bogus 'binary files .. differ' and xxx~ diffs. I also added a pre-amble to state the origin.

Can you review these changes (test if possible) and let me know if okay to commit. Also can you confirm that for the yaffs_utils-20060418-mkyaffs2image.patch you are the originator (or where the changes came from) and confirm they're freely distributable so that I can add this when I upload to the GPP.

Thanks for your help.

Regards, Stuart

Peter Barada wrote:
On Fri, 2009-11-06 at 17:29 +0000, Stuart Hughes wrote:
Hi Peter,

If you can send me a new patch that would help. A flag in .ltibrc to indicate times are local would be fine, the default (no entry at all) should be to GMT (UTC).

Attached.

1) re-factored ELF generation.

2) Fixes the absolute prefixing to only apply when creating symbolic link in rpm/SOURCES/

3) Added flag in .ltibrc to modify gm_yyyymmdd() to return localtime IFF flag %use_localdir is set and non-zero. My perl foo is not super stong so I brute-forced it.

Example flag usage in .ltibrc:

# If %use_localtime is set, and non-zero, then timestamps are in localtime, not 
GMT
%use_localtime
1


Regards, Stuart

Peter Barada wrote:
> On Fri, 2009-11-06 at 16:07 +0000, Stuart Hughes wrote:
>> Hi Peter,
>>
>> I understand your reluctance to use UTC (GMT), but I still think in the >> log run that will cause less confusion. If you just want a timestamp, >> who about using the 'time' seconds since the epoch? Anyhow I can >> foresee many issues if you use localtime, so although there's no >> right/wrong wrt it would please me to go with something based on UTC. > I understand the implications of using localtime, especially if > development is spread out across timezones. Seconds since epoch would > certainly work, but is quite cumbersome for users I distribute images to > that don't understand how to convert back-n-forth from localtime. > > In my case the granularity is only to a day, and isolated to the stamp > on the file so I wouldn't expect much problem with it. > > As a compromise, would a patch that adds/uses a flag to .ltibrc to > specify whether timestamps are in localtime or GMT be acceptable? Then > the default can be GMT and users can choose which time refernce they > want to use..... > >> For now I'll apply your proposed change to add $top to relative paths, >> lets see if there is any fallout (regressions) and if so deal with it then. > As I'm the only one (apparently) who needs this, lemme look at fixing > the symbolic link creation in rpm/SOURCES instead. I'll get you > something over the weekend. > >> I will re-factor deployment.lkc as discussed (as time permits). > > If you want, I can re-factor and resubmit the change.... > >> Regards, Stuart
>>
>> Peter Barada wrote:
>> > On Fri, 2009-11-06 at 09:13 +0000, Stuart Hughes wrote:
>> >> Hi Peter,
>> >>
>> >> Thanks for the patches. I need to take a closer look (maybe over the >> >> w/e) but here's some initial comments/questions for you:
>> >>
>> >> ---+ bin/Ltibutils.pm
>> >>
>> >> I don't like the idea of using localtime as timestamps when making ELF >> >> images. The reason is this will confuse people as it's inconsistent >> >> with all other timestamps used in LTIB and also without a timezone it >> >> can't be given an absolute reference. I'd advise switching to gm_yyyymmdd. >> > >> > In my timezone (GMT+5), its quite aggravating to do a build a 6:59pm and >> > get one date, but then a build at 7:01pm produces tomorrows date. The >> > date is only used in the ELF image name to stamp it. >> > >> > The reason for the date is so ELF images I create are anchored by date >> > which makes it much easier to track when bugs pop up (by bisecting tests >> > using all images to date(thanks to really cheap disc space!)) as well as >> > easily have developers/users "keep up" with feature additions. >> > >> > The only place gm_yyyymmdd() is used is in Ltibrelease.pm::release_main. >> > The same functionality (i.e. calling gmtime) is replicated in multiple >> > places (autobuild, listpkginfo, mk_pkg_results). >> > >> >> I think prefixing relative paths with $top in parse_config is probably >> >> okay, but I'm surprised it is needed as ltib is always run from the top >> >> directory? Even if it doesn't do any harm, I'm a bit worried that this >> >> could break other configs if they run from a different directory and >> >> assume that current working directory. (I can't remember if anything >> >> else uses this function).
>> > In my %ldirs I have:
>> > >> > /var/ltmp/pkgs
>> > /opt/freescale/pkgs
>> > my-package-pool
>> > >> > and if I have the yaffs_utils-20060418-mkyaffs2image.patch patch in >> > my-package-pool, and w/o the change to prefix the relative path, adding >> > a print of $getcwd() and $path right before the "if (-f $path) {" >> > statement in get_file(), then I see the following output: >> > >> > address@hidden:~/work/logic/svn/eps_svn/software/products/linux/LTIB/trunk/ltib-20091102$ ./ltib -p yaffs-utils.spec -m prep >> > >> > Processing: yaffs-utils
>> > =========================
>> > Build path taken because: build key set, no prebuilt rpm, >> > pwd: /home/peter/work/logic/svn/eps_svn/software/products/linux/LTIB/trunk/ltib-20091102 path: /opt/ltib/pkgs/yaffs_utils-20060418-mkyaffs2image.patch
>> > pwd: 
/home/peter/work/logic/svn/eps_svn/software/products/linux/LTIB/trunk/ltib-20091102 
path: /var/tmp/pkgs/yaffs_utils-20060418-mkyaffs2image.patch
>> > pwd: 
/home/peter/work/logic/svn/eps_svn/software/products/linux/LTIB/trunk/ltib-20091102 
path: /opt/freescale/pkgs/yaffs_utils-20060418-mkyaffs2image.patch
>> > pwd: 
/home/peter/work/logic/svn/eps_svn/software/products/linux/LTIB/trunk/ltib-20091102 
path: my-package-pool/yaffs_utils-20060418-mkyaffs2image.patch
>> > Testing network connectivity
>> > OK GPP: >> > >> > Try yaffs_utils-20060418-mkyaffs2image.patch.md5 from the GPP
>> > http://bitshrine.org/gpp/yaffs_utils-20060418-mkyaffs2image.patch.md5:
>> > 10:23:48 ERROR 404: Not Found.
>> > WARN: skipping md5sum check for 
lpd-IP-package-pool/yaffs_utils-20060418-mkyaffs2image.patch, md5 file was not found
>> > >> > rpmbuild --dbpath /home/peter/work/logic/svn/eps_svn/software/products/linux/LTIB/trunk/ltib-20091102/rootfs//var/lib/rpm --target arm --define '_unpackaged_files_terminate_build 0' --define '_target_cpu arm' --define '__strip strip' --define '_topdir /home/peter/work/logic/svn/eps_svn/software/products/linux/LTIB/trunk/ltib-20091102/rpm' --define '_prefix /usr' --define '_tmppath /home/peter/work/logic/svn/eps_svn/software/products/linux/LTIB/trunk/ltib-20091102/tmp' --define '_rpmdir /home/peter/work/logic/svn/eps_svn/software/products/linux/LTIB/trunk/ltib-20091102/rpm/RPMS' --define '_mandir /usr/share/man' --define '_sysconfdir /etc' --define '_localstatedir /var' -bp /home/peter/work/logic/svn/eps_svn/software/products/linux/LTIB/trunk/ltib-20091102/dist/lfs-5.1/yaffs-utils/yaffs-utils.spec
>> > Building target platforms: arm
>> > Building for target arm
>> > error: File 
/home/peter/work/logic/svn/eps_svn/software/products/linux/LTIB/trunk/ltib-20091102/rpm/SOURCES/yaffs_utils-20060418-mkyaffs2image.patch:
 No such file or directory
>> > Build time for yaffs-utils: 0 seconds
>> > >> > Failed building yaffs-utils >> > >> > >> > f_prep() returned an error, exiting
>> > traceback:
>> >  main:561
>> > >> > Exiting on error or interrupt >> > >> > >> > so get_file works fine w/o the change. The failure is because >> > rpm/SOURCES/yaffs_utils-20060418-mkyaffs2image.patch is a symbolic link >> > to "my-package-pool/yaffs_utils-20060418-mkyaffs2image.patch" using a >> > relative path, which causes rpm to fail as the symbolic link is valid >> > IFF the cwd (when accessing that file) is the top-level LTIB directory. >> > I think rpm changes its working directory to "rpm/BUILD" which would >> > cause accessing that file to fail.... >> > >> > I'll look at prefixing $top in the symbolic link creation, not in >> > get_file itself and see what happens in my LTIB usage.... >> > >> > >> >> ---+ config/userspace/deployment.lkc
>> >>
>> >> I can see what you're doing with the logic for primary deployment style >> >> + elf. If I understand correctly if your platform has an elf capability >> >> then you want to build that as well as your primary choice. If so then >> >> I think it would be better to re-factor this. Put it back as was, add >> >> yaffs2 to the 'root filesystem image type' choice-list and add a new >> >> independent section below it like this:
>> >>
>> >> if CAP_DEPLOYMENT_ELF && (DEPLOYMENT_JFFS2
>> >>         || DEPLOYMENT_YAFFS2
>> >>         || DEPLOYMENT_RAMDIS)
>> >> config DEPLOYMENT_ELF
>> >>         bool "build an combined elf image"
>> >> endif
>> >>
>> >> If you agree I can make that change.
>> > >> > Yes, on my platform I want to optionally build the ELF file as well as >> > the rootfs, and in the case of a ramdisk, combine it into the ELF file >> > (as the other rootfs images would reside on non-volatile storage). >> > >> > Your refactoring makes perfect sense to me. >> > >> >> Aside from that it looks okay so far.
>> >>
>> >> Regards, Stuart
>> >>
>> >>
>> >> Peter Barada wrote:
>> >> > Stuart,
>> >> > >> >> > The attached patch adds YAFFS2 as a deployment method to the current >> >> > LTIB (actually LTIB as checked out 20091102), as well as patches to >> >> > yaffs-utils-20060418 to allow for mkfsyaffs2image to be built and take >> >> > args that allow a device table. >> >> > >> >> > I've purposely left the original mkyaffsimage code alone (and did not >> >> > add a YAFFS deployment method) as I don't have a target with small-block >> >> > NAND to test that functionality with, but it should be failry simple to add. >> >> > >> >> > The patch to deployment.lkc and bin/Ltibutils.pm also adds in ELF >> >> > support, as in have LTIB create an ELF file of the resultant >> >> > u-boot/kernel or u-boot/kernel/ramdisk using a Makefile in >> >> > config/platform/__platform__/elf-image, and the ELF creation capability >> >> > is enabled if the platform's main.lkc contains: >> >> > >> >> > # Can deploy an ELF image.
>> >> > config CAP_DEPLOYMENT_ELF
>> >> >     bool
>> >> >     default y
>> >> > >> >> > >> >> > If this capability is not present then the code should act as it does >> >> > now (with the addition of creation of a YAFFS2 rootfs image). My target >> >> > has LoLo as its boot loader, so to boot linux I need to load >> >> > u-boot/kernel and exec u-boot (which then uses bootm witht he address of >> >> > where the kernel was loaded as part of the ELF file) so I need the ELF >> >> > deployment method. I can provide the Makefile/utilities for my target >> >> > to link together u-boot/kernel/rootfs into a single ELF file if anyone >> >> > is interested. >> >> > >> >> > I've been thinking about the sector/spare/erase size configuration for >> >> > YAFFS (and the erase size for JFFS2), and I'm starting to convince >> >> > myself that these variables should be in a platform's main.lkc as >> >> > constants. The patch to yaffs-utils doesn't have any sector/page/block >> >> > size information in it, I'll generate that later and have mkyaffs2image >> >> > take advantage of it. >> >> > >> >> > Hopefully people will find this useful. >> >> > >> >> > -- >> >> > Peter Barada <address@hidden <mailto:address@hidden> <mailto:address@hidden> <mailto:address@hidden> <mailto:address@hidden>>
>> >> > Logic Product Development, Inc.
>> >> > >> > -- >> > Peter Barada <address@hidden <mailto:address@hidden> <mailto:address@hidden> <mailto:address@hidden>>
>> > Logic Product Development, Inc.
>> > > -- > Peter Barada <address@hidden <mailto:address@hidden> <mailto:address@hidden>>
> Logic Product Development, Inc.
>
--
Peter Barada <address@hidden <mailto:address@hidden>>
Logic Product Development, Inc.

20091107: Submitted by Peter Barada to the LTIB mailing list.
Subject: Re: [Ltib] Adding YAFFS2 deployment to LTIB (as well as elf file 
generation of result)

Add support for yaffs2 as well as yaffs

diff --exclude CVS --exclude .git -uNr yaffs_utils-20060418/yaffs2/devextras.h 
yaffs_utils-20060418.modified/yaffs2/devextras.h
--- yaffs_utils-20060418/yaffs2/devextras.h     2006-04-24 07:39:43.000000000 
-0400
+++ yaffs_utils-20060418.modified/yaffs2/devextras.h    2009-11-03 
12:18:09.000000000 -0500
@@ -200,6 +200,8 @@
        for (pos = (head)->next, n = pos->next; pos != (head); \
                pos = n, n = pos->next)
 
+#ifdef CONFIG_YAFFS_PROVIDE_DEFS
+
 /*
  * File types
  */
@@ -245,7 +247,7 @@
        unsigned int ia_attr_flags;
 };
 
-#define KERN_DEBUG
+#endif
 
 #else
 
diff --exclude CVS --exclude .git -uNr 
yaffs_utils-20060418/yaffs2/utils/Makefile 
yaffs_utils-20060418.modified/yaffs2/utils/Makefile
--- yaffs_utils-20060418/yaffs2/utils/Makefile  2006-04-24 07:38:44.000000000 
-0400
+++ yaffs_utils-20060418.modified/yaffs2/utils/Makefile 2009-11-03 
12:08:45.000000000 -0500
@@ -16,7 +16,8 @@
 
 #KERNELDIR = /usr/src/kernel-headers-2.4.18
 
-CFLAGS =   -I/usr/include -I.. -O2 -Wall -DCONFIG_YAFFS_UTIL
+INCDIR=-I$(KHDR_DIR)
+CFLAGS =   -O2 -Wall -DCONFIG_YAFFS_UTIL  -I.. $(INCDIR)
 CFLAGS+=   -Wshadow -Wpointer-arith -Wwrite-strings -Wstrict-prototypes 
-Wmissing-declarations
 CFLAGS+=   -Wmissing-prototypes -Wredundant-decls -Wnested-externs -Winline
 
@@ -31,11 +32,12 @@
 MKYAFFSSOURCES = mkyaffsimage.c
 MKYAFFSIMAGEOBJS = $(MKYAFFSSOURCES:.c=.o)
 
-MKYAFFS2SOURCES = mkyaffs2image.c
+MKYAFFS2SOURCES = mkyaffs2image.c dev_table.c
 MKYAFFS2LINKS = yaffs_packedtags2.c yaffs_tagsvalidity.c
 MKYAFFS2IMAGEOBJS = $(MKYAFFS2SOURCES:.c=.o) $(MKYAFFS2LINKS:.c=.o)
 
-all: mkyaffsimage mkyaffs2image
+TARGETS=mkyaffsimage mkyaffs2image
+all: $(TARGETS)
 
 $(COMMONLINKS) $(MKYAFFSLINKS) $(MKYAFFS2LINKS):
        ln -s ../$@ $@
@@ -49,6 +51,9 @@
 mkyaffs2image: $(COMMONOBJS) $(MKYAFFS2IMAGEOBJS)
        $(CC) -o $@ $(COMMONOBJS) $(MKYAFFS2IMAGEOBJS)
 
+install:        
+       mkdir -p ${DESDIR}/${SBINDIR}
+       install  $(TARGETS)  ${DESTDIR}/${SBINDIR}/ 
 
 clean:
-       rm -f $(COMMONOBJS) $(MKYAFFSIMAGEOBJS) $(MKYAFFS2IMAGEOBJS) 
$(COMMONLINKS) $(MKYAFFSLINKS) $(MKYAFFS2LINKS) mkyaffsimage mkyaffs2image core
+       rm -f $(COMMONOBJS) $(MKYAFFSIMAGEOBJS) $(MKYAFFS2IMAGEOBJS) 
$(COMMONLINKS) $(MKYAFFSLINKS) $(MKYAFFS2LINKS) $(TARGETS) core
diff --exclude CVS --exclude .git -uNr 
yaffs_utils-20060418/yaffs2/utils/dev_table.c 
yaffs_utils-20060418.modified/yaffs2/utils/dev_table.c
--- yaffs_utils-20060418/yaffs2/utils/dev_table.c       1969-12-31 
19:00:00.000000000 -0500
+++ yaffs_utils-20060418.modified/yaffs2/utils/dev_table.c      2009-11-03 
12:22:12.000000000 -0500
@@ -0,0 +1,456 @@
+#define _GNU_SOURCE
+#include <sys/types.h>
+#include <stdio.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <sys/mman.h>
+#include <fcntl.h>
+#include <dirent.h>
+#include <sys/stat.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <string.h>
+#include <stdarg.h>
+#include <stdint.h>
+#include <malloc.h>
+#include <ctype.h>
+
+#include "dev_table.h"
+
+extern int progress;
+static const char *const app_name = "mkfs.yaffs";
+
+static void verror_msg(const char *s, va_list p)
+{
+       fflush(stdout);
+       fprintf(stderr, "%s: ", app_name);
+       vfprintf(stderr, s, p);
+}
+
+static void error_msg_and_die(const char *s, ...)
+{
+       va_list p;
+
+       va_start(p, s);
+       verror_msg(s, p);
+       va_end(p);
+       putc('\n', stderr);
+       exit(EXIT_FAILURE);
+}
+
+struct deventry {
+  char *name;                  // name of entry
+  char full_name[511];         // full name of entry
+  int dumped;                  // !0 if entry dumped
+  int ino;  // increments from 0
+  unsigned long uid;
+  unsigned long gid;
+  unsigned long mode;
+  dev_t rdev;
+  int parentId;
+  struct deventry *child;       // children
+  struct deventry *next;        // next at this level
+  struct deventry *parent_next; // next at parent level
+  int skip;                    // !0 if entry is to be skipped
+};
+
+struct deventry *root;
+
+struct path_component {
+  char *next_component; // ptr to where next component starts(if one)
+} pc;
+
+// Finds first or next path comoponent of a string
+static char *find_next_component(char *path, char **next)
+{
+  char *r;
+
+  // Skip leading '/'
+  while(*path && *path == '/')
+    path++;
+
+  // Search for next separator
+  r = path;
+  if (*r) {
+    while (*r && *r != '/')
+      r++;
+    *next = r;
+    if (*r) {
+      *r = 0;
+    } else
+      *next = NULL;
+  } else
+    *next = NULL;
+
+  return path;
+}
+
+
+static int dev_table_ino = 0;
+
+static void add_dev_entry(const char *name, unsigned long uid, unsigned long 
gid, unsigned long mode, dev_t rdev)
+{
+  struct deventry *e;
+  struct deventry *p, **q;
+  char nbuf[128];
+  char *next, *path;
+
+  e = malloc(sizeof(*p));
+  if (!e)
+    error_msg_and_die("No memory for dirent");
+
+  memset(e, 0, sizeof(*e));
+  // e->name = strdup(name);
+  e->uid = uid;
+  e->gid = gid;
+  e->mode = mode;
+  e->rdev = rdev;
+  e->ino = ++dev_table_ino;
+  strcpy(e->full_name, name);
+
+  strcpy(nbuf, name);
+
+  // Find first component, return in s, set t to following
+  path = find_next_component(nbuf, &next);
+
+  p = *(q = &root);
+  while (p) {
+    if (!strcmp (p->name, path)) {
+      p = *(q=&p->child);  // Move to child
+      if (next)
+       path = find_next_component(next+1, &next);
+      else
+       break;
+    } else
+      p = *(q = &p->next);
+  }
+  e->name = strdup(path);
+  *q = e;
+}
+
+static struct deventry *find_dev_dir(const char *name)
+{
+  struct deventry *p, **q;
+  char nbuf[128];
+  char *next, *path;
+
+  strcpy(nbuf, name);
+
+  // Find first component, return in s, set t to following
+  path = find_next_component(nbuf, &next);
+
+  p = *(q = &root);
+  while (p) {
+    if (!strcmp (p->name, path)) {
+      if (!next)
+       return p;
+      p = *(q=&p->child);  // Move to child
+       path = find_next_component(next+1, &next);
+    } else
+      p = *(q = &p->next);
+  }
+  return NULL;
+}
+
+extern char *in_file;
+static struct deventry *find_dev_table_entry(const char *path)
+{
+  struct deventry *p;
+  char *q = in_file;
+
+  while (*q && *q == *path) {
+    q++, path++;
+  }
+
+  if (*path == '/')
+    path++;
+
+  if (*path) {
+    p = find_dev_dir(path);
+    return p;
+  }
+  return 0;
+}
+
+DIR *my_opendir(const char *path)
+{
+  struct deventry *p;
+  if ((p = find_dev_table_entry(path))) {
+    p->dumped = 1;
+  }
+  return opendir(path);
+}
+
+struct dirent *my_readdir(DIR *dir)
+{
+  return readdir(dir);
+}
+
+int lstat_dev_table(char *path, struct stat *stat)
+{
+  struct deventry *p;
+
+  p = find_dev_table_entry(path);
+  if (!p || p->dumped)
+    return 0;
+
+  p->dumped = 1;
+
+  memset(stat, 0, sizeof(*stat));
+  stat->st_dev = 0;
+  stat->st_ino = p->ino;
+  stat->st_mode = p->mode;
+  stat->st_rdev = p->rdev;
+
+  return 1;
+}
+
+void dev_table_set_parent(char *path, int parentId)
+{
+  struct deventry *p;
+
+  if ((p = find_dev_table_entry(path))) {
+    if (progress)
+      printf("%s: path %s parentId %d\n", __FUNCTION__, path, parentId);
+    p->parentId = parentId;
+    p->skip = 1;  // as we already have the object, no need to create it again
+  }
+}
+
+void
+add_dev_table_entries(void)
+{
+  struct deventry *p;
+  struct dirent d;
+  char name[128];
+  p = root;
+  while (p) {
+    if (!p->dumped && !p->skip) {
+      strcpy(d.d_name, p->name);
+      sprintf(name, "%s%s", in_file, p->full_name);
+      process_entry(&d, p->parentId, name);
+    }
+    if (p->child) {
+      p = p->child;
+    } else if (p->next)
+      p = p->next;
+    else {
+      p = p->parent_next;
+    }
+  }
+}
+
+static void add_host_filesystem_entry(char *name, char *hostpath, unsigned 
long uid, unsigned long gid, unsigned long mode, dev_t rdev)
+{
+  struct dirent d;
+
+  if (progress)
+    printf("%s - %s 0x%lx 0x%lx 0x%lx 0x%llx\n",
+        name, hostpath, uid, gid, mode, rdev);
+
+  add_dev_entry(name, uid, gid, mode, rdev);
+  
+}
+
+static void recurse_post_build_dev_tree(struct deventry *p, struct deventry 
*q, int parentId)
+{
+  while (p) {
+    if (p->child) {
+      if (!p->parentId)
+       fprintf(stderr, "%s doesn't have a parentId\n", p->full_name);
+      recurse_post_build_dev_tree(p->child, p->next, p->parentId);
+    } else if (!p->parentId)
+      p->parentId = parentId;
+    if (p->next)
+      p = p->next;
+    else {
+      p->parent_next = q;
+      break;
+    }
+  }
+}
+
+void post_build_dev_tree(void)
+{
+  recurse_post_build_dev_tree(root, NULL, 0);
+}
+
+void dump_dev_tree(void)
+{
+  struct deventry *p;
+
+  p = root;
+  while (p) {
+    printf("name %s\n", p->name);
+    if (p->child) {
+      printf("Add /\n");
+      p = p->child;
+    } else if (p->next)
+      p = p->next;
+    else {
+      printf("pop\n");
+      p = p->parent_next;
+    }
+  }
+}
+
+
+/*  device table entries take the form of:
+    <path>     <type> <mode>   <uid>   <gid>   <major> <minor> <start> <inc>   
<count>
+    /dev/mem     c    640       0       0         1       1       0     0      
   -
+
+    type can be one of:
+       f       A regular file
+       d       Directory
+       c       Character special device file
+       b       Block special device file
+       p       Fifo (named pipe)
+
+    I don't bother with symlinks (permissions are irrelevant), hard
+    links (special cases of regular files), or sockets (why bother).
+
+    Regular files must exist in the target root directory.  If a char,
+    block, fifo, or directory does not exist, it will be created.
+*/
+
+#ifdef __GNUC__
+#define SCANF_PREFIX "a"
+#define SCANF_STRING(s) (&s)
+#define GETCWD_SIZE 0
+#else
+#define SCANF_PREFIX "511"
+#define SCANF_STRING(s) (s = malloc(512))
+#define GETCWD_SIZE -1
+#endif
+
+static char default_rootdir[] = ".";
+static char *rootdir = default_rootdir;
+
+static int interpret_table_entry(char *line)
+{
+       char *hostpath;
+       char type, *name = NULL, *tmp, *dir;
+       unsigned long mode = 0755, uid = 0, gid = 0, major = 0, minor = 0;
+       unsigned long start = 0, increment = 1, count = 0;
+       struct filesystem_entry *parent, *entry;
+
+       if (sscanf (line, "%" SCANF_PREFIX "s %c %lo %lu %lu %lu %lu %lu %lu 
%lu",
+                SCANF_STRING(name), &type, &mode, &uid, &gid, &major, &minor,
+                &start, &increment, &count) < 0)
+       {
+               return 1;
+       }
+
+       if (!strcmp(name, "/")) {
+               fprintf(stderr, "Device table entries require absolute paths");
+               exit(-1);
+       }
+
+       asprintf(&hostpath, "%s%s", rootdir, name);
+
+       /* Check if this file already exists... */
+       switch (type) {
+               case 'd':
+                       mode |= S_IFDIR;
+                       break;
+               case 'f':
+                       mode |= S_IFREG;
+                       break;
+               case 'p':
+                       mode |= S_IFIFO;
+                       break;
+               case 'c':
+                       mode |= S_IFCHR;
+                       break;
+               case 'b':
+                       mode |= S_IFBLK;
+                       break;
+               default:
+                       fprintf(stderr, "Unsupported file type");
+                       exit(-1);
+       }
+
+       switch (type) {
+       case 'd':
+         add_host_filesystem_entry(name, hostpath, uid, gid, mode, 0);
+         break;
+       case 'f':
+         add_host_filesystem_entry(name, hostpath, uid, gid, mode, 0);
+         break;
+       case 'p':
+         add_host_filesystem_entry(name, hostpath, uid, gid, mode, 0);
+         break;
+       case 'c':
+       case 'b':
+         if (count > 0) {
+           dev_t rdev;
+           unsigned long i;
+           char *dname, *hpath;
+
+           for (i = start; i < count; i++) {
+             dname = hpath = NULL;
+             asprintf(&dname, "%s%lu", name, i);
+             asprintf(&hpath, "%s/%s%lu", rootdir, name, i);
+             rdev = makedev(major, minor + (i * increment - start));
+             add_host_filesystem_entry(dname, hpath, uid, gid,
+                                       mode, rdev);
+             free(dname);
+             free(hpath);
+           }
+         } else {
+           dev_t rdev = makedev(major, minor);
+           add_host_filesystem_entry(name, hostpath, uid, gid,
+                                     mode, rdev);
+         }
+         break;
+       default:
+         fprintf(stderr, "Unsupported file type");
+         exit(-1);
+       }
+       free(name);
+       free(hostpath);
+       return 0;
+}
+
+int parse_device_table(FILE * file)
+{
+       char *line;
+       int status = 0;
+       size_t length = 0;
+
+#if 0
+       /* Turn off squash, since we must ensure that values
+        * entered via the device table are not squashed */
+       squash_uids = 0;
+       squash_perms = 0;
+#endif
+       /* Looks ok so far.  The general plan now is to read in one
+        * line at a time, check for leading comment delimiters ('#'),
+        * then try and parse the line as a device table.  If we fail
+        * to parse things, try and help the poor fool to fix their
+        * device table with a useful error msg... */
+       line = NULL;
+       while (getline(&line, &length, file) != -1) {
+               /* First trim off any whitespace */
+               int len = strlen(line);
+
+               /* trim trailing whitespace */
+               while (len > 0 && isspace(line[len - 1]))
+                       line[--len] = '\0';
+               /* trim leading whitespace */
+               memmove(line, &line[strspn(line, " \n\r\t\v")], len);
+
+               /* How long are we after trimming? */
+               len = strlen(line);
+
+               /* If this is NOT a comment line, try to interpret it */
+               if (len && *line != '#') {
+                       if (interpret_table_entry(line))
+                               status = 1;
+               }
+
+               free(line);
+               line = NULL;
+       }
+       return status;
+}
diff --exclude CVS --exclude .git -uNr 
yaffs_utils-20060418/yaffs2/utils/dev_table.h 
yaffs_utils-20060418.modified/yaffs2/utils/dev_table.h
--- yaffs_utils-20060418/yaffs2/utils/dev_table.h       1969-12-31 
19:00:00.000000000 -0500
+++ yaffs_utils-20060418.modified/yaffs2/utils/dev_table.h      2009-11-03 
12:01:26.000000000 -0500
@@ -0,0 +1,11 @@
+#include <stdio.h>
+
+extern DIR *my_opendir(const char *path);
+extern struct dirent *my_readdir(DIR *dir);
+extern void post_build_dev_tree(void);
+extern void dump_dev_tree(void);
+extern void add_dev_table_entries(void);
+extern int lstat_dev_table(char *path, struct stat *stat);
+extern void dev_table_set_parent(char *path, int parentId);
+extern int parse_device_table(FILE * file);
+extern void process_entry(struct dirent *entry, int parent, char *full_name);
diff --exclude CVS --exclude .git -uNr 
yaffs_utils-20060418/yaffs2/utils/mkyaffs2image.c 
yaffs_utils-20060418.modified/yaffs2/utils/mkyaffs2image.c
--- yaffs_utils-20060418/yaffs2/utils/mkyaffs2image.c   2006-04-24 
07:39:48.000000000 -0400
+++ yaffs_utils-20060418.modified/yaffs2/utils/mkyaffs2image.c  2009-11-03 
12:23:24.000000000 -0500
@@ -1,37 +1,38 @@
 /*
- * YAFFS: Yet another FFS. A NAND-flash specific file system.
+ * YAFFS: Yet Another Flash File System. A NAND-flash specific file system.
  *
- * makeyaffsimage.c 
- *
- * Makes a YAFFS file system image that can be used to load up a file system.
- *
- * Copyright (C) 2002 Aleph One Ltd.
+ * Copyright (C) 2002-2007 Aleph One Ltd.
  *   for Toby Churchill Ltd and Brightstar Engineering
  *
  * Created by Charles Manning <address@hidden>
+ * Nick Bane modifications flagged NCB
+ * Endian handling patches by James Ng.
+ * mkyaffs2image hacks by NCB
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 as
  * published by the Free Software Foundation.
+ */
+
+/*
+ * makeyaffs2image.c
  *
- *
- * Nick Bane modifications flagged NCB
- *
- * Endian handling patches by James Ng.
- * 
- * mkyaffs2image hacks by NCB
- *
+ * Makes a YAFFS2 file system image that can be used to load up a file system.
+ * Uses default Linux MTD layout - change if you need something different.
  */
  
 #include <stdlib.h>
 #include <stdio.h>
 #include <fcntl.h>
 #include <sys/types.h>
+#include <pwd.h>
 #include <sys/stat.h>
 #include <dirent.h>
 #include <string.h>
 #include <unistd.h>
+#include <errno.h>
 #include "yaffs_ecc.h"
+#include "dev_table.h"
 #include "yaffs_guts.h"
 
 #include "yaffs_tagsvalidity.h"
@@ -44,7 +45,7 @@
 #define chunkSize 2048
 #define spareSize 64
 
-const char * mkyaffsimage_c_version = "$Id: mkyaffs2image.c,v 1.2 2005/12/13 
00:34:58 tpoynor Exp $";
+const char * mkyaffsimage_c_version = "$Id: mkyaffs2image.c,v 1.4 2007-02-14 
01:09:06 wookey Exp $";
 
 
 typedef struct
@@ -67,6 +68,84 @@
 
 static int convert_endian = 0;
 
+static int big_endian, little_endian;
+static int want_big_endian, want_little_endian;
+
+static int debug;  // should add options to turn on...
+int progress;  // !0 for progress output
+
+struct passwd *passwd_list;
+struct passwd *root_passwd;
+int passwd_list_size;
+
+struct passwd *find_entry_by_uid(int uid)
+{
+       struct passwd *p;
+       int i;
+       for (p=passwd_list, i=0; i<passwd_list_size; ++i, ++p) {
+               if (uid == p->pw_uid)
+                 return p;
+       }
+       return root_passwd;
+}
+
+struct passwd *find_entry_by_name(const char *name)
+{
+       struct passwd *p;
+       int i;
+       for (p=passwd_list, i=0; i<passwd_list_size; ++i, ++p) {
+               if (!strcmp(name, p->pw_name))
+                       return p;
+       }
+       return root_passwd;
+}
+
+static char *dev_table_name;  // name of device table
+static char *pw_name;  // file to pull permission information out of
+int remap_ownership = 0;  // !0 -> remap unknown ownership to root
+
+void process_pw_file(const char *fname)
+{
+       struct passwd *new_passwd_list, *p;
+       FILE *f;
+       struct passwd *tmp_passwd;
+       f = fopen(fname, "r");
+       if (!f) {
+               fprintf(stderr, "%s: can't open %s, %s\n", __FUNCTION__, fname, 
strerror(errno));
+               exit(1);
+       }
+
+       while ((tmp_passwd = fgetpwent(f)) != NULL) {
+               if (passwd_list)
+                       new_passwd_list = realloc(passwd_list, 
(passwd_list_size+1) * sizeof(*passwd_list));
+               else
+                       new_passwd_list = malloc(sizeof(*passwd_list));
+               if(!new_passwd_list) {
+                       fprintf(stderr, "%s: realloc/malloc failed, %s\n", 
__FUNCTION__, strerror(errno));
+                       exit(1);
+               }
+               passwd_list = new_passwd_list;
+               p = &passwd_list[passwd_list_size++];
+               p->pw_name = strdup(tmp_passwd->pw_name);
+               p->pw_passwd = strdup(tmp_passwd->pw_passwd);
+               p->pw_uid = tmp_passwd->pw_uid;
+               p->pw_gid = tmp_passwd->pw_gid;
+               p->pw_gecos = strdup(tmp_passwd->pw_gecos);
+               p->pw_dir = strdup(tmp_passwd->pw_dir);
+               p->pw_shell = strdup(tmp_passwd->pw_shell);
+       }
+       if (!passwd_list) {
+               fprintf(stderr, "%s: fgetpwent failed, %s\n", __FUNCTION__, 
strerror(errno));
+               exit(1);
+       }
+       root_passwd = find_entry_by_name("root");
+       if (remap_ownership && !root_passwd) {
+               fprintf(stderr, "%s: No root entry in passwd file!\n", 
__FUNCTION__);
+               exit(1);
+       }
+}
+
+
 static int obj_compare(const void *a, const void * b)
 {
   objItem *oa, *ob;
@@ -160,6 +239,7 @@
 {
        yaffs_ExtendedTags t;
        yaffs_PackedTags2 pt;
+       unsigned char spareBuf[spareSize];
 
        error = write(outFile,data,chunkSize);
        if(error < 0) return error;
@@ -187,7 +267,9 @@
        yaffs_PackTags2(&pt,&t);
        
 //     return write(outFile,&pt,sizeof(yaffs_PackedTags2));
-       return write(outFile,&pt,spareSize);
+       memset(spareBuf, 0xff, sizeof(spareBuf));
+       memcpy(spareBuf, &pt, sizeof(pt));
+       return write(outFile,&spareBuf,spareSize);
        
 }
 
@@ -252,16 +334,12 @@
     oh->roomToGrow[7] = SWAP32(oh->roomToGrow[7]);
     oh->roomToGrow[8] = SWAP32(oh->roomToGrow[8]);
     oh->roomToGrow[9] = SWAP32(oh->roomToGrow[9]);
-    oh->roomToGrow[10] = SWAP32(oh->roomToGrow[10]);
-    oh->roomToGrow[11] = SWAP32(oh->roomToGrow[11]);
 #endif
 }
 
 static int write_object_header(int objId, yaffs_ObjectType t, struct stat *s, 
int parent, const char *name, int equivalentObj, const char * alias)
 {
        __u8 bytes[chunkSize];
-       
-       
        yaffs_ObjectHeader *oh = (yaffs_ObjectHeader *)bytes;
        
        memset(bytes,0xff,sizeof(bytes));
@@ -309,6 +387,155 @@
        
 }
 
+#define PATH_LEN 1024
+
+static int process_directory(int parent, const char *path);
+
+void process_entry(struct dirent *entry, int parent, char *full_name)
+{
+       int ret;
+       struct stat stats;
+       int equivalentObj;
+       int newObj;
+
+       ret = lstat(full_name,&stats);
+       if (ret) {
+         // Hmm, not found - is it in the
+         // device tree
+         if (!lstat_dev_table(full_name, &stats))
+           return;
+       }
+       
+       if (remap_ownership) {
+         struct passwd *p;
+         p = find_entry_by_uid(stats.st_uid);
+         if (p) {
+           stats.st_uid = p->pw_uid;
+           stats.st_gid = p->pw_gid;
+         }
+         
+       }
+
+       if(S_ISLNK(stats.st_mode) ||
+           S_ISREG(stats.st_mode) ||
+           S_ISDIR(stats.st_mode) ||
+           S_ISFIFO(stats.st_mode) ||
+           S_ISBLK(stats.st_mode) ||
+           S_ISCHR(stats.st_mode) ||
+           S_ISSOCK(stats.st_mode))
+       {
+       
+               newObj = obj_id++;
+               nObjects++;
+
+               if (progress)
+                       printf("Object %d, parent %d, %s is a 
",newObj,parent,full_name);
+               
+               /* We're going to create an object for it */
+               if((equivalentObj = find_obj_in_list(stats.st_dev, 
stats.st_ino)) > 0)
+               {
+                       /* we need to make a hard link */
+                       if (progress)
+                               printf("hard link to object 
%d\n",equivalentObj);
+                       error =  write_object_header(newObj, 
YAFFS_OBJECT_TYPE_HARDLINK, &stats, parent, entry->d_name, equivalentObj, NULL);
+               }
+               else 
+               {
+                       
+                       add_obj_to_list(stats.st_dev,stats.st_ino,newObj);
+                       
+                       if(S_ISLNK(stats.st_mode))
+                       {
+               
+                               char symname[500];
+                       
+                               memset(symname,0, sizeof(symname));
+               
+                               readlink(full_name,symname,sizeof(symname) -1);
+                       
+                               if (progress)
+                                       printf("symlink to \"%s\"\n",symname);
+                               error =  write_object_header(newObj, 
YAFFS_OBJECT_TYPE_SYMLINK, &stats, parent, entry->d_name, -1, symname);
+
+                       }
+                       else if(S_ISREG(stats.st_mode))
+                       {
+                               if (progress)
+                                       printf("file, ");
+                               error =  write_object_header(newObj, 
YAFFS_OBJECT_TYPE_FILE, &stats, parent, entry->d_name, -1, NULL);
+
+                               if(error >= 0)
+                               {
+                                       int h;
+                                       __u8 bytes[chunkSize];
+                                       int nBytes;
+                                       int chunk = 0;
+                                       
+                                       h = open(full_name,O_RDONLY);
+                                       if(h >= 0)
+                                       {
+                                               
memset(bytes,0xff,sizeof(bytes));
+                                               while((nBytes = 
read(h,bytes,sizeof(bytes))) > 0)
+                                               {
+                                                       chunk++;
+                                                       
write_chunk(bytes,newObj,chunk,nBytes);
+                                                       
memset(bytes,0xff,sizeof(bytes));
+                                               }
+                                               if(nBytes < 0) 
+                                                       error = nBytes;
+
+                                               if (progress)
+                                                       printf("%d data chunks 
written\n",chunk);
+                                       }
+                                       else
+                                       {
+                                               perror("Error opening file");
+                                       }
+                                       close(h);
+                                       
+                               }                                               
        
+                                                                               
        
+                       }
+                       else if(S_ISSOCK(stats.st_mode))
+                       {
+                               if (progress)
+                                       printf("socket\n");
+                               error =  write_object_header(newObj, 
YAFFS_OBJECT_TYPE_SPECIAL, &stats, parent, entry->d_name, -1, NULL);
+                       }
+                       else if(S_ISFIFO(stats.st_mode))
+                       {
+                               if (progress)
+                                       printf("fifo\n");
+                               error =  write_object_header(newObj, 
YAFFS_OBJECT_TYPE_SPECIAL, &stats, parent, entry->d_name, -1, NULL);
+                       }
+                       else if(S_ISCHR(stats.st_mode))
+                       {
+                               if (progress)
+                                       printf("character device\n");
+                               error =  write_object_header(newObj, 
YAFFS_OBJECT_TYPE_SPECIAL, &stats, parent, entry->d_name, -1, NULL);
+                       }
+                       else if(S_ISBLK(stats.st_mode))
+                       {
+                               if (progress)
+                                       printf("block device\n");
+                               error =  write_object_header(newObj, 
YAFFS_OBJECT_TYPE_SPECIAL, &stats, parent, entry->d_name, -1, NULL);
+                       }
+                       else if(S_ISDIR(stats.st_mode))
+                       {
+                               if (progress)
+                                       printf("directory\n");
+                               error =  write_object_header(newObj, 
YAFFS_OBJECT_TYPE_DIRECTORY, &stats, parent, entry->d_name, -1, NULL);
+                               // process_directory(1,full_name);
+                               process_directory(newObj,full_name);
+                               dev_table_set_parent(full_name, newObj);
+                       }
+               }
+       }
+       else
+       {
+               printf(" we don't handle this type\n");
+       }
+}
 
 static int process_directory(int parent, const char *path)
 {
@@ -324,129 +551,15 @@
        {
                while((entry = readdir(dir)) != NULL)
                {
-               
                        /* Ignore . and .. */
                        if(strcmp(entry->d_name,".") &&
                           strcmp(entry->d_name,".."))
                        {
-                               char full_name[500];
-                               struct stat stats;
-                               int equivalentObj;
-                               int newObj;
-                               
+                               char full_name[PATH_LEN];
                                sprintf(full_name,"%s/%s",path,entry->d_name);
-                               
-                               lstat(full_name,&stats);
-                               
-                               if(S_ISLNK(stats.st_mode) ||
-                                   S_ISREG(stats.st_mode) ||
-                                   S_ISDIR(stats.st_mode) ||
-                                   S_ISFIFO(stats.st_mode) ||
-                                   S_ISBLK(stats.st_mode) ||
-                                   S_ISCHR(stats.st_mode) ||
-                                   S_ISSOCK(stats.st_mode))
-                               {
-                               
-                                       newObj = obj_id++;
-                                       nObjects++;
-                                       
-                                       printf("Object %d, %s is a 
",newObj,full_name);
-                                       
-                                       /* We're going to create an object for 
it */
-                                       if((equivalentObj = 
find_obj_in_list(stats.st_dev, stats.st_ino)) > 0)
-                                       {
-                                               /* we need to make a hard link 
*/
-                                               printf("hard link to object 
%d\n",equivalentObj);
-                                               error =  
write_object_header(newObj, YAFFS_OBJECT_TYPE_HARDLINK, &stats, parent, 
entry->d_name, equivalentObj, NULL);
-                                       }
-                                       else 
-                                       {
-                                               
-                                               
add_obj_to_list(stats.st_dev,stats.st_ino,newObj);
-                                               
-                                               if(S_ISLNK(stats.st_mode))
-                                               {
-                                       
-                                                       char symname[500];
-                                               
-                                                       memset(symname,0, 
sizeof(symname));
-                                       
-                                                       
readlink(full_name,symname,sizeof(symname) -1);
-                                               
-                                                       printf("symlink to 
\"%s\"\n",symname);
-                                                       error =  
write_object_header(newObj, YAFFS_OBJECT_TYPE_SYMLINK, &stats, parent, 
entry->d_name, -1, symname);
-
-                                               }
-                                               else if(S_ISREG(stats.st_mode))
-                                               {
-                                                       printf("file, ");
-                                                       error =  
write_object_header(newObj, YAFFS_OBJECT_TYPE_FILE, &stats, parent, 
entry->d_name, -1, NULL);
-
-                                                       if(error >= 0)
-                                                       {
-                                                               int h;
-                                                               __u8 
bytes[chunkSize];
-                                                               int nBytes;
-                                                               int chunk = 0;
-                                                               
-                                                               h = 
open(full_name,O_RDONLY);
-                                                               if(h >= 0)
-                                                               {
-                                                                       
memset(bytes,0xff,sizeof(bytes));
-                                                                       
while((nBytes = read(h,bytes,sizeof(bytes))) > 0)
-                                                                       {
-                                                                               
chunk++;
-                                                                               
write_chunk(bytes,newObj,chunk,nBytes);
-                                                                               
memset(bytes,0xff,sizeof(bytes));
-                                                                       }
-                                                                       
if(nBytes < 0) 
-                                                                          
error = nBytes;
-                                                                          
-                                                                       
printf("%d data chunks written\n",chunk);
-                                                               }
-                                                               else
-                                                               {
-                                                                       
perror("Error opening file");
-                                                               }
-                                                               close(h);
-                                                               
-                                                       }                       
                                
-                                                                               
                                
-                                               }
-                                               else if(S_ISSOCK(stats.st_mode))
-                                               {
-                                                       printf("socket\n");
-                                                       error =  
write_object_header(newObj, YAFFS_OBJECT_TYPE_SPECIAL, &stats, parent, 
entry->d_name, -1, NULL);
-                                               }
-                                               else if(S_ISFIFO(stats.st_mode))
-                                               {
-                                                       printf("fifo\n");
-                                                       error =  
write_object_header(newObj, YAFFS_OBJECT_TYPE_SPECIAL, &stats, parent, 
entry->d_name, -1, NULL);
-                                               }
-                                               else if(S_ISCHR(stats.st_mode))
-                                               {
-                                                       printf("character 
device\n");
-                                                       error =  
write_object_header(newObj, YAFFS_OBJECT_TYPE_SPECIAL, &stats, parent, 
entry->d_name, -1, NULL);
-                                               }
-                                               else if(S_ISBLK(stats.st_mode))
-                                               {
-                                                       printf("block 
device\n");
-                                                       error =  
write_object_header(newObj, YAFFS_OBJECT_TYPE_SPECIAL, &stats, parent, 
entry->d_name, -1, NULL);
-                                               }
-                                               else if(S_ISDIR(stats.st_mode))
-                                               {
-                                                       printf("directory\n");
-                                                       error =  
write_object_header(newObj, YAFFS_OBJECT_TYPE_DIRECTORY, &stats, parent, 
entry->d_name, -1, NULL);
-// NCB modified 10/9/2001                              
process_directory(1,full_name);
-                                                       
process_directory(newObj,full_name);
-                                               }
-                                       }
-                               }
-                               else
-                               {
-                                       printf(" we don't handle this type\n");
-                               }
+                               process_entry(entry, parent, full_name);
                        }
+               
                }
        }
        
@@ -455,27 +568,113 @@
 }
 
 
+char *in_file, *out_file;
+
+void usage()
+{
+  printf("usage: mkyaffsimage -c -s <size> dir image_file\n");
+  printf("           -c  produce a big-endian image from a little-endian 
machine\n");
+  printf("           -P  show progress\n");
+  printf("           -b  produce a big-endian image\n");
+  printf("           -l  produce a little-endian image\n");
+  
+  printf("           -s <size>  size of block in flash(minus spares in 
NAND)\n");
+  printf("           -N  produce a NAND image(if not set assume NOR)\n");
+  printf("           -p <file>  permission file to remap owner/group from\n");
+  printf("           -r         If no user/group in file, make root/wheel\n");
+  printf("           -D <file> Device table file to create in target image\n");
+  printf("           dir        the directory tree to be converted\n");
+  printf("           image_file the output file to hold the image\n");
+  exit(1);
+}
+
+union {
+  unsigned char c[2];
+  unsigned short s;
+} u_endian;
+
+void determine_endianess(void)
+{
+
+  u_endian.c[0] = '6';
+  u_endian.c[1] = '8';
+
+  if (u_endian.s == (('6'<<8)|'8'))
+    big_endian = 1;
+  if (u_endian.s == (('8'<<8)|'6'))
+    little_endian = 1;
+}
+
+
 int main(int argc, char *argv[])
 {
        struct stat stats;
-       
-       printf("mkyaffs2image: image building tool for YAFFS2 built 
"__DATE__"\n");
-       
-       if(argc < 3)
+       int i;
+
+       determine_endianess();
+
+       for (i=1; i<argc; ++i) {
+               if (argv[i][0] == '-') {
+                       if (argv[i][1] == 'd')
+                               debug = 1;
+                       else if (argv[i][1] == 'c')
+                               convert_endian = 1;
+                       else if (argv[i][1] == 'b')
+                               want_big_endian = 1;
+                       else if (argv[i][1] == 'l')
+                               want_little_endian = 1;
+                       else if (argv[i][1] == 'r')
+                               remap_ownership = 1;
+                       else if (argv[i][1] == 'P')
+                               progress = 1;
+                       else if (argv[i][1] == 'D') {
+                               if (argv[i][2] != '\0')
+                                       dev_table_name = &argv[i][2];
+                               else
+                                       if (++i == argc) {
+                                               printf("device table arg 
missing constant\n");
+                                               usage();
+                                       }
+                               dev_table_name = argv[i];
+                       } else if (argv[i][1] == 'p') {
+                               if (argv[i][2] != '\0')
+                                       pw_name = &argv[i][2];
+                               else
+                                       if (++i == argc) {
+                                               printf("size arg missing 
constant\n");
+                                               usage();
+                                       }
+                               pw_name = argv[i];
+                       }
+               } else {
+                       if (!in_file)
+                               in_file = argv[i];
+                       else if (!out_file)
+                               out_file = argv[i];
+                       else {
+                               printf("Extra file designator '%s'\n",argv[i]);
+                               usage();
+                       }
+               }
+       }
+
+       if (progress)
+               printf("mkyaffs2image: image building tool for YAFFS2 built 
"__DATE__"\n");
+
+       if (!in_file)
        {
-               printf("usage: mkyaffs2image dir image_file [convert]\n");
-               printf("           dir        the directory tree to be 
converted\n");
-               printf("           image_file the output file to hold the 
image\n");
-        printf("           'convert'  produce a big-endian image from a 
little-endian machine\n");
-               exit(1);
+               printf("Input directory not specified\n");
+               usage();
+       }
+
+       if (!out_file)
+       {
+               printf("Output file not specified\n");
+               usage();
        }
 
-    if ((argc == 4) && (!strncmp(argv[3], "convert", strlen("convert"))))
-    {
-        convert_endian = 1;
-    }
     
-       if(stat(argv[1],&stats) < 0)
+       if(stat(in_file,&stats) < 0)
        {
                printf("Could not stat %s\n",argv[1]);
                exit(1);
@@ -487,7 +686,7 @@
                exit(1);
        }
        
-       outFile = open(argv[2],O_CREAT | O_TRUNC | O_WRONLY, S_IREAD | 
S_IWRITE);
+       outFile = open(out_file,O_CREAT | O_TRUNC | O_WRONLY, S_IREAD | 
S_IWRITE | S_IRGRP | S_IROTH);
        
        
        if(outFile < 0)
@@ -496,10 +695,30 @@
                exit(1);
        }
        
-       printf("Processing directory %s into image file %s\n",argv[1],argv[2]);
+       if (!pw_name)
+               pw_name = "/etc/passwd";
+       process_pw_file(pw_name);
+
+       if (dev_table_name) {
+               FILE *f;
+
+               f = fopen(dev_table_name, "r");
+               if (!f) {
+                       fprintf(stderr, "Can't open '%s' for reading\n", 
dev_table_name);
+                       exit(-1);
+               }
+               parse_device_table(f);
+               fclose(f);
+               // dump_dev_tree();
+       }
+
+       printf("Processing directory %s into image file %s\n",in_file, 
out_file);
        error =  write_object_header(1, YAFFS_OBJECT_TYPE_DIRECTORY, &stats, 
1,"", -1, NULL);
        if(error)
        error = process_directory(YAFFS_OBJECTID_ROOT,argv[1]);
+
+       post_build_dev_tree();
+       add_dev_table_entries();
        
        close(outFile);
        
diff --exclude CVS --exclude .git -uNr 
yaffs_utils-20060418/yaffs2/utils/mkyaffsimage.c 
yaffs_utils-20060418.modified/yaffs2/utils/mkyaffsimage.c
--- yaffs_utils-20060418/yaffs2/utils/mkyaffsimage.c    2006-04-24 
07:39:48.000000000 -0400
+++ yaffs_utils-20060418.modified/yaffs2/utils/mkyaffsimage.c   2009-11-03 
12:29:01.000000000 -0500
@@ -115,6 +115,7 @@
        return -1;
 }
 
+#if 0
 // NCB added 10/9/2002
 static __u16 yaffs_CalcNameSum(const char *name)
 {
@@ -131,6 +132,7 @@
        }
        return sum;
 }
+#endif
 
 
 static void yaffs_CalcECC(const __u8 *data, yaffs_Spare *spare)
@@ -323,8 +325,6 @@
     oh->roomToGrow[7] = SWAP32(oh->roomToGrow[7]);
     oh->roomToGrow[8] = SWAP32(oh->roomToGrow[8]);
     oh->roomToGrow[9] = SWAP32(oh->roomToGrow[9]);
-    oh->roomToGrow[10] = SWAP32(oh->roomToGrow[10]);
-    oh->roomToGrow[11] = SWAP32(oh->roomToGrow[11]);
 #endif
 }
 
diff --exclude CVS --exclude .git -uNr 
yaffs_utils-20060418/yaffs2/utils/yaffs_ecc.c 
yaffs_utils-20060418.modified/yaffs2/utils/yaffs_ecc.c
--- yaffs_utils-20060418/yaffs2/utils/yaffs_ecc.c       1969-12-31 
19:00:00.000000000 -0500
+++ yaffs_utils-20060418.modified/yaffs2/utils/yaffs_ecc.c      2006-04-24 
07:39:43.000000000 -0400
@@ -0,0 +1,329 @@
+/*
+ * YAFFS: Yet another FFS. A NAND-flash specific file system. 
+ *
+ * yaffs_ecc.c: ECC generation/correction algorithms.
+ *
+ * Copyright (C) 2002 Aleph One Ltd.
+ *
+ * Created by Charles Manning <address@hidden>
+ *
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * version 2.1 as published by the Free Software Foundation.
+ */
+
+ /*
+  * This code implements the ECC algorithm used in SmartMedia.
+  *
+  * The ECC comprises 22 bits of parity information and is stuffed into 3 
bytes. 
+  * The two unused bit are set to 1.
+  * The ECC can correct single bit errors in a 256-byte page of data. Thus, 
two such ECC 
+  * blocks are used on a 512-byte NAND page.
+  *
+  */
+
+/* Table generated by gen-ecc.c
+ * Using a table means we do not have to calculate p1..p4 and p1'..p4'
+ * for each byte of data. These are instead provided in a table in bits7..2.
+ * Bit 0 of each entry indicates whether the entry has an odd or even parity, 
and therefore
+ * this bytes influence on the line parity.
+ */
+
+const char *yaffs_ecc_c_version =
+    "$Id: yaffs_ecc.c,v 1.6 2005/08/11 02:51:49 charles Exp $";
+
+#include "yportenv.h"
+
+#include "yaffs_ecc.h"
+
+static const unsigned char column_parity_table[] = {
+       0x00, 0x55, 0x59, 0x0c, 0x65, 0x30, 0x3c, 0x69,
+       0x69, 0x3c, 0x30, 0x65, 0x0c, 0x59, 0x55, 0x00,
+       0x95, 0xc0, 0xcc, 0x99, 0xf0, 0xa5, 0xa9, 0xfc,
+       0xfc, 0xa9, 0xa5, 0xf0, 0x99, 0xcc, 0xc0, 0x95,
+       0x99, 0xcc, 0xc0, 0x95, 0xfc, 0xa9, 0xa5, 0xf0,
+       0xf0, 0xa5, 0xa9, 0xfc, 0x95, 0xc0, 0xcc, 0x99,
+       0x0c, 0x59, 0x55, 0x00, 0x69, 0x3c, 0x30, 0x65,
+       0x65, 0x30, 0x3c, 0x69, 0x00, 0x55, 0x59, 0x0c,
+       0xa5, 0xf0, 0xfc, 0xa9, 0xc0, 0x95, 0x99, 0xcc,
+       0xcc, 0x99, 0x95, 0xc0, 0xa9, 0xfc, 0xf0, 0xa5,
+       0x30, 0x65, 0x69, 0x3c, 0x55, 0x00, 0x0c, 0x59,
+       0x59, 0x0c, 0x00, 0x55, 0x3c, 0x69, 0x65, 0x30,
+       0x3c, 0x69, 0x65, 0x30, 0x59, 0x0c, 0x00, 0x55,
+       0x55, 0x00, 0x0c, 0x59, 0x30, 0x65, 0x69, 0x3c,
+       0xa9, 0xfc, 0xf0, 0xa5, 0xcc, 0x99, 0x95, 0xc0,
+       0xc0, 0x95, 0x99, 0xcc, 0xa5, 0xf0, 0xfc, 0xa9,
+       0xa9, 0xfc, 0xf0, 0xa5, 0xcc, 0x99, 0x95, 0xc0,
+       0xc0, 0x95, 0x99, 0xcc, 0xa5, 0xf0, 0xfc, 0xa9,
+       0x3c, 0x69, 0x65, 0x30, 0x59, 0x0c, 0x00, 0x55,
+       0x55, 0x00, 0x0c, 0x59, 0x30, 0x65, 0x69, 0x3c,
+       0x30, 0x65, 0x69, 0x3c, 0x55, 0x00, 0x0c, 0x59,
+       0x59, 0x0c, 0x00, 0x55, 0x3c, 0x69, 0x65, 0x30,
+       0xa5, 0xf0, 0xfc, 0xa9, 0xc0, 0x95, 0x99, 0xcc,
+       0xcc, 0x99, 0x95, 0xc0, 0xa9, 0xfc, 0xf0, 0xa5,
+       0x0c, 0x59, 0x55, 0x00, 0x69, 0x3c, 0x30, 0x65,
+       0x65, 0x30, 0x3c, 0x69, 0x00, 0x55, 0x59, 0x0c,
+       0x99, 0xcc, 0xc0, 0x95, 0xfc, 0xa9, 0xa5, 0xf0,
+       0xf0, 0xa5, 0xa9, 0xfc, 0x95, 0xc0, 0xcc, 0x99,
+       0x95, 0xc0, 0xcc, 0x99, 0xf0, 0xa5, 0xa9, 0xfc,
+       0xfc, 0xa9, 0xa5, 0xf0, 0x99, 0xcc, 0xc0, 0x95,
+       0x00, 0x55, 0x59, 0x0c, 0x65, 0x30, 0x3c, 0x69,
+       0x69, 0x3c, 0x30, 0x65, 0x0c, 0x59, 0x55, 0x00,
+};
+
+/* Count the bits in an unsigned char or a U32 */
+
+static int yaffs_CountBits(unsigned char x)
+{
+       int r = 0;
+       while (x) {
+               if (x & 1)
+                       r++;
+               x >>= 1;
+       }
+       return r;
+}
+
+static int yaffs_CountBits32(unsigned x)
+{
+       int r = 0;
+       while (x) {
+               if (x & 1)
+                       r++;
+               x >>= 1;
+       }
+       return r;
+}
+
+/* Calculate the ECC for a 256-byte block of data */
+void yaffs_ECCCalculate(const unsigned char *data, unsigned char *ecc)
+{
+       unsigned int i;
+
+       unsigned char col_parity = 0;
+       unsigned char line_parity = 0;
+       unsigned char line_parity_prime = 0;
+       unsigned char t;
+       unsigned char b;
+
+       for (i = 0; i < 256; i++) {
+               b = column_parity_table[*data++];
+               col_parity ^= b;
+
+               if (b & 0x01)   // odd number of bits in the byte
+               {
+                       line_parity ^= i;
+                       line_parity_prime ^= ~i;
+               }
+
+       }
+
+       ecc[2] = (~col_parity) | 0x03;
+
+       t = 0;
+       if (line_parity & 0x80)
+               t |= 0x80;
+       if (line_parity_prime & 0x80)
+               t |= 0x40;
+       if (line_parity & 0x40)
+               t |= 0x20;
+       if (line_parity_prime & 0x40)
+               t |= 0x10;
+       if (line_parity & 0x20)
+               t |= 0x08;
+       if (line_parity_prime & 0x20)
+               t |= 0x04;
+       if (line_parity & 0x10)
+               t |= 0x02;
+       if (line_parity_prime & 0x10)
+               t |= 0x01;
+       ecc[1] = ~t;
+
+       t = 0;
+       if (line_parity & 0x08)
+               t |= 0x80;
+       if (line_parity_prime & 0x08)
+               t |= 0x40;
+       if (line_parity & 0x04)
+               t |= 0x20;
+       if (line_parity_prime & 0x04)
+               t |= 0x10;
+       if (line_parity & 0x02)
+               t |= 0x08;
+       if (line_parity_prime & 0x02)
+               t |= 0x04;
+       if (line_parity & 0x01)
+               t |= 0x02;
+       if (line_parity_prime & 0x01)
+               t |= 0x01;
+       ecc[0] = ~t;
+
+#ifdef CONFIG_YAFFS_ECC_WRONG_ORDER
+       // Swap the bytes into the wrong order
+       t = ecc[0];
+       ecc[0] = ecc[1];
+       ecc[1] = t;
+#endif
+}
+
+
+/* Correct the ECC on a 256 byte block of data */
+
+int yaffs_ECCCorrect(unsigned char *data, unsigned char *read_ecc,
+                    const unsigned char *test_ecc)
+{
+       unsigned char d0, d1, d2;       /* deltas */
+
+       d0 = read_ecc[0] ^ test_ecc[0];
+       d1 = read_ecc[1] ^ test_ecc[1];
+       d2 = read_ecc[2] ^ test_ecc[2];
+
+       if ((d0 | d1 | d2) == 0)
+               return 0; /* no error */
+
+       if (((d0 ^ (d0 >> 1)) & 0x55) == 0x55 &&
+           ((d1 ^ (d1 >> 1)) & 0x55) == 0x55 &&
+           ((d2 ^ (d2 >> 1)) & 0x54) == 0x54) {
+               /* Single bit (recoverable) error in data */
+
+               unsigned byte;
+               unsigned bit;
+
+#ifdef CONFIG_YAFFS_ECC_WRONG_ORDER
+               // swap the bytes to correct for the wrong order
+               unsigned char t;
+
+               t = d0;
+               d0 = d1;
+               d1 = t;
+#endif
+
+               bit = byte = 0;
+
+               if (d1 & 0x80)
+                       byte |= 0x80;
+               if (d1 & 0x20)
+                       byte |= 0x40;
+               if (d1 & 0x08)
+                       byte |= 0x20;
+               if (d1 & 0x02)
+                       byte |= 0x10;
+               if (d0 & 0x80)
+                       byte |= 0x08;
+               if (d0 & 0x20)
+                       byte |= 0x04;
+               if (d0 & 0x08)
+                       byte |= 0x02;
+               if (d0 & 0x02)
+                       byte |= 0x01;
+
+               if (d2 & 0x80)
+                       bit |= 0x04;
+               if (d2 & 0x20)
+                       bit |= 0x02;
+               if (d2 & 0x08)
+                       bit |= 0x01;
+
+               data[byte] ^= (1 << bit);
+
+               return 1; /* Corrected the error */
+       }
+
+       if ((yaffs_CountBits(d0) + 
+            yaffs_CountBits(d1) + 
+            yaffs_CountBits(d2)) ==  1) {
+               /* Reccoverable error in ecc */
+
+               read_ecc[0] = test_ecc[0];
+               read_ecc[1] = test_ecc[1];
+               read_ecc[2] = test_ecc[2];
+
+               return 1; /* Corrected the error */
+       }
+       
+       /* Unrecoverable error */
+
+       return -1;
+
+}
+
+
+/*
+ * ECCxxxOther does ECC calcs on arbitrary n bytes of data
+ */
+void yaffs_ECCCalculateOther(const unsigned char *data, unsigned nBytes,
+                            yaffs_ECCOther * eccOther)
+{
+       unsigned int i;
+
+       unsigned char col_parity = 0;
+       unsigned line_parity = 0;
+       unsigned line_parity_prime = 0;
+       unsigned char b;
+
+       for (i = 0; i < nBytes; i++) {
+               b = column_parity_table[*data++];
+               col_parity ^= b;
+
+               if (b & 0x01)    {
+                       /* odd number of bits in the byte */
+                       line_parity ^= i;
+                       line_parity_prime ^= ~i;
+               }
+
+       }
+
+       eccOther->colParity = (col_parity >> 2) & 0x3f;
+       eccOther->lineParity = line_parity;
+       eccOther->lineParityPrime = line_parity_prime;
+}
+
+int yaffs_ECCCorrectOther(unsigned char *data, unsigned nBytes,
+                         yaffs_ECCOther * read_ecc,
+                         const yaffs_ECCOther * test_ecc)
+{
+       unsigned char cDelta;   /* column parity delta */
+       unsigned lDelta;        /* line parity delta */
+       unsigned lDeltaPrime;   /* line parity delta */
+       unsigned bit;
+
+       cDelta = read_ecc->colParity ^ test_ecc->colParity;
+       lDelta = read_ecc->lineParity ^ test_ecc->lineParity;
+       lDeltaPrime = read_ecc->lineParityPrime ^ test_ecc->lineParityPrime;
+
+       if ((cDelta | lDelta | lDeltaPrime) == 0)
+               return 0; /* no error */
+
+       if (lDelta == ~lDeltaPrime && (((cDelta ^ (cDelta >> 1)) & 0x15) == 
0x15))
+       {
+               /* Single bit (recoverable) error in data */
+
+               bit = 0;
+
+               if (cDelta & 0x20)
+                       bit |= 0x04;
+               if (cDelta & 0x08)
+                       bit |= 0x02;
+               if (cDelta & 0x02)
+                       bit |= 0x01;
+
+               data[lDelta] ^= (1 << bit);
+
+               return 1; /* corrected */
+       }
+
+       if ((yaffs_CountBits32(lDelta) + yaffs_CountBits32(lDeltaPrime) +
+            yaffs_CountBits(cDelta)) == 1) {
+               /* Reccoverable error in ecc */
+
+               *read_ecc = *test_ecc;
+               return 1; /* corrected */
+       }
+
+       /* Unrecoverable error */
+
+       return -1;
+
+}
+
diff --exclude CVS --exclude .git -uNr 
yaffs_utils-20060418/yaffs2/utils/yaffs_packedtags2.c 
yaffs_utils-20060418.modified/yaffs2/utils/yaffs_packedtags2.c
--- yaffs_utils-20060418/yaffs2/utils/yaffs_packedtags2.c       1969-12-31 
19:00:00.000000000 -0500
+++ yaffs_utils-20060418.modified/yaffs2/utils/yaffs_packedtags2.c      
2006-04-24 07:39:43.000000000 -0400
@@ -0,0 +1,170 @@
+/*
+ * YAFFS: Yet another FFS. A NAND-flash specific file system. 
+ *
+ * yaffs_packedtags2.c: Tags packing for YAFFS2
+ *
+ * Copyright (C) 2002 Aleph One Ltd.
+ *
+ * Created by Charles Manning <address@hidden>
+ *
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * version 2.1 as published by the Free Software Foundation.
+ */
+
+#include "yaffs_packedtags2.h"
+#include "yportenv.h"
+#include "yaffs_tagsvalidity.h"
+
+/* This code packs a set of extended tags into a binary structure for
+ * NAND storage
+ */
+
+/* Some of the information is "extra" struff which can be packed in to
+ * speed scanning
+ * This is defined by having the EXTRA_HEADER_INFO_FLAG set.
+ */
+
+/* Extra flags applied to chunkId */
+
+#define EXTRA_HEADER_INFO_FLAG 0x80000000
+#define EXTRA_SHRINK_FLAG      0x40000000
+#define EXTRA_SHADOWS_FLAG     0x20000000
+#define EXTRA_SPARE_FLAGS      0x10000000
+
+#define ALL_EXTRA_FLAGS                0xF0000000
+
+/* Also, the top 4 bits of the object Id are set to the object type. */
+#define EXTRA_OBJECT_TYPE_SHIFT (28)
+#define EXTRA_OBJECT_TYPE_MASK  ((0x0F) << EXTRA_OBJECT_TYPE_SHIFT)
+
+static void yaffs_DumpPackedTags2(const yaffs_PackedTags2 * pt)
+{
+       T(YAFFS_TRACE_MTD,
+         (TSTR("packed tags obj %d chunk %d byte %d seq %d" TENDSTR),
+          pt->t.objectId, pt->t.chunkId, pt->t.byteCount,
+          pt->t.sequenceNumber));
+}
+
+static void yaffs_DumpTags2(const yaffs_ExtendedTags * t)
+{
+       T(YAFFS_TRACE_MTD,
+         (TSTR
+          ("ext.tags eccres %d blkbad %d chused %d obj %d chunk%d byte "
+           "%d del %d ser %d seq %d"
+           TENDSTR), t->eccResult, t->blockBad, t->chunkUsed, t->objectId,
+          t->chunkId, t->byteCount, t->chunkDeleted, t->serialNumber,
+          t->sequenceNumber));
+
+}
+
+void yaffs_PackTags2(yaffs_PackedTags2 * pt, const yaffs_ExtendedTags * t)
+{
+       pt->t.chunkId = t->chunkId;
+       pt->t.sequenceNumber = t->sequenceNumber;
+       pt->t.byteCount = t->byteCount;
+       pt->t.objectId = t->objectId;
+
+       if (t->chunkId == 0 && t->extraHeaderInfoAvailable) {
+               /* Store the extra header info instead */
+               /* We save the parent object in the chunkId */
+               pt->t.chunkId = EXTRA_HEADER_INFO_FLAG
+                       | t->extraParentObjectId;
+               if (t->extraIsShrinkHeader) {
+                       pt->t.chunkId |= EXTRA_SHRINK_FLAG;
+               }
+               if (t->extraShadows) {
+                       pt->t.chunkId |= EXTRA_SHADOWS_FLAG;
+               }
+
+               pt->t.objectId &= ~EXTRA_OBJECT_TYPE_MASK;
+               pt->t.objectId |=
+                   (t->extraObjectType << EXTRA_OBJECT_TYPE_SHIFT);
+
+               if (t->extraObjectType == YAFFS_OBJECT_TYPE_HARDLINK) {
+                       pt->t.byteCount = t->extraEquivalentObjectId;
+               } else if (t->extraObjectType == YAFFS_OBJECT_TYPE_FILE) {
+                       pt->t.byteCount = t->extraFileLength;
+               } else {
+                       pt->t.byteCount = 0;
+               }
+       }
+
+       yaffs_DumpPackedTags2(pt);
+       yaffs_DumpTags2(t);
+
+#ifndef YAFFS_IGNORE_TAGS_ECC
+       {
+               yaffs_ECCCalculateOther((unsigned char *)&pt->t,
+                                       sizeof(yaffs_PackedTags2TagsPart),
+                                       &pt->ecc);
+       }
+#endif
+}
+
+void yaffs_UnpackTags2(yaffs_ExtendedTags * t, yaffs_PackedTags2 * pt)
+{
+
+       memset(t, 0, sizeof(yaffs_ExtendedTags));
+
+       yaffs_InitialiseTags(t);
+
+       if (pt->t.sequenceNumber != 0xFFFFFFFF) {
+               /* Page is in use */
+#ifdef YAFFS_IGNORE_TAGS_ECC
+               {
+                       t->eccResult = 0;
+               }
+#else
+               {
+                       yaffs_ECCOther ecc;
+                       yaffs_ECCCalculateOther((unsigned char *)&pt->t,
+                                               sizeof
+                                               (yaffs_PackedTags2TagsPart),
+                                               &ecc);
+                       t->eccResult =
+                           yaffs_ECCCorrectOther((unsigned char *)&pt->t,
+                                                 sizeof
+                                                 (yaffs_PackedTags2TagsPart),
+                                                 &pt->ecc, &ecc);
+               }
+#endif
+               t->blockBad = 0;
+               t->chunkUsed = 1;
+               t->objectId = pt->t.objectId;
+               t->chunkId = pt->t.chunkId;
+               t->byteCount = pt->t.byteCount;
+               t->chunkDeleted = 0;
+               t->serialNumber = 0;
+               t->sequenceNumber = pt->t.sequenceNumber;
+
+               /* Do extra header info stuff */
+
+               if (pt->t.chunkId & EXTRA_HEADER_INFO_FLAG) {
+                       t->chunkId = 0;
+                       t->byteCount = 0;
+
+                       t->extraHeaderInfoAvailable = 1;
+                       t->extraParentObjectId =
+                           pt->t.chunkId & (~(ALL_EXTRA_FLAGS));
+                       t->extraIsShrinkHeader =
+                           (pt->t.chunkId & EXTRA_SHRINK_FLAG) ? 1 : 0;
+                       t->extraShadows =
+                           (pt->t.chunkId & EXTRA_SHADOWS_FLAG) ? 1 : 0;
+                       t->extraObjectType =
+                           pt->t.objectId >> EXTRA_OBJECT_TYPE_SHIFT;
+                       t->objectId &= ~EXTRA_OBJECT_TYPE_MASK;
+
+                       if (t->extraObjectType == YAFFS_OBJECT_TYPE_HARDLINK) {
+                               t->extraEquivalentObjectId = pt->t.byteCount;
+                       } else {
+                               t->extraFileLength = pt->t.byteCount;
+                       }
+               }
+       }
+
+       yaffs_DumpPackedTags2(pt);
+       yaffs_DumpTags2(t);
+
+}
diff --exclude CVS --exclude .git -uNr 
yaffs_utils-20060418/yaffs2/utils/yaffs_tagsvalidity.c 
yaffs_utils-20060418.modified/yaffs2/utils/yaffs_tagsvalidity.c
--- yaffs_utils-20060418/yaffs2/utils/yaffs_tagsvalidity.c      1969-12-31 
19:00:00.000000000 -0500
+++ yaffs_utils-20060418.modified/yaffs2/utils/yaffs_tagsvalidity.c     
2006-04-24 07:39:43.000000000 -0400
@@ -0,0 +1,31 @@
+
+/*
+ * YAFFS: Yet another FFS. A NAND-flash specific file system. 
+ *
+ * Copyright (C) 2002 Aleph One Ltd.
+ *   for Toby Churchill Ltd and Brightstar Engineering
+ *
+ * Created by Charles Manning <address@hidden>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * $Id: yaffs_tagsvalidity.c,v 1.2 2005/08/11 02:33:03 marty Exp $
+ */
+
+#include "yaffs_tagsvalidity.h"
+
+void yaffs_InitialiseTags(yaffs_ExtendedTags * tags)
+{
+       memset(tags, 0, sizeof(yaffs_ExtendedTags));
+       tags->validMarker0 = 0xAAAAAAAA;
+       tags->validMarker1 = 0x55555555;
+}
+
+int yaffs_ValidateTags(yaffs_ExtendedTags * tags)
+{
+       return (tags->validMarker0 == 0xAAAAAAAA &&
+               tags->validMarker1 == 0x55555555);
+
+}
diff --exclude CVS --exclude .git -uNr yaffs_utils-20060418/yaffs2/yaffs_guts.h 
yaffs_utils-20060418.modified/yaffs2/yaffs_guts.h
--- yaffs_utils-20060418/yaffs2/yaffs_guts.h    2006-04-24 07:39:43.000000000 
-0400
+++ yaffs_utils-20060418.modified/yaffs2/yaffs_guts.h   2009-11-03 
12:22:29.000000000 -0500
@@ -691,8 +691,10 @@
 unsigned yaffs_GetObjectType(yaffs_Object * obj);
 int yaffs_GetObjectLinkCount(yaffs_Object * obj);
 
+#if !defined(CONFIG_YAFFS_UTIL)
 int yaffs_SetAttributes(yaffs_Object * obj, struct iattr *attr);
 int yaffs_GetAttributes(yaffs_Object * obj, struct iattr *attr);
+#endif
 
 /* File operations */
 int yaffs_ReadDataFromFile(yaffs_Object * obj, __u8 * buffer, __u32 offset,
Index: .ltibrc
===================================================================
RCS file: /sources/ltib/ltib/.ltibrc,v
retrieving revision 1.13
diff -u -r1.13 .ltibrc
--- .ltibrc     28 Sep 2009 13:37:49 -0000      1.13
+++ .ltibrc     7 Nov 2009 09:56:41 -0000
@@ -96,8 +96,12 @@
 %CCACHE_DIR
 $home/.ccache
 
+# control whether datestamps are UTC (default) or localtime
+#%use_localtime
+#0
+
 # This is used to trigger re-running the host install package
 # pass.  Bump this number up if you update a host support
 # package and you want to force others to install this update
 %host_wait_warning
-.host_wait_warning32
+.host_wait_warning33
Index: ltib
===================================================================
RCS file: /sources/ltib/ltib/ltib,v
retrieving revision 1.54
diff -u -r1.54 ltib
--- ltib        5 Nov 2009 17:03:10 -0000       1.54
+++ ltib        7 Nov 2009 09:56:43 -0000
@@ -799,6 +799,11 @@
                     # needed if the lpp moves and links break
                     unlink($tgt);
 
+                    # if $src is relative, then prefix it with "$cf->{top}/"
+                    # to make the rpm/SOURCE/$tgt symbolic link absolute
+                    if ($src !~ m/^\//) {
+                        $src = "$cf->{top}/$src";
+                    }
                     symlink($src, $tgt)
                             or die("symlink $cf->{lpp}/$file, $tgt: $!");
                 }
@@ -1521,7 +1526,7 @@
                        if ! defined $ENV{DISTCC_HOSTS} && $cf->{DISTCC_HOSTS};
         $ENV{DISTCC_TCP_CORK} = $cf->{DISTCC_TCP_CORK}
          if ! defined $ENV{DISTCC_TCP_CORK} && defined $cf->{DISTCC_TCP_CORK};
-       $ENV{MAKEFLAGS} = $cf->{MAKEFLAGS}
+            $ENV{MAKEFLAGS} = $cf->{MAKEFLAGS}
                              if ! defined $ENV{MAKEFLAGS} && $cf->{MAKEFLAGS};
         if(! defined $ENV{CCACHE_DIR} && $cf->{CCACHE_DIR}) {
             $ENV{CCACHE_DIR} = $cf->{CCACHE_DIR}; 
Index: bin/Ltibutils.pm
===================================================================
RCS file: /sources/ltib/ltib/bin/Ltibutils.pm,v
retrieving revision 1.33
diff -u -r1.33 Ltibutils.pm
--- bin/Ltibutils.pm    27 Oct 2009 10:12:15 -0000      1.33
+++ bin/Ltibutils.pm    7 Nov 2009 09:56:44 -0000
@@ -103,10 +103,18 @@
     return $hr;
 }
 
+#
+# gm_yyyymmdd can return the date, either in GMT, or in localtime.
+# Usefull when the local timezone is far away from GMT.
 sub gm_yyyymmdd
 {
-    my($day, $month, $year) = (gmtime)[3,4,5];
-    return sprintf("%04d%02d%02d", $year+1900, $month+1, $day);
+    if ($cf->{use_localtime}) {
+        my ($day, $month, $year) = (localtime)[3,4,5];
+        return sprintf("%04d%02d%02d", $year+1900, $month+1, $day);
+    } else {
+        my ($day, $month, $year) = (gmtime)[3,4,5];
+        return sprintf("%04d%02d%02d", $year+1900, $month+1, $day);
+    }
 }
 
 sub parse_config
@@ -659,6 +667,8 @@
     my $x = $verbose ? '-x' : '';
     my $v = $verbose ? '-v' : '';
     my $cmd;
+    my $cur_date = gm_yyyymmdd();
+    my $elf_datestamp = $pcf->{DEPLOYMENT_ELF_DATESTAMP} ? "-$cur_date" : "";
 
     system_nb(<<TXT);
 set -e
@@ -673,6 +683,10 @@
 then
     rm -f $tdir/rootfs.jffs2
 fi
+if [ "$pcf->{DEPLOYMENT_YAFFS2}" = "y" ]
+then
+    rm -f $tdir/rootfs.yaffs2
+fi
 if [ "$pcf->{DEPLOYMENT_CRAMFS}" = "y" ]
 then
     rm -f $tdir/cramfs.*
@@ -867,6 +881,11 @@
     mkfs.jffs2 -n $pad_opt -D $dev_tab -U $endian -e 
$pcf->{DEPLOYMENT_ERASE_BLOCK_SIZE} -d $stage -o $tdir/rootfs.jffs2
     ln -sf $tdir/rootfs.jffs2 $tdir/rootfs_image
 fi
+if [ "$pcf->{DEPLOYMENT_YAFFS2}" = "y" ]
+then
+    mkfs.yaffs2 -r -p $stage/etc/passwd -N -D $dev_tab $endian $stage 
$tdir/rootfs.yaffs2
+    ln -sf $tdir/rootfs.yaffs2 $tdir/rootfs_image
+fi
 if [ "$pcf->{DEPLOYMENT_CRAMFS}" = "y" ]
 then
     mkfs.cramfs -q -D $dev_tab $endian $stage $tdir/rootfs.cramfs
@@ -925,6 +944,20 @@
         ln -sf $tdir/initramfs.cpio.gz.uboot $tdir/rootfs_image
     fi
 fi
+if [ "$pcf->{DEPLOYMENT_ELF}" = "y" ]
+then
+    elf_image="linux-demo-$pcf->{PLATFORM_ELF}$elf_datestamp.elf"
+    if [ "$pcf->{DEPLOY_RAMDISK_AND_ELF}" = "y" ]
+    then
+        echo "creating elf file that contains u-boot, kernel, ramdisk"
+        make -C \$PLATFORM_PATH/elf-image elf-with-rootfs 
UBOOT=$cf->{top}/rootfs/boot/u-boot.bin KERNEL=$cf->{top}/rootfs/boot/uImage 
ROOTFS=$cf->{top}/rootfs.ext2.gz.uboot IMAGE=$cf->{top}/\$elf_image
+    else
+        echo "creating elf file that contains u-boot, kernel, rootfs assumed 
elsewhere"
+        make -C \$PLATFORM_PATH/elf-image elf-without-rootfs 
UBOOT=$cf->{top}/rootfs/boot/u-boot.bin KERNEL=$cf->{top}/rootfs/boot/uImage 
IMAGE=$cf->{top}/\$elf_image
+    fi
+    ln -sf \$elf_image image.elf
+fi
+
 if [ "$pcf->{DEPLOYMENT_ROOTFS_KEEPSTAGE}" = "y" ]
 then
     echo "Saving temporary staging directory: $stage"
Index: config/platform/host/ltib.preconfig
===================================================================
RCS file: /sources/ltib/ltib/config/platform/host/ltib.preconfig,v
retrieving revision 1.3
diff -u -r1.3 ltib.preconfig
--- config/platform/host/ltib.preconfig 27 Aug 2009 08:31:14 -0000      1.3
+++ config/platform/host/ltib.preconfig 7 Nov 2009 09:56:44 -0000
@@ -377,7 +377,7 @@
 # CONFIG_PKG_XORG_X11_XKB_UTILS is not set
 # CONFIG_PKG_XORG_X11_TWM is not set
 # CONFIG_PKG_XTERM is not set
-# CONFIG_PKG_YAFFS_UTILS is not set
+CONFIG_PKG_YAFFS_UTILS=y
 # CONFIG_PKG_ZAPTEL is not set
 # CONFIG_PKG_ZLIB is not set
 
Index: config/userspace/deployment.lkc
===================================================================
RCS file: /sources/ltib/ltib/config/userspace/deployment.lkc,v
retrieving revision 1.4
diff -u -r1.4 deployment.lkc
--- config/userspace/deployment.lkc     14 Sep 2009 09:39:16 -0000      1.4
+++ config/userspace/deployment.lkc     7 Nov 2009 09:56:45 -0000
@@ -15,6 +15,11 @@
         help
             build a jffs2 flash filesystem image
 
+    config DEPLOYMENT_YAFFS2
+        bool "yaffs2"
+        help
+            build a yaffs2 flash filesystem image
+
     config DEPLOYMENT_RAMDISK
         bool "ext2.gz ramdisk"
         help
@@ -49,9 +54,27 @@
         area is always available
 endchoice
 
+if CAP_DEPLOYMENT_ELF && (DEPLOYMENT_JFFS2 \
+                      || DEPLOYMENT_YAFFS2 \
+                      || DEPLOYMENT_RAMDISK)
+config DEPLOYMENT_ELF
+       bool "Create a combined ELF image"
+       help
+            Create an ELF file that contains u-boot and the kernel.
+            If the deployment is "ramdisk", then link in the ramdisk
+            image as well.
+config DEPLOYMENT_ELF_DATESTAMP
+       depends DEPLOYMENT_ELF
+       bool "Add date to the ELF image filename"
+       help
+           If you set this option you will get a datestamp (yyyymmdd)
+           added to the image.
+endif
+
 config SYSCFG_DEPLOYMENT_STYLE
     string
     default JFFS2      if DEPLOYMENT_JFFS2
+    default YAFFS2     if DEPLOYMENT_YAFFS2
     default RAMDISK    if DEPLOYMENT_RAMDISK
     default CRAMFS     if DEPLOYMENT_CRAMFS
     default ROMFS      if DEPLOYMENT_ROMFS 
@@ -113,7 +136,7 @@
     default n
 
 config SYSCFG_TMPFS_SIZE
-    depends SYSCFG_READONLY_FS || DEPLOYMENT_JFFS2
+    depends SYSCFG_READONLY_FS || DEPLOYMENT_JFFS2 || DEPLOYMENT_YAFFS2
     string "tmpfs size"
     default "512k"
     help
@@ -124,10 +147,10 @@
        from the total available RAM to the system.
 
 config SYSCFG_RAM_DIRS
-    depends SYSCFG_READONLY_FS || DEPLOYMENT_JFFS2
+    depends SYSCFG_READONLY_FS || DEPLOYMENT_JFFS2 || DEPLOYMENT_YAFFS2
     string "Place these dirs in writable RAM"
     default "/tmp /etc /var" if SYSCFG_READONLY_FS
-    default "/tmp /var"      if DEPLOYMENT_JFFS2
+    default "/tmp /var"      if DEPLOYMENT_JFFS2 || DEPLOYMENT_YAFFS2
     help
        Flash may only be erased a finite number of times (of the order
        of 100000 times for a NOR device).  If you deploy to Flash,
@@ -256,7 +279,7 @@
         .ko are stripped like this.
 
 config DEPLOYMENT_PADDING_KB
-    depends ! DEPLOYMENT_NFS && ! DEPLOYMENT_JFFS2
+    depends ! DEPLOYMENT_NFS && ! DEPLOYMENT_JFFS2 && ! DEPLOYMENT_YAFFS2
     default "0"
     string "Allocate extra space (Kbytes)"
     help
Index: dist/lfs-5.1/yaffs-utils/yaffs-utils.spec
===================================================================
RCS file: /sources/ltib/ltib/dist/lfs-5.1/yaffs-utils/yaffs-utils.spec,v
retrieving revision 1.1.1.5
diff -u -r1.1.1.5 yaffs-utils.spec
--- dist/lfs-5.1/yaffs-utils/yaffs-utils.spec   4 Apr 2008 10:51:53 -0000       
1.1.1.5
+++ dist/lfs-5.1/yaffs-utils/yaffs-utils.spec   7 Nov 2009 09:56:46 -0000
@@ -3,7 +3,7 @@
 Summary         : YAFFS Utilities.
 Name            : yaffs_utils
 Version         : 20060418
-Release         : 1
+Release         : 2
 License         : GPL
 Vendor          : Freescale
 Packager        : Alan Tull
@@ -12,6 +12,7 @@
 Patch0          : yaffs_mxc.patch
 Patch1          : yaffs_utils-20060418-mtd-include.patch
 Patch2          : yaffs_utils-20060418-include-order.patch
+Patch3          : yaffs_utils-20060418-mkyaffs2image.patch
 BuildRoot       : %{_tmppath}/%{name}
 Prefix          : %{pfx}
 
@@ -26,14 +27,15 @@
 %patch0 -p1
 %patch1 -p1
 %patch2 -p1
+%patch3 -p1
 
 %Build
-make KERNELDIR=$DEV_IMAGE/usr/src/linux -C yaffs/utils
+make KERNELDIR=$DEV_IMAGE/usr/src/linux -C yaffs2/utils
 
 %Install
 rm -rf $RPM_BUILD_ROOT
 mkdir -p $RPM_BUILD_ROOT/%{pfx}/%{_prefix}/bin
-make -C yaffs/utils install DESTDIR=$RPM_BUILD_ROOT/%{pfx} 
SBINDIR=%{_prefix}/bin 
+make -C yaffs2/utils install DESTDIR=$RPM_BUILD_ROOT/%{pfx} 
SBINDIR=%{_prefix}/bin
 
 %Clean
 rm -rf $RPM_BUILD_ROOT

reply via email to

[Prev in Thread] Current Thread [Next in Thread]