This is the mail archive of the
mailing list for the eCos project.
Re: NAND review
- From: Nick Garnett <nickg at ecoscentric dot com>
- To: Andrew Lunn <andrew at lunn dot ch>
- Cc: john at dallaway dot org dot uk, "ecos-devel at ecos dot sourceware dot org" <ecos-devel at ecos dot sourceware dot org>
- Date: 10 Jun 2009 18:39:23 +0100
- Subject: Re: NAND review
- References: <4A126D59.firstname.lastname@example.org> <20090519162853.GA27459@lunn.ch> <20090603085115.GA27508@lunn.ch>
Andrew Lunn <email@example.com> writes:
> IMHO Ross's partitioning scheme/API is broken. I've tried to trigger
> discussion about this, but there has not been much interest. This is a
> shame, because to fix it will require API changes, so requiring
> changes to the YAFFS glue code etc. I'm also not the only one with
> reservations about this partitioning, i've had a private email from a
> respected member of the community expressing reservations about the
> I would say the way forward with partitioning is to discuss the
> requirements, where can the partitioning information come from, where
> does it need to go to, what should the APIs look like. Then do some
> design work to make draft APIs, collect comments and then do the
> implementation work/modifications as necessary.
In the interests of getting things moving, I'm going to give my take
on the partitioning debate. I discussed this with Ross before he
implemented the scheme, so I guess I must take some of the blame :-/
The first thing to say is that partitioning was never intended to be
the functional equivalent of the flash FIS directory. NAND flash is
designed to be used to store filesystems (possibly very primitive)
rather be used as a read-only memory like NOR flash. There will almost
always be another layer of software dealing with bad blocks, wear
levelling and OOB data between the application and the NAND device
itself. Different partitions will be handled by different
subsystems. NAND partitions are much more like the partitions on a
disk and the choice of the term was meant to convey this. It is a
relatively primitive way to divide the NAND up into functional areas.
It is sometimes best to think about a concrete example, and my
thoughts on NAND use were informed by thinking about how to use the
NAND on an Atmel AT91SAM9 based device. These processors have no
on-chip flash and must boot from an external device. A variety of such
devices are allowed, from dataflash on an SPI bus, EEPROM on I2C and
NAND flash. NOR flash is not an option, and few of the -EK boards are
equipped with it.
To boot, a SAM9 device runs an on-chip bootloader that searches the
external memories for something it recognizes as an executable, loads
it into on-chip SRAM and jumps into it. On-chip SRAM is small, so this
can only be a secondary bootstrap which will then fetch the real
executable into external memory and run it.
When booting from NAND the on-chip bootstrap simply reads the
executable from the start of the flash, it assumes the first block is
valid. Atmel supply a secondary bootstrap, snappily named
AT91Bootstrap, that will then load the main executable. This code has
to handle factory marked bad blocks. Starting at a fixed offset in the
NAND it reads a fixed number of blocks into external RAM, skipping
those that have a bad block mark.
So, here we already have two partitions in the NAND device, one for
the secondary bootstrap and one for the main executable. If the
executable is RedBoot, then it may want to store config data and
applications in the NAND itself. It may do this in a third partition
using YAFFS or UFFS, or a virtual V2/NOR flash driver. Finally, any
applications will need to use a filesystem, which for security and
reliability should probably be distinct from that used by RedBoot.
The size and position of the first two partitions is fixed by the
on-chip ROM and the secondary bootstrap. Bad block handling and
filesystem structure would make it very difficult to move or resize
any other partitions. So, once the partitioning of a NAND has been
decided on and initialized, it is fixed for good, much like disk
I don't see much utility in having an on-chip partition table. NAND
chips, unlike disks, are not portable between different systems, so
there is little need for it to be self-describing. There is also no
standard for NAND partitioning, even in the Linux world where
partition tables seem to be either written into the driver, or are
supplied on the command line from the bootstrap. Linux compatibility
is desirable, if only to avoid reinventing the wheel, and we should
follow their lead, rather than try to invent something of our own.
For now, defining the partitioning of the NAND statically, via CDL, is
logically equivalent to the Linux approach of writing the table into
the driver. If a partitioning standard does emerge, then the hooks are
already present to make use of it.
> There has been comments that Rutgers code has too many layers. Rutger
> aims to allow as much code reuse between drivers as possible, which i
> think is good. Simon commented that he thinks Ross's design may result
> in a lot of code stuck in HALs where it is hard to reuse without copy
> paste. However Ross argued that he thinks that making code reusable is
> going to be hard, there is too many different configurations of chips
> and controllers, etc.
> With only one supported platform on Ross's code and two with Rutgers,
> i think it is too early to tell the truth. However, im generally in
> favour of layers.
Just a few quick words about layering...
We have to be very careful in eCos not to over-do the abstractions.
eCos is still an embedded operating system and not a full-featured
general purpose OS. As such we must take care not to compromise code
size and performance. There are some areas in eCos already where we
have more layers than we strictly need, and performance has
suffered. Many of the target processors are relatively slow, without
caches or much fast memory and every extra call and indirection can
cost a lot of cycles.
The layering approach in the eCosCentric code is intended to keep the
layers to a minimum where possible. However, it doesn't preclude the
use of additional abstractions where necessary.
While the driver itself lives in the platform HAL, chip specifics are
#included, rather than going through a call/return interface. This
keeps the functional separation but reduces runtime overhead and
allows the compiler to optimize the code. The author of a chip driver
can always choose to move parts of the code to a separately compiled
source file if that makes more sense.
Equally, while the current LPC2468 driver is entirely in the platform
HAL, parts of this could be moved into common code in the variant HAL
if it can be shared. However, since it is not currently very clear
where that division of labour must go, this has not been done for this
initial driver. As further drivers are developed we will get a better
feel for where this line needs to be drawn.
I think in general an approach that keeps the system defined layering
to a minimum while allowing subsystems to abstract common code
internally gets the best of both worlds.
Nick Garnett eCos Kernel Architect
eCosCentric Limited http://www.eCosCentric.com The eCos experts
Barnwell House, Barnwell Drive, Cambridge, UK. Tel: +44 1223 245571
Registered in England and Wales: Reg No: 4422071