2 * YAFFS: Yet another FFS. A NAND-flash specific file system.
3 * mkyaffs.c Format a chunk of NAND for YAFFS.
5 * Copyright (C) 2002 Aleph One Ltd.
6 * for Toby Churchill Ltd and Brightstar Engineering
8 * Created by Charles Manning <charles@aleph1.co.uk>
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2 as
12 * published by the Free Software Foundation.
15 * This file is crafted from nandtest.c by Miguel Freitas (miguel@cetuc.puc-rio.br)
16 * and Steven J. Hill (sjhill@cotw.com)
19 * Formatting a YAFFS device is very simple. Just erase all undamaged blocks.
20 * NB Don't erase blocks maked as damaged.
32 #include <sys/ioctl.h>
33 #include <sys/types.h>
34 #include <asm/types.h>
35 #include <mtd/mtd-user.h>
37 const char *mkyaffs_c_version = "$Id: mkyaffs.c,v 1.9 2005-10-11 23:39:56 charles Exp $";
39 // countBits is a quick way of counting the number of bits in a byte.
40 // ie. countBits[n] holds the number of 1 bits in a byte with the value n.
42 static const char countBits[256] =
44 0,1,1,2,1,2,2,3,1,2,2,3,2,3,3,4,
45 1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,
46 1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,
47 2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,
48 1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,
49 2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,
50 2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,
51 3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,
52 1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,
53 2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,
54 2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,
55 3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,
56 2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,
57 3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,
58 3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,
59 4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8
63 * Buffer arrays used for running tests
66 unsigned char oobbuf[16];
67 unsigned char imgpage[528];
73 struct nand_oobinfo yaffs_oobinfo = {
75 eccpos: {8, 9, 10, 13, 14, 15}
78 struct nand_oobinfo yaffs_noeccinfo = {
86 int main(int argc, char **argv)
96 struct mtd_oob_buf oob = {0, 16, (unsigned char *) &oobbuf};
99 struct nand_oobinfo oobsel;
101 if (argc > 1 && strcmp (argv[optcnt], "-?") == 0) {
105 if (argc > 1 && strcmp (argv[optcnt], "-h") == 0) {
109 if (argc > 1 && strcmp (argv[optcnt], "-e") == 0) {
114 printf("argc %d sh %d optcnt %d\n",argc, showHelp, optcnt);
116 /* Make sure a device was specified */
117 if(showHelp || argc < (optcnt + 1)) {
118 printf("usage: %s [-e] <mtdname> [image name]\n", argv[0]);
119 printf(" -e Use mtd ecc. Default: do not use mtd ecc\n");
120 printf(" mtdname Name of mtd device\n");
121 printf(" image name Name of optional image file\n\n");
122 printf("Function: Formats a NAND mtd device for YAFFS. If the optional\n"
123 "image file is specified, then the file system is loaded with\n"
128 if( argc > (optcnt + 1) &&
129 (img = open(argv[optcnt + 1],O_RDONLY)) == -1) {
130 perror("opening image file");
135 imglen = lseek(img,0,SEEK_END);
137 printf("Image not a multiple of 528 bytes\n");
142 lseek(img,0,SEEK_SET);
144 /* Open the device */
145 if((fd = open(argv[optcnt], O_RDWR)) == -1) {
146 perror("opening flash");
150 /* Fill in MTD device capability structure */
151 if(ioctl(fd, MEMGETINFO, &meminfo) != 0) {
152 perror("MEMGETINFO");
157 // set the appropriate oob layout selector
158 oobsel = usemtdecc ? yaffs_oobinfo : yaffs_noeccinfo;
159 if (ioctl (fd, MEMSETOOBSEL, &oobsel) != 0) {
160 perror ("MEMSETOOBSEL");
165 /* Make sure device page sizes are valid */
166 if( !(meminfo.oobsize == 16 && meminfo.oobblock == 512))
168 printf("Unknown flash (not normal NAND)\n");
174 (imglen/528 +32)*512 > meminfo.size){
175 printf("Image is too big for NAND\n");
180 printf("Erasing and programming NAND\n");
181 for(addr = 0; addr < meminfo.size; addr += meminfo.erasesize)
183 /* Read the OOB data to determine if the block is valid.
184 * If the block is damaged, then byte 5 of the OOB data will
185 * have at least 2 zero bits.
190 if (ioctl(fd, MEMREADOOB, &oob) != 0)
192 perror("ioctl(MEMREADOOB)");
197 if(countBits[oobbuf[5]] < 7)
199 printf("Block at 0x08%lx is damaged and is not being formatted\n",addr);
203 /* Erase this block */
205 erase.length = meminfo.erasesize;
206 printf("Erasing block at 0x08%lx\n",addr);
207 if(ioctl(fd, MEMERASE, &erase) != 0)
209 perror("\nMTD Erase failure\n");
214 /* Do some programming, but not in the first block */
217 for(offset = 0; offset <meminfo.erasesize; offset+=512)
219 if(read(img,imgpage,528) == 528){
221 imgpage[512+8] = 0xff;
222 imgpage[512+9] = 0xff;
223 imgpage[512+10] = 0xff;
224 imgpage[512+13] = 0xff;
225 imgpage[512+14] = 0xff;
226 imgpage[512+15] = 0xff;
228 oob.start = addr+offset;
230 oob.ptr=&imgpage[512];
231 ioctl(fd,MEMWRITEOOB,&oob);
233 lseek(fd,addr+offset,SEEK_SET);
234 write(fd,imgpage,512);
245 /* All the tests succeeded */