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 #include #include +#include #include #include #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] \n"); + printf(" the directory tree to be converted\n"); + printf(" 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 and/or 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