This is the mail archive of the
mailing list for the eCos project.
Re: NAND flash driver considerations: RFC
- From: Rutger Hofman <rutger at cs dot vu dot nl>
- To: ecos-discuss at sources dot redhat dot com, Jonathan Larmour <jifl at eCosCentric dot com>, Jürgen Lambrecht <J dot Lambrecht at televic dot com>
- Date: Thu, 25 Sep 2008 02:29:42 +0200
- Subject: [ECOS] Re: NAND flash driver considerations: RFC
- References: <48D06732.firstname.lastname@example.org>
I have received no responses for this RFC.
Wouldn't anybody care to comment?
Or do you think it is more useful if I just present my proposed NAND
controller interfaces (public and controller-specific), my proposed NAND
chip interfaces, and my proposed .cdl config setup? For sure that is
some stages later in the design.
Rutger Hofman wrote:
I am writing a NAND flash driver for eCos. I would like to get reactions
and advice on some issues, so I can correct now while I am still coding
(and my guess is, this won't be the last time).
NAND internal interfaces
NAND flash is actually two devices: the flash chip(s), and the
controller, often a separate part, sometimes integrated into a CPU (as
with my BlackFin BF54x).
The chips seem to have a fairly uniform interface, as canonicalized by
ONFI (http://www.onfi.org). All chips have lines for 'chip enable',
'select command', 'select address', 'r/w', 'data bus (x8 or x16)',
'status', which are handled in a standard way.
Consequently, any controller has a very good chance of being able to
speak to any chip, in hardware terms.
Moreover, the command set is mostly (a subset of) ONFI.
Deviations from the ONFI standard seem to be centered in the command
that interrogates the chip about its properties. #LUNs, #blocks/LUN,
#pages/block, data/page, spare size, bus width (x8 or x16), support for
optional commands, and timing characteristics can typically be obtained
either in ONFI speak (the 'READ PARAMETER BLOCK' command) or with a
The NAND flash controllers vary in their CPU interface. They may have
registers that reflect the basic capabilities of the chip interface
('command', 'address', 'data', 'status'). Or they may solve that
differently, in some serial way or whatever.
+++ My proposal:
= define a NAND controller /interface/ that specifies functions for the
chip capabilities ('command', 'address', 'data', 'status'); any NAND
controller /implementation/ must define them.
(See below: on top of that NAND controller interface, generic NAND code
provides the functions specified by ONFI to read/program (partial) pages
incl. spare erea, erase blocks, etc.)
= as far as the chip is concerned: most of the parameters are found
through chip interrogation, only very few parameters remain to be
specified in a .cdl or a chip .h file: bus width?, maybe some timings;
the src for the chip must contain any routines that deviate from ONFI,
where the device interrogation routine may be an obvious candidate. (If
a chip doesn't support this kind of interrogation, or if it must be
overridden, well, it must go into the chip .cdl after all.)
eCos directory structure
Should NAND be grouped under flash in packages/io and packages/devs? To
be honest, the interface under which NAND flash is approached only
vaguely resembles that for NOR flash. When we would choose for
flash/nand, then we should also have to have flash/nor/ and move all
things currently flashing down there.
+++ My proposal:
have packages/io/nand/ and packages/devs/nand/* *beside* packages/flash/
and packages/devs/flash/*. They are very different. Also, who wants
refactoring of flash/* into flash/nor/*.
Is there a case to be made for separate nand/controller/ and nand/chip/
NAND eCos device type
NAND flash is neither a character device (CHAR_DEVTAB_ENTRY), nor a
block device (BLOCK_DEVTAB_ENTRY), nor a net device (NET_DEVTAB_ENTRY),
nor a flash device in the sense of the eCos device driver structure.
- must be erased in 'blocks'
- must be programmed/read in (partial) pages (there usually is a good
number of pages per block)
- has a 'spare' area for each page (to store ECCs, bad block info, and
client, e.g. file system info); spare is to be handled explicitly
- has single-bit failures, corrected by ECCs
- has bad blocks
- and may have a copy-back function to relocate data within the flash chip.
NAND controllers may calculate ECCs in hardware on the fly.
So, should we copy/paste one of those many device driver infrastructures
and modify them to accomodate the NAND flash devices?
eCos NOR flash has solved this in its own way: it does device lookup
based on the addresses that the NOR flash is memory-mapped to. But NAND
flash is *not* memory-mapped. Besides, NAND flashes can/will exceed 4GB
in size, so they cannot be addressed with 32bits.
+++ My proposal:
= I would rather create NAND devices as just DEVTAB_ENTRYs, and mark
them as NAND (or OTHER or ...) i.s.o. CHAR/BLOCK type. The function
dispatch block ptr can be cast, or it can be put in the private area.
This way one can do device lookup in the normal way with cyg_io_lookup()
("/dev/nand0" resolves to a device handle).
= I propose to create two separate device types: NAND controllers and
NAND chips. The two device types might be designated as "/dev/nand0" for
controller 0, and "/dev/nand0.2" for the third chip connected to
I agree that this is kind of broken. But I have trouble thinking of a
way to do device lookup otherwise. Besides, we might consider
generalization of the device structure in the sense that the functions
block is no longer strictly typed. Its actual type might be derived from
the device driver type field.
External interface of NAND devices (controller on top of chip)
+++ My proposal:
the ONFI functions exported by the generic NAND controller code are
- lookup/init; a controller must initialize any chips it owns, locating
them e.g. by their names ("/dev/nand0" owns "/dev/nand0.0" ..
- programming of a (partial) page incl spare
- reading of a (partial) page incl spare, optionally exporting the
controller's calculated ECC
- erase of a block
- marking block as bad
- querying block badness
- retrieving initial bad block table
To be extended later:
- reading/programming of multiple pages ?within a block
- interleaved support
The spare area will usually have fields for ECC values, either
calculated by the layer above, or by a controller that supports it.
So, at the NAND flash layer, there is no attempt to hide bad blocks,
spare areas, ECC handling. The layer above (file system, 'contiguous'
programmer) must handle that.
This exactly fits the YAFFS2 interface (sorry, no idea about JFFS2, but
I'd hope so).
I don't know yet how 'contiguous' programming should work. Typical
application: the boot loader code. For NAND flash booting, typically a
first-level bootstrap is read from block 0 (guaranteed to be 'good').
This contains code to copy the rest of the bootloader code from NAND
flash to RAM, while taking in consideration any bad blocks. Hmmm...
would there be any interest in this? As for me, I am currently just
interested in getting YAFFS2 alive.
Well, I hope that this is understandable, and sorry that it is so much.
Looking forward to your comments,
Before posting, please read the FAQ: http://ecos.sourceware.org/fom/ecos
and search the list archive: http://ecos.sourceware.org/ml/ecos-discuss