[Yaffs] [PATCH 2/2] mkyaffs2image: add support for inband ta…

Top Page
Attachments:
Message as email
+ (text/plain)
Delete this message
Reply to this message
Author: Angus CLARK
Date:  
To: yaffs
Old-Topics: [Yaffs] [PATCH 1/2] yaffs linux: update yaffs_get_mtd_device() code refactoring
Subject: [Yaffs] [PATCH 2/2] mkyaffs2image: add support for inband tags and user-defined page geometries

Signed-off-by: Angus Clark <>
---
utils/mkyaffs2image.c | 154 +++++++++++++++++++++++++++++++++++++-----------
1 files changed, 118 insertions(+), 36 deletions(-)

diff --git a/utils/mkyaffs2image.c b/utils/mkyaffs2image.c
index b46f285..ddebcb6 100644
--- a/utils/mkyaffs2image.c
+++ b/utils/mkyaffs2image.c
@@ -29,6 +29,7 @@
#include <dirent.h>
#include <string.h>
#include <unistd.h>
+#include <getopt.h>
#include <errno.h>
#include <assert.h>
#include "yaffs_ecc.h"
@@ -40,12 +41,15 @@ unsigned yaffs_trace_mask=0;

#define MAX_OBJECTS 10000

-// Adjust these to match your NAND LAYOUT:
-#define chunkSize 2048
-#define spareSize 64
-#define pagesPerBlock 64
-
+#define inbandSize 16

+int pageSize = 2048;
+int spareSize = 64;
+int blockSize = 0x20000;
+int chunkSize;
+int pagesPerBlock;
+int inband_tags = 0;
+int no_pad = 0;

typedef struct
{
@@ -207,14 +211,21 @@ static int write_chunk(u8 *data, u32 id, u32 chunk_id, u32 n_bytes)

     nPages++;


-    memset(&pt, 0, sizeof(pt));
-    yaffs_pack_tags2(&pt,&t,1);
-
-    memset(spareData, 0xff, sizeof(spareData));
-    shuffle_oob(spareData, &pt);
-
-    if (write(outFile,spareData,sizeof(spareData)) != sizeof(spareData))
-        fatal("write");
+    if (inband_tags) {
+        struct yaffs_packed_tags2_tags_only pt2tp;
+        yaffs_pack_tags2_tags_only(&pt2tp, &t);
+        if (write(outFile,&pt2tp,inbandSize) != inbandSize)
+            fatal("write");
+    } else {
+        memset(&pt, 0, sizeof(pt));
+        yaffs_pack_tags2(&pt,&t,1);
+        
+        memset(spareData, 0xff, sizeof(spareData));
+        shuffle_oob(spareData, &pt);
+        
+        if (write(outFile,spareData,sizeof(spareData)) != sizeof(spareData))
+            fatal("write");
+    }
     return 0;
 }


@@ -332,15 +343,16 @@ static int write_object_header(int id, enum yaffs_obj_type t, struct stat *s, in

 static void pad_image(void)
 {
-    u8 data[chunkSize + spareSize];
+    int dataSize = inband_tags ? pageSize : pageSize + spareSize;
+    u8 data[dataSize];
     int padPages = (nPages % pagesPerBlock);


     if (padPages)
     {
-        memset(data, 0xff, sizeof(data));
+        memset(data, 0xff, dataSize);
         for (padPages = pagesPerBlock-padPages; padPages; padPages--)
         {
-            if (write(outFile, data, sizeof(data)) != sizeof(data))
+            if (write(outFile, data, dataSize) != dataSize)
                 fatal("write");
         }
     }
@@ -506,51 +518,121 @@ static int process_directory(int parent, const char *path)
 }



+static void print_usage(void)
+{
+    printf("Usage: mkyaffs2image [Options] <dir> <image_file>\n");
+    printf("           <dir>          the directory tree to be converted\n");
+    printf("           <image.yaffs2> the output file to hold the image\n");
+    printf("Options:\n");
+    printf("  -c | --convert          produce a big-endian image from a little-endian machine\n");
+    printf("  -p | --page-size        Page size of target NAND device [2048]\n");
+    printf("  -o | --oob-size         OOB size of target NAND device [64]\n");
+    printf("  -b | --block-size       Block size of target NAND device [0x20000]\n");
+    printf("  -i | --inabnd-tags      Use Inband Tags\n");
+    printf("  -n | --no-pad           Do not pad to end of block\n");
+    printf("\n\n");
+}
+
 int main(int argc, char *argv[])
 {
+    const char *short_options = "cp:o:b:in";
+    const struct option long_options[] = {
+        {"convert", 0, 0, 'c'},
+        {"page-size", 1, 0, 'p'},
+        {"oob-size", 1, 0, 'o'},
+        {"block-size", 1, 0, 'b'},
+        {"inband-tags", 0, 0, 'i'},
+        {"no-pad", 0, 0, 'n'},
+    };
+    char *endptr;
+    int c, option_index;
+
+    char *dir, *img;
+    
     struct stat stats;

    
     printf("mkyaffs2image: image building tool for YAFFS2 built "__DATE__"\n");

    
-    if(argc < 3)
-    {
-        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);
+    while ((c = getopt_long(argc, argv, short_options, long_options,
+                &option_index)) != -1) {
+        switch (c) {
+        case 'c':
+            convert_endian = 1;
+            break;
+        case 'p':
+            pageSize = strtoul(optarg, &endptr, 0);
+            if (*endptr != '\0') {
+                fprintf(stderr, "invalid 'page-size' argument[%s]\n",
+                    optarg);
+                return 1;
+            }
+            break;
+        case 'o':
+            spareSize = strtoul(optarg, &endptr, 0);
+            if (*endptr != '\0') {
+                fprintf(stderr, "invalid 'oob-size' [%s] argument\n",
+                    optarg);
+                return 1;
+            }
+            break;
+        case 'b':
+            blockSize = strtoul(optarg, &endptr, 0);
+            if (*endptr != '\0') {
+                fprintf(stderr, "invalid 'block-size' [%s] argument\n",
+                    optarg);
+                return 1;
+            }
+            break;
+        case 'i':
+            inband_tags = 1;
+            break;
+        case 'n':
+            no_pad = 1;
+            break;
+        default:
+            print_usage();
+            return 1;
+        }
     }


-    if ((argc == 4) && (!strncmp(argv[3], "convert", strlen("convert"))))
-    {
-        convert_endian = 1;
-    }
+    if (argc - optind < 1) {
+        fprintf(stderr, "Missing <dir> and/or <image.yaffs2> argument\n");
+        print_usage();
+        return 1;
+    }
+
+    dir = argv[optind];
+    img = argv[optind + 1];
+
+    chunkSize = inband_tags ? pageSize - inbandSize : pageSize;
+    pagesPerBlock = blockSize / pageSize;


-    if(stat(argv[1],&stats) < 0)
+    if(stat(dir,&stats) < 0)
     {
-        printf("Could not stat %s\n",argv[1]);
+        printf("Could not stat %s\n",dir);
         exit(1);
     }

    
     if(!S_ISDIR(stats.st_mode))
     {
-        printf(" %s is not a directory\n",argv[1]);
+        printf(" %s is not a directory\n",dir);
         exit(1);
     }

    
-    outFile = open(argv[2],O_CREAT | O_TRUNC | O_WRONLY, S_IREAD | S_IWRITE);
+    outFile = open(img,O_CREAT | O_TRUNC | O_WRONLY, S_IREAD | S_IWRITE);

    
    
     if(outFile < 0)
     {
-        printf("Could not open output file %s\n",argv[2]);
+        printf("Could not open output file %s\n",img);
         exit(1);
     }

    
-    printf("Processing directory %s into image file %s\n",argv[1],argv[2]);
-    process_directory(YAFFS_OBJECTID_ROOT,argv[1]);
-    
-    pad_image();
+    printf("Processing directory %s into image file %s\n",dir,img);
+    process_directory(YAFFS_OBJECTID_ROOT,dir);
+
+    if (!no_pad)
+        pad_image();


     close(outFile);

    
--
1.7.7