/*
* YAFFS: Yet Another Flash File System. A NAND-flash specific file system.
*
- * Copyright (C) 2002-2010 Aleph One Ltd.
- * for Toby Churchill Ltd and Brightstar Engineering
+ * Copyright (C) 2002-2018 Aleph One Ltd.
*
* Created by Charles Manning <charles@aleph1.co.uk>
* Nick Bane modifications flagged NCB
*/
/*
- * makeyaffsimage.c
+ * makeyaffsimage.c
*
* Makes a YAFFS file system image that can be used to load up a file system.
*/
-
+
#include <stdlib.h>
#include <stdio.h>
#include <fcntl.h>
static objItem obj_list[MAX_OBJECTS];
-static int n_obj = 0;
-static int obj_id = YAFFS_NOBJECT_BUCKETS + 1;
+static int obj_alloc_id = YAFFS_NOBJECT_BUCKETS + 1;
static int n_obj, nDirectories, nPages;
static int obj_compare(const void *a, const void * b)
{
objItem *oa, *ob;
-
+
oa = (objItem *)a;
ob = (objItem *)b;
-
+
if(oa->dev < ob->dev) return -1;
if(oa->dev > ob->dev) return 1;
if(oa->ino < ob->ino) return -1;
if(oa->ino > ob->ino) return 1;
-
+
return 0;
}
obj_list[n_obj].obj = obj;
n_obj++;
qsort(obj_list,n_obj,sizeof(objItem),obj_compare);
-
+
}
else
{
test.dev = dev;
test.ino = ino;
-
+
if(n_obj > 0)
{
i = bsearch(&test,obj_list,n_obj,sizeof(objItem),obj_compare);
return -1;
}
+#if 0
// NCB added 10/9/2002
static u16 yaffs_calc_name_sum(const char *name)
{
u16 sum = 0;
u16 i = 1;
-
+
u8 *bname = (u8 *)name;
-
+
while (*bname)
{
sum += (*bname) * i;
}
return sum;
}
+#endif
-
-static void yaffs_calc_ecc(const u8 *data, yaffs_spare *spare)
+static void yaffs_calc_ecc(const u8 *data, struct yaffs_spare *spare)
{
- yaffs_ecc_cacl(data , spare->ecc1);
- yaffs_ecc_cacl(&data[256] , spare->ecc2);
+ yaffs_ecc_calc(data , spare->ecc1);
+ yaffs_ecc_calc(&data[256] , spare->ecc2);
}
static void yaffs_calc_tags_ecc(struct yaffs_tags *tags)
{
// Todo don't do anything yet. Need to calculate ecc
- unsigned char *b = ((yaffs_tags_union_t *)tags)->as_bytes;
+ unsigned char *b = ((union yaffs_tags_union *)tags)->as_bytes;
unsigned i,j;
unsigned ecc = 0;
unsigned bit = 0;
b[6] &= 0xC0;
b[7] &= 0x03;
}
-
+
for(i = 0; i < 8; i++)
{
// NCB modified 20-9-02 for(j = 1; j &0x7f; j<<=1)
}
}
}
-
+
// Write out ECC
if (!convert_endian)
{
b[7] |= ((ecc & 0x3F) << 2);
}
}
-static void yaffs_load_tags_to_spare(yaffs_spare *sparePtr, struct yaffs_tags *tagsPtr)
+static void yaffs_load_tags_to_spare(struct yaffs_spare *sparePtr, struct yaffs_tags *tagsPtr)
{
- yaffs_tags_union_t *tu = (yaffs_tags_union_t *)tagsPtr;
-
+ union yaffs_tags_union *tu = (union yaffs_tags_union *)tagsPtr;
+
//yaffs_calc_tags_ecc(tagsPtr);
-
+
sparePtr->tb0 = tu->as_bytes[0];
sparePtr->tb1 = tu->as_bytes[1];
sparePtr->tb2 = tu->as_bytes[2];
*/
static void little_to_big_endian(struct yaffs_tags *tagsPtr)
{
- yaffs_tags_union_t * tags = (yaffs_tags_union_t* )tagsPtr; // Work in bytes.
- yaffs_tags_union_t temp;
+ union yaffs_tags_union * tags = (union yaffs_tags_union* )tagsPtr; // Work in bytes.
+ union yaffs_tags_union temp;
memset(&temp, 0, sizeof(temp));
// Ick, I hate magic numbers.
static int write_chunk(u8 *data, u32 obj_id, u32 chunk_id, u32 n_bytes)
{
struct yaffs_tags t;
- yaffs_spare s;
+ struct yaffs_spare s;
error = write(outFile,data,512);
if(error < 0) return error;
memset(&t,0xff,sizeof (struct yaffs_tags));
- memset(&s,0xff,sizeof (yaffs_spare));
-
+ memset(&s,0xff,sizeof (struct yaffs_spare));
+
t.chunk_id = chunk_id;
t.serial_number = 0;
t.n_bytes_lsb = n_bytes;
{
little_to_big_endian(&t);
}
-
+
yaffs_calc_tags_ecc(&t);
yaffs_load_tags_to_spare(&s,&t);
yaffs_calc_ecc(data,&s);
-
+
nPages++;
-
- return write(outFile,&s,sizeof(yaffs_spare));
-
+
+ return write(outFile,&s,sizeof(struct yaffs_spare));
+
}
#define SWAP32(x) ((((x) & 0x000000FF) << 24) | \
#define SWAP16(x) ((((x) & 0x00FF) << 8) | \
(((x) & 0xFF00) >> 8))
-
+
// This one is easier, since the types are more standard. No funky shifts here.
static void object_header_little_to_big_endian(struct yaffs_obj_hdr* oh)
{
oh->sum_no_longer_used = SWAP16(oh->sum_no_longer_used); // u16 - Not used, but done for completeness.
// name = skip. Char array. Not swapped.
oh->yst_mode = SWAP32(oh->yst_mode);
-#ifdef CONFIG_YAFFS_WINCE // WinCE doesn't implement this, but we need to just in case.
- // In fact, WinCE would be *THE* place where this would be an issue!
- oh->not_for_wince[0] = SWAP32(oh->not_for_wince[0]);
- oh->not_for_wince[1] = SWAP32(oh->not_for_wince[1]);
- oh->not_for_wince[2] = SWAP32(oh->not_for_wince[2]);
- oh->not_for_wince[3] = SWAP32(oh->not_for_wince[3]);
- oh->not_for_wince[4] = SWAP32(oh->not_for_wince[4]);
-#else
+
// Regular POSIX.
oh->yst_uid = SWAP32(oh->yst_uid);
oh->yst_gid = SWAP32(oh->yst_gid);
oh->yst_atime = SWAP32(oh->yst_atime);
oh->yst_mtime = SWAP32(oh->yst_mtime);
oh->yst_ctime = SWAP32(oh->yst_ctime);
-#endif
- oh->file_size = SWAP32(oh->file_size); // Aiee. An int... signed, at that!
+ oh->file_size_low = SWAP32(oh->file_size_low); // Aiee. An int... signed, at that!
oh->equiv_id = SWAP32(oh->equiv_id);
// alias - char array.
oh->yst_rdev = SWAP32(oh->yst_rdev);
-#ifdef CONFIG_YAFFS_WINCE
oh->win_ctime[0] = SWAP32(oh->win_ctime[0]);
oh->win_ctime[1] = SWAP32(oh->win_ctime[1]);
oh->win_atime[0] = SWAP32(oh->win_atime[0]);
oh->win_atime[1] = SWAP32(oh->win_atime[1]);
oh->win_mtime[0] = SWAP32(oh->win_mtime[0]);
oh->win_mtime[1] = SWAP32(oh->win_mtime[1]);
- oh->room_to_grow[0] = SWAP32(oh->room_to_grow[0]);
- oh->room_to_grow[1] = SWAP32(oh->room_to_grow[1]);
- oh->room_to_grow[2] = SWAP32(oh->room_to_grow[2]);
- oh->room_to_grow[3] = SWAP32(oh->room_to_grow[3]);
- oh->room_to_grow[4] = SWAP32(oh->room_to_grow[4]);
- oh->room_to_grow[5] = SWAP32(oh->room_to_grow[5]);
-#else
- oh->room_to_grow[0] = SWAP32(oh->room_to_grow[0]);
- oh->room_to_grow[1] = SWAP32(oh->room_to_grow[1]);
- oh->room_to_grow[2] = SWAP32(oh->room_to_grow[2]);
- oh->room_to_grow[3] = SWAP32(oh->room_to_grow[3]);
- oh->room_to_grow[4] = SWAP32(oh->room_to_grow[4]);
- oh->room_to_grow[5] = SWAP32(oh->room_to_grow[5]);
- oh->room_to_grow[6] = SWAP32(oh->room_to_grow[6]);
- oh->room_to_grow[7] = SWAP32(oh->room_to_grow[7]);
- oh->room_to_grow[8] = SWAP32(oh->room_to_grow[8]);
- oh->room_to_grow[9] = SWAP32(oh->room_to_grow[9]);
- oh->room_to_grow[10] = SWAP32(oh->room_to_grow[10]);
- oh->room_to_grow[11] = SWAP32(oh->room_to_grow[11]);
-#endif
+
+ oh->reserved[0] = SWAP32(oh->reserved[0]);
+
+ oh->inband_shadowed_obj_id = SWAP32(oh->inband_shadowed_obj_id);
+ oh->inband_is_shrink = SWAP32(oh->inband_is_shrink);
+ oh->shadows_obj = SWAP32(oh->shadows_obj);
+ oh->is_shrink = SWAP32(oh->is_shrink);
}
static int write_object_header(int obj_id, enum yaffs_obj_type t, struct stat *s, int parent, const char *name, int equivalentObj, const char * alias)
{
u8 bytes[512];
-
-
+
+
struct yaffs_obj_hdr *oh = (struct yaffs_obj_hdr *)bytes;
-
+
memset(bytes,0xff,512);
-
+
oh->type = t;
oh->parent_obj_id = parent;
-
+
strncpy(oh->name,name,YAFFS_MAX_NAME_LENGTH);
-
-
+
+
if(t != YAFFS_OBJECT_TYPE_HARDLINK)
{
oh->yst_mode = s->st_mode;
oh->yst_ctime = s->st_ctime;
oh->yst_rdev = s->st_rdev;
}
-
+
if(t == YAFFS_OBJECT_TYPE_FILE)
{
- oh->file_size = s->st_size;
+ oh->file_size_low = s->st_size;
}
-
+
if(t == YAFFS_OBJECT_TYPE_HARDLINK)
{
oh->equiv_id = equivalentObj;
}
-
+
if(t == YAFFS_OBJECT_TYPE_SYMLINK)
{
strncpy(oh->alias,alias,YAFFS_MAX_ALIAS_LENGTH);
{
object_header_little_to_big_endian(oh);
}
-
+
return write_chunk(bytes,obj_id,0,0xffff);
-
+
}
struct dirent *entry;
nDirectories++;
-
+
dir = opendir(path);
-
+
if(dir)
{
while((entry = readdir(dir)) != NULL)
{
-
+
/* Ignore . and .. */
if(strcmp(entry->d_name,".") &&
strcmp(entry->d_name,".."))
struct stat stats;
int equivalentObj;
int newObj;
-
+
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_ISCHR(stats.st_mode) ||
S_ISSOCK(stats.st_mode))
{
-
- newObj = obj_id++;
+
+ newObj = obj_alloc_id++;
n_obj++;
-
+
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)
{
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
+ else
{
-
+
add_obj_to_list(stats.st_dev,stats.st_ino,newObj);
-
+
if(S_ISLNK(stats.st_mode))
{
-
+
char symname[500];
-
+ int ret;
+
memset(symname,0, sizeof(symname));
-
- readlink(full_name,symname,sizeof(symname) -1);
-
+
+ ret = readlink(full_name,symname,sizeof(symname) -1);
+
+ if (ret < 0)
+ perror("readlink of symlink");
+
printf("symlink to \"%s\"\n",symname);
error = write_object_header(newObj, YAFFS_OBJECT_TYPE_SYMLINK, &stats, parent, entry->d_name, -1, symname);
u8 bytes[512];
int n_bytes;
int chunk = 0;
-
+
h = open(full_name,O_RDONLY);
if(h >= 0)
{
write_chunk(bytes,newObj,chunk,n_bytes);
memset(bytes,0xff,512);
}
- if(n_bytes < 0)
+ if(n_bytes < 0)
error = n_bytes;
-
+
printf("%d data chunks written\n",chunk);
}
else
perror("Error opening file");
}
close(h);
-
- }
-
+
+ }
+
}
else if(S_ISSOCK(stats.st_mode))
{
}
}
}
-
+
return 0;
}
int main(int argc, char *argv[])
{
struct stat stats;
-
+
printf("mkyaffsimage: image building tool for YAFFS built "__DATE__"\n");
-
+
if(argc < 3)
{
printf("usage: mkyaffsimage dir image_file [convert]\n");
{
convert_endian = 1;
}
-
+
if(stat(argv[1],&stats) < 0)
{
printf("Could not stat %s\n",argv[1]);
exit(1);
}
-
+
if(!S_ISDIR(stats.st_mode))
{
printf(" %s is not a directory\n",argv[1]);
exit(1);
}
-
+
outFile = open(argv[2],O_CREAT | O_TRUNC | O_WRONLY, S_IREAD | S_IWRITE);
-
-
+
+
if(outFile < 0)
{
printf("Could not open output file %s\n",argv[2]);
exit(1);
}
-
+
printf("Processing directory %s into image file %s\n",argv[1],argv[2]);
error = write_object_header(1, YAFFS_OBJECT_TYPE_DIRECTORY, &stats, 1,"", -1, NULL);
if(error)
error = process_directory(YAFFS_OBJECTID_ROOT,argv[1]);
-
+
close(outFile);
-
+
if(error < 0)
{
perror("operation incomplete");
"%d objects in %d directories\n"
"%d NAND pages\n",n_obj, nDirectories, nPages);
}
-
+
close(outFile);
-
+
exit(0);
-}
+}