diff --exclude CVS --exclude .git -uNr yaffs_utils-20060418/Makefile yaffs_utils-20060418.modified/Makefile --- yaffs_utils-20060418/Makefile 1969-12-31 19:00:00.000000000 -0500 +++ yaffs_utils-20060418.modified/Makefile 2009-11-09 11:37:40.000000000 -0500 @@ -0,0 +1,2 @@ +distclean: + make -C yaffs2/utils clean 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-09 11:37:40.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-09 12:09:43.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 = -Wall -DCONFIG_YAFFS_UTIL -I.. -g $(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=mkfs.yaffs mkfs.yaffs2 +all: $(TARGETS) $(COMMONLINKS) $(MKYAFFSLINKS) $(MKYAFFS2LINKS): ln -s ../$@ $@ @@ -43,12 +45,15 @@ $(COMMONOBJS) $(MKYAFFSIMAGEOBJS) $(MKYAFFS2IMAGEOBJS) : %.o: %.c $(CC) -c $(CFLAGS) $< -o $@ -mkyaffsimage: $(COMMONOBJS) $(MKYAFFSIMAGEOBJS) - $(CC) -o $@ $(COMMONOBJS) $(MKYAFFSIMAGEOBJS) +mkfs.yaffs: $(COMMONOBJS) $(MKYAFFSIMAGEOBJS) + $(CC) -o $@ $(CFLAGS) $(COMMONOBJS) $(MKYAFFSIMAGEOBJS) -mkyaffs2image: $(COMMONOBJS) $(MKYAFFS2IMAGEOBJS) - $(CC) -o $@ $(COMMONOBJS) $(MKYAFFS2IMAGEOBJS) +mkfs.yaffs2: $(COMMONOBJS) $(MKYAFFS2IMAGEOBJS) + $(CC) -o $@ $(CFLAGS) $(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-09 11:37:40.000000000 -0500 @@ -0,0 +1,481 @@ +/* + * YAFFS: Yet Another Flash File System. A NAND-flash specific file system. + * + * Copyright 2001, 2002 Red Hat, Inc. + * 2001 David A. Schleef + * 2002 Axis Communications AB + * 2001, 2002 Erik Andersen + * 2004 University of Szeged, Hungary + * 2006 KaiGai Kohei + * 2009 Logic Product Development, Inc. + * + * Created from mkfs.jffs2 utility + * + * 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. + */ + +#define _GNU_SOURCE +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#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 *stats) +{ + struct deventry *p; + + p = find_dev_table_entry(path); + if (!p || p->dumped) + return 0; + + p->dumped = 1; + + memset(stats, 0, sizeof(*stats)); + stats->st_dev = 0; + stats->st_ino = p->ino; + stats->st_mode = p->mode; + stats->st_rdev = p->rdev; + + return 1; +} + +static int in_add_dev_table_entries; + +// Track entries in rootfs, so we don't duplicate entries in device table +void dev_table_set_entry(char *path, int parentId, struct stat *stats) +{ + struct deventry *p; + + if ((p = find_dev_table_entry(path))) { + // Skip it if we've already seen it, or we're adding in the devices + if (p->skip || in_add_dev_table_entries) + return; + + if (progress) + printf("%s: path %s parentId %d\n", __FUNCTION__, path, parentId); + + if (S_ISDIR(stats->st_mode)) + p->parentId = parentId; + + p->skip = 1; // now that we've seen it, no need to deal with it again + } +} + +void +add_dev_table_entries(void) +{ + struct deventry *p; + struct dirent d; + char name[128]; + + in_add_dev_table_entries = 1; + 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) +{ + 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: + + /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; + unsigned long mode = 0755, uid = 0, gid = 0, major = 0, minor = 0; + unsigned long start = 0, increment = 1, count = 0; + + 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-09 11:37:40.000000000 -0500 @@ -0,0 +1,23 @@ +/* + * YAFFS: Yet Another Flash File System. A NAND-flash specific file system. + * + * Copyright (C) 2009 Logic Product Development, Inc. + * + * Created by Peter Barada + * + * 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. + */ + +#include + +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_entry(char *path, int parentId, struct stat *stats); +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-09 11:37:40.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 + * 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 #include #include #include +#include #include #include #include #include +#include #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; + +static struct passwd *find_entry_by_uid(int uid) +{ + struct passwd *p; + int i; + for (p=passwd_list, i=0; ipw_uid) + return p; + } + return root_passwd; +} + +static struct passwd *find_entry_by_name(const char *name) +{ + struct passwd *p; + int i; + for (p=passwd_list, i=0; ipw_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 + +static 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; @@ -127,7 +206,7 @@ * NOTE: The tag is not usable after this other than calculating the CRC * with. */ -static void little_to_big_endian(yaffs_Tags *tagsPtr) +static void little_to_big_endian(yaffs_ExtendedTags *tagsPtr) { #if 0 // FIXME NCB yaffs_TagsUnion * tags = (yaffs_TagsUnion* )tagsPtr; // Work in bytes. @@ -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); + dev_table_set_entry(full_name, newObj, &stats); + + 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); + } + } + } + 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; + +static void usage(void) +{ + printf("usage: mkyaffsimage -c -s 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 of block in flash(minus spares in NAND)\n"); + printf(" -N produce a NAND image(if not set assume NOR)\n"); + printf(" -p permission file to remap owner/group from\n"); + printf(" -r If no user/group in file, make root/wheel\n"); + printf(" -D 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; + +static 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; iroomToGrow[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/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-09 11:37:40.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, diff --exclude CVS --exclude .git -uNr yaffs_utils-20060418/yaffs2/yaffs_tagsvalidity.h yaffs_utils-20060418.modified/yaffs2/yaffs_tagsvalidity.h --- yaffs_utils-20060418/yaffs2/yaffs_tagsvalidity.h 2006-04-24 07:39:43.000000000 -0400 +++ yaffs_utils-20060418.modified/yaffs2/yaffs_tagsvalidity.h 2009-11-09 11:37:40.000000000 -0500 @@ -18,8 +18,11 @@ #ifndef __YAFFS_TAGS_VALIDITY_H__ #define __YAFFS_TAGS_VALIDITY_H__ + #include "yaffs_guts.h" +#if 0 void yaffs_InitialiseTags(yaffs_ExtendedTags * tags); int yaffs_ValidateTags(yaffs_ExtendedTags * tags); #endif +#endif