[Yaffs] Why does YAFFS skip the first block?

Peter Barada Peter.B@LogicPD.com
Wed Jun 22 01:13:03 BST 2005


On Wed, 2005-06-22 at 10:47 +1200, Charles Manning wrote:
> On Wednesday 22 June 2005 07:25, Peter Barada wrote:
> > I have a NOR implementation of YAFFS, and I've been pounding my head
> > with mkyaffsimage.c trying to get an image that can be built on a linux
> > box and used on a ColdFire mcf5475 based embedded Linux board using
> > kernel 2.4.26.
> >
> > To do this, I've set up the MTD access such that the spare abuts its
> > corresponding data chunk which all seems to work(this is that I make
> > sure that a data chunk and spare are in the same block).  What I
> > stumbled across is that YAFFS refuses to use the first flash block(which
> > in my case is 64K in size) by setting dev->startBlock = 1 in
> > yaffs_internal_read_super.  This causes it to behave bizarrely when I
> > first burned the image created by mkyaffsimage into the flash starting
> > at block zero.
> >
> > If I change dev->startBlock to zero, then yaffs_GutsInitialize() fails
> > due to checks for a non-zero startBlock.  If I change those checks to
> > allow a zero startBlock, things look like they work fine, including the
> > image that mkyaffsimage created(after I modified write_chunk to place
> > the data and spares in the appropriate offsets).
> >
> > Am I setting myself up for a bunch of problems by changing the
> > startBlock to zero?
> 
> Not using chunk zero is a historical accident, of sorts. On NAND, chunk zero 
> is guaranteed good while others might not. On many systems, the first n 
> chunks hold boot image  etc. Sometimes chunk zero is used to store bad block 
> tables etc.
> 
> I needed a value for "invalid chunk" and "invalid block" and, because of the 
> above, and because zero is easy to use, I chose zero.  In hindsight, it might 
> have been better to use -1/0xffffffffff.
> 
> Most NAND folk don't hurt to much if a single block has to be lost (since 
> NAND typically has many blocks), but it can be  nasty for NOR folk with few 
> blocks.

Yeah, that's my problem.  It wastes a serious percentage of space...

> All is not lost though, there is a way to use that block zero,  and it is 
> pretty straight forward. You just need to tell YAFFS some lies!
> 
> All yaffs flash calls go through a few access functions. 
> All you need to do is to do a mapping in these functions so that yaffs block 
> 1 = physical block 0.
> 
> eg.
> int (*writeChunkToNAND)(struct yaffs_DeviceStruct *dev,int chunkInNAND, const 
> __u8 *data, yaffs_Spare *spare)
> {
>       chunkInNAND -= dev->nChunksPerBlock; 
> 
>      .....   // rest of stuff
> }
> 
> int (*eraseBlockInNAND)(struct yaffs_DeviceStruct *dev,int blockInNAND)
> {
>     blockInNAND--;
>     ...// rest of stuff
> }
> 
> Now you must need to keep the illusion going by setting up the device start 
> and end blocks accordingly. If you have, say, 32 physical blocks numbered 
> from 0 to 31, then just set up startBlock=1 and endBlock =32;
> 
> There is no chunk or block info imprinted in the actual YAFFS data, so no 
> changes are needed to mkyaffsimage etc to make this work.

Ugh, that sounds like a *total* hack.  Is there anything wrong with
allowing dev->startBlock to be zero instead of 1?

I *could* do the remap in the access functions, but it *assumes some
magical offset that requires a comment of:

	/* This is a total hack since YAFFS refuses to use block zero */

Is there anything *actually* wrong with using block zero?  If what you
say is true for NAND, then you don't even bother using the one
guaranteed good block in the device...

> -- Charles
> 
> 
> 
>      
-- 
Peter Barada <Peter.B@LogicPD.com>





More information about the yaffs mailing list