<META NAME="GENERATOR" CONTENT="StarOffice/5.2 (Linux)">
<META NAME="CREATED" CONTENT="20020517;23103700">
<META NAME="CHANGEDBY" CONTENT=" ">
- <META NAME="CHANGED" CONTENT="20020518;7200400">
+ <META NAME="CHANGED" CONTENT="20020531;19314400">
</HEAD>
<BODY>
<H2 ALIGN=CENTER>Running up YAFFS using the MTD interface</H2>
-<P>Here are the steps required to get YAFFS going with the
+<P>Here are the steps required to get YAFFS going with the
NANDemulation MTD that I have written.</P>
<P><FONT COLOR="#800000"><FONT SIZE=4 STYLE="font-size: 16pt"><I><U><B>Warning:
This is experimental stuff that plugs into the kernel. It has only
<H3>Preparing the kernel</H3>
<P>First off, you need to patch the mtdcore services.</P>
<OL>
- <LI><P>Replace the devices/mtd/mtdpart.c file with the one enclosed.
- This patches the problem where special NAND functions are not being
- copied through the partition handler. The changes are marked with a
- comment containing my initials <B><FONT FACE="Courier, monospace">cdhm</FONT></B>.</P>
+ <LI><P>Replace the mtd files with the latest from the mtd cvs. This
+ fixes problems where special NAND functions are not being copied
+ through the partition handler.
+ </P>
<LI><P>Build the kernel including the following configurations to
support mtd.</P>
</OL>
<P STYLE="margin-left: 2cm">CONFIG_MTD_DEBUG=y</P>
<OL>
<P>CONFIG_MTD_DEBUG_VERBOSE=3</P>
- <H3 ALIGN=LEFT></H3>
</OL>
<H3 ALIGN=LEFT>Setting up yaffs</H3>
<OL>
<LI><P>Run the mtd utility MAKEDEV to make the /dev/mtdxxx entries.</P>
<LI><P>Load up the NANDemul MTD by typing<BR><FONT FACE="Courier, monospace">#/sbin/insmod
mtdemul/nandemul.o</FONT><BR>You should now be able to see the
- device in the mtd list by typing <BR>#<FONT FACE="Courier, monospace">cat
+ device in the mtd list by typing <BR>#<FONT FACE="Courier, monospace">cat
/proc/mtd</FONT><BR>If all is well, the device will now be
accessible as <FONT FACE="Courier, monospace">/dev/mtd0</FONT> and
<FONT FACE="Courier, monospace">/dev/mtdblock0</FONT> (or whatever).</P>
NANDemul tests out the mtd interface so in theory it should work on
real NAND too.</FONT></P>
<P><FONT FACE="Times, serif">Note though that since YAFFS applies the
-ECC, it does not expect the NAND device to be applying ECC. You
-probably want to configure the NAND driver with ECC disabled.</FONT></P>
+ECC and verify, it does not expect the NAND device to be applying ECC
+or verification. </FONT>
+</P>
+<P><FONT FACE="Times, serif">You probably need to configure the NAND
+with the following disabled:</FONT></P>
+<P><FONT FACE="Times, serif">CONFIG_MTD_NAND_ECC</FONT></P>
+<P><FONT FACE="Times, serif">CONFIG_MTD_NAND_VERIFY_WRITE</FONT></P>
+<P><FONT FACE="Times, serif">Nick Banes has had YAFFS working on real
+NAND, with a few issues. </FONT>
+</P>
+<P><BR><BR>
+</P>
<P><BR><BR>
</P>
</BODY>
#########################################################
# Makefile auto generated by Cygnus Source Navigator.
-# Target: yaffsdev_RAM Date: May 03 2002 Time: 07:11:35 PM
+# Target: yaffsdev_disk Date: May 29 2002 Time: 08:12:41 PM
#
.SUFFIXES: .cc .class .java .cxx .C .cpp .o .c .l .y
-VPATH = /opt/aleph1/yaffs/.
+VPATH = /opt/yaffs/.
YACC = bison
YACC_FLAGS =
LEX_FLAGS =
JAVA_FLAGS =
-CC_FLAGS = -g -Wall
+CC_FLAGS = -g -Wall -DYAFFS_PARANOID -DYAFFS_FILEEM
CPP_FLAGS =
YACC_INCLUDES =
LEX_INCLUDES =
JAVA_DEFINES =
CC_DEFINES =
CPP_DEFINES =
-yaffsdev_RAM_LIBS =
+yaffsdev_disk_LIBS =
LINKER = gcc
LINKER_FLAGS =
LINKER_ENTRY =
-yaffsdev_RAM_OBJECTS = yaffs_guts.o yaffs_ramem.o yaffsdev.o
+yaffsdev_disk_OBJECTS = nand_ecc.o yaffs_fileem.o yaffs_guts.o yaffsdev.o
all: yaffsdev
-yaffsdev: $(yaffsdev_RAM_OBJECTS)
- $(LINKER) -o yaffsdev $(LINKER_ENTRY) $(LINKER_FLAGS) $(yaffsdev_RAM_OBJECTS) $(yaffsdev_RAM_LIBS)
+yaffsdev: $(yaffsdev_disk_OBJECTS)
+ $(LINKER) -o yaffsdev $(LINKER_ENTRY) $(LINKER_FLAGS) $(yaffsdev_disk_OBJECTS) $(yaffsdev_disk_LIBS)
.y.c:
$(YACC) $< $(YACC_FLAGS) $(YACC_DEFINES) $(YACC_INCLUDES)
$(CPP) -c $< $(CPP_FLAGS) $(CPP_DEFINES) $(CPP_INCLUDES)
-yaffs_guts.o: /opt/aleph1/yaffs/yaffs_guts.h /opt/aleph1/yaffs/yaffsinterface.h /opt/aleph1/yaffs/yportenv.h
-yaffs_ramem.o: yaffs_nandemul.h /opt/aleph1/yaffs/devextras.h /opt/aleph1/yaffs/yaffs_guts.h /opt/aleph1/yaffs/yaffsinterface.h /opt/aleph1/yaffs/yportenv.h
-yaffsdev.o: yaffs_nandemul.h /usr/include/stdio.h /usr/include/stdlib.h /usr/include/string.h /opt/aleph1/yaffs/yaffs_guts.h /opt/aleph1/yaffs/yaffsinterface.h
+nand_ecc.o: /opt/yaffs/yportenv.h
+yaffs_fileem.o: /opt/2.4.18/linux/include/linux/stat.h /opt/2.4.18/linux/include/linux/types.h /usr/include/fcntl.h /usr/include/stdio.h /usr/include/stdlib.h /usr/include/string.h /usr/include/unistd.h /opt/yaffs/yaffs_fileem.h /opt/yaffs/yaffs_guts.h /opt/yaffs/yaffsinterface.h
+yaffs_guts.o: /opt/yaffs/yaffs_guts.h /opt/yaffs/yaffsinterface.h /opt/yaffs/yportenv.h
+yaffsdev.o: yaffs_nandemul.h /usr/include/stdio.h /usr/include/stdlib.h /usr/include/string.h /opt/yaffs/yaffs_fileem.h /opt/yaffs/yaffs_guts.h /opt/yaffs/yaffsinterface.h
clean:
rm -f *.o
*/
//yaffs_fileem.c
-#include "yaffs_nandif.h"
+#include "yaffs_fileem.h"
#include "yaffs_guts.h"
#include "yaffsinterface.h"
-static void CheckInit(void)
+static void CheckInit(yaffs_Device *dev)
{
static int initialised = 0;
printf("Creating emulation file...\n");
for(i = 0; i < FILE_SIZE_IN_BLOCKS; i++)
{
- yaffs_EraseBlockInNAND(i);
+ yaffs_FEEraseBlockInNAND(dev,i);
}
}
}
}
-int yaffs_WriteChunkToNAND(int chunkInNAND,__u8 *data, yaffs_Spare *spare)
+int yaffs_FEWriteChunkToNAND(yaffs_Device *dev,int chunkInNAND,const __u8 *data, yaffs_Spare *spare)
{
int pos;
pos = chunkInNAND * 528;
- CheckInit();
+ CheckInit(dev);
if(data)
}
-int yaffs_ReadChunkFromNAND(int chunkInNAND, __u8 *data, yaffs_Spare *spare)
+int yaffs_FEReadChunkFromNAND(yaffs_Device *dev,int chunkInNAND, __u8 *data, yaffs_Spare *spare)
{
int pos;
pos = chunkInNAND * 528;
- CheckInit();
+ CheckInit(dev);
if(data)
{
}
-int yaffs_EraseBlockInNAND(int blockInNAND)
+int yaffs_FEEraseBlockInNAND(yaffs_Device *dev,int blockInNAND)
{
int i;
- CheckInit();
+ CheckInit(dev);
printf("Erasing block %d\n",blockInNAND);
return YAFFS_OK;
}
+int yaffs_FEInitialiseNAND(yaffs_Device *dev)
+{
+ return YAFFS_OK;
+}
+static void yaffs_put_super(struct super_block *sb);
+
static ssize_t yaffs_file_read(struct file *f, char *buf, size_t n, loff_t *pos);
static ssize_t yaffs_file_write(struct file *f, const char *buf, size_t n, loff_t *pos);
statfs: yaffs_statfs,
read_inode: yaffs_read_inode,
put_inode: yaffs_put_inode,
+ put_super: yaffs_put_super,
// read_inode:
// remount_fs:
// clear_inode:
static void yaffs_put_inode(struct inode *inode)
{
T(("yaffs_put_inode: ino %d, count %d\n",(int)inode->i_ino, atomic_read(&inode->i_count)));
+
+ yaffs_FlushFile(yaffs_InodeToObject(inode));
+
}
#ifdef YAFFS_ADDRESS_OPS
}
+static void yaffs_put_super(struct super_block *sb)
+{
+ yaffs_Device *dev = yaffs_SuperToDevice(sb);
+
+ if(dev->putSuperFunc)
+ {
+ dev->putSuperFunc(sb);
+ }
+}
+
+
+#ifdef YAFFS_MTD_ENABLED
+
+static void yaffs_MTDPutSuper(struct super_block *sb)
+{
+
+ struct mtd_info *mtd = yaffs_SuperToDevice(sb)->genericDevice;
+
+ if(mtd->sync)
+ {
+ mtd->sync(mtd);
+ }
+
+ put_mtd_device(mtd);
+}
+
+#endif
+
static struct super_block *yaffs_internal_read_super(int useRam, struct super_block * sb, void * data, int silent)
{
struct inode * inode;
if(useRam)
{
-#if YAFFS_RAM_ENABLED
+#ifdef YAFFS_RAM_ENABLED
// Set the yaffs_Device up for ram emulation
sb->u.generic_sbp = dev = kmalloc(sizeof(yaffs_Device),GFP_KERNEL);
dev->readChunkFromNAND = nandemul_ReadChunkFromNAND;
dev->eraseBlockInNAND = nandemul_EraseBlockInNAND;
dev->initialiseNAND = nandemul_InitialiseNAND;
+
#endif
}
dev->eraseBlockInNAND = nandmtd_EraseBlockInNAND;
dev->initialiseNAND = nandmtd_InitialiseNAND;
+ dev->putSuperFunc = yaffs_MTDPutSuper;
#endif
}
static int yaffs_AllocateChunk(yaffs_Device *dev,int useReserve);
-#if YAFFS_PARANOID
-static int yaffs_CheckFileSanity(yaffs_Object *in)
+#ifdef YAFFS_PARANOID
+static int yaffs_CheckFileSanity(yaffs_Object *in);
#else
#define yaffs_CheckFileSanity(in)
#endif
return retVal;
}
+#ifdef YAFFS_PARANOID
+
+static int yaffs_CheckChunkErased(struct yaffs_DeviceStruct *dev,int chunkInNAND)
+{
+ static int init = 0;
+ static __u8 cmpbuf[YAFFS_BYTES_PER_CHUNK];
+ static __u8 data[YAFFS_BYTES_PER_CHUNK];
+ static __u8 spare[16];
+
+ int retVal;
+
+ retVal = YAFFS_OK;
+
+ dev->readChunkFromNAND(dev,chunkInNAND,data,(yaffs_Spare *)spare);
+
+
+
+ if(!init)
+ {
+ memset(cmpbuf,0xff,YAFFS_BYTES_PER_CHUNK);
+ init = 1;
+ }
+
+ if(memcmp(cmpbuf,data,YAFFS_BYTES_PER_CHUNK)) retVal = YAFFS_FAIL;
+ if(memcmp(cmpbuf,spare,16)) retVal = YAFFS_FAIL;
+
+ return retVal;
+
+}
+
+#endif
+
+
int yaffs_EraseBlockInNAND(struct yaffs_DeviceStruct *dev,int blockInNAND)
{
return dev->eraseBlockInNAND(dev,blockInNAND);
}
#ifdef YAFFS_PARANOID
- if(yaffs_CheckChunkErased(retVal) == YAFFS_FAIL)
+ if(yaffs_CheckChunkErased(dev,retVal) == YAFFS_FAIL)
{
T(("..................Trying to allocate non-erased page %d\n",retVal));
}
theChunk = tn->level0[chunkInInode & YAFFS_TNODES_LEVEL0_MASK] << dev->chunkGroupBits;
// Now we need to do the shifting etc and search for it
- for(i = 0,found = 0; i < dev->chunkGroupSize && !found; i++)
+ for(i = 0,found = 0; theChunk && i < dev->chunkGroupSize && !found; i++)
{
yaffs_ReadChunkTagsFromNAND(dev,theChunk,tags);
if(tags->chunkId == chunkInInode &&
theChunk = tn->level0[chunkInInode & YAFFS_TNODES_LEVEL0_MASK] << dev->chunkGroupBits;
// Now we need to do the shifting etc and search for it
- for(i = 0,found = 0; i < dev->chunkGroupSize && !found; i++)
+ for(i = 0,found = 0; theChunk && i < dev->chunkGroupSize && !found; i++)
{
yaffs_ReadChunkTagsFromNAND(dev,theChunk,tags);
if(tags->chunkId == chunkInInode &&
for(chunk = 1; chunk <= nChunks; chunk++)
{
- tn = yaffs_FindLevel0Tnode(&in->variant.fileVariant, chunk);
+ tn = yaffs_FindLevel0Tnode(in->myDev,&in->variant.fileVariant, chunk);
if(tn)
{
- theChunk = tn->level0[chunk & YAFFS_TNODES_LEVEL0_MASK] << dev->chunkGroupBits;
+ theChunk = tn->level0[chunk & YAFFS_TNODES_LEVEL0_MASK] << in->myDev->chunkGroupBits;
- yaffs_ReadChunkTagsFromNAND(theChunk,tags);
+ yaffs_ReadChunkTagsFromNAND(in->myDev,theChunk,tags);
if(tags->chunkId == chunk &&
tags->objectId == in->objectId)
{
// found it;
-
+
}
else
{
int retVal;
if(in->dirty)
{
+ T(("flushing object header\n"));
retVal = yaffs_UpdateObjectHeader(in,NULL);
}
else
int (*readChunkFromNAND)(struct yaffs_DeviceStruct *dev,int chunkInNAND, __u8 *data, yaffs_Spare *spare);
int (*eraseBlockInNAND)(struct yaffs_DeviceStruct *dev,int blockInNAND);
int (*initialiseNAND)(struct yaffs_DeviceStruct *dev);
-
-
+#ifdef __KERNEL__
+ void (*putSuperFunc)(struct super_block *sb);
+#endif
+
// Runtime parameters.
yaffs_BlockInfo *blockInfo;
int nErasedBlocks;
*/
#include "yaffsinterface.h"
+#if YAFFS_FILEEM
+#include "yaffs_fileem.h"
+#else
#include "yaffs_nandemul.h"
+#endif
+
#include "yaffs_guts.h"
#include <stdlib.h>
device.nBlocks = (2 * 1024 * 1024) / (YAFFS_CHUNKS_PER_BLOCK * YAFFS_BYTES_PER_CHUNK);
device.startBlock = 1; // Don't use block 0
device.endBlock = device.nBlocks - 1;
-
+
+#if YAFFS_FILEEM
+ device.writeChunkToNAND = yaffs_FEWriteChunkToNAND;
+ device.readChunkFromNAND = yaffs_FEReadChunkFromNAND;
+ device.eraseBlockInNAND = yaffs_FEEraseBlockInNAND;
+ device.initialiseNAND = yaffs_FEInitialiseNAND;
+
+ printf("Testing on file emulation\n");
+#else
device.writeChunkToNAND = nandemul_WriteChunkToNAND;
device.readChunkFromNAND = nandemul_ReadChunkFromNAND;
device.eraseBlockInNAND = nandemul_EraseBlockInNAND;
device.initialiseNAND = nandemul_InitialiseNAND;
+ printf("Testing on RAM emulation\n");
+#endif
+
yaffs_GutsInitialise(&device);
// yaffs_GutsTest();