노무현 대통령 배너


2006. 3. 22. 13:31

[본문스크랩] NAND Flash

NAND FLASH

NAND vs. NOR

Beside the different silicon cell design, the most important difference between NAND and NOR Flash is the bus interface. NOR Flash is connected to a address / data bus direct like other memory devices as SRAM etc. NAND Flash uses a multiplexed I/O Interface with some additional control pins. NAND flash is a sequential access device appropriate for mass storage applications, while NOR flash is a random access device appropriate for code storage application.NOR Flash can be used for code storage and code execution. Code stored on NAND Flash can't be executed frome there. It must be loaded into RAM memory and executed from there.

NOR Flash와 NAND Flash의 가장 큰 차이는 버스 인터페이스이다. NOR Flash는 SRAM과 같은 다른 메모리 디바이스들과마찬가지로 어드레스/데이타 버스에 바로 연결된다. NAND Flash는 몇명 제어핀이 추가된 다중화된 I/O 인터페이스를 사용한다. NOR Flash가 코드 저장에 적합한 랜덤 엑세스 디바이스인데 반해 NAND Flash는 데이타 저장에 적합한 순차 엑세스 디바이스다. NOR Flash가 코드가 저장/실행되는 저장 장치인데 반해 NAND Flash 저장된 코드는 NAND Flash상에서 수행될 수 없다. NAND Flash에 저장된 코드는 RAM으로 로드되어야만 수행될 수 있다.

NOR NAND
Interface Bus I/O
Cell Size Large Small
Cell Cost High Low
Read Time Fast Slow
Program Time single ByteFast Slow
Program Time multi ByteSlow Fast
Erase Time Slow Fast
Power consumption High Low, but requires additional RAM
Can execute code Yes No, but newer chips can execute a small loader out of the first page(삼성의 OneNAND가 여기에 해당된다.)
Bit twiddling nearly unrestricted 1-3 times, also known as "partial page program restriction"
Bad blocks at ship time NoAllowed

Some facts about write speed.
NAND is typically faster than NOR for large writes. A typical NOR write is 10uS per word, which results in 1280uS per 512 bytes on a 32-bit bus. A typical NAND write is 50nS per byte + 10uS page seek + 200uS program which results in 236uS per 512 bytes on a 8 bit bus.

As NAND Flash is cheaper than NOR Flash and has a very slim interface it was selected as the optimum solution for large nonvolatile storage applications such as solid state file storage, digital audio/voice recorder, digital still camera and portable applications requiring non-volatility.

속도에 관한 몇몇 사실.

일반적으로 NAND는 대량 기록시 NOR보다 빠르다. NOR의 전형적인 기록속도는 32-비트 버스상에서 512-바이트를 기록하였을 때, 1280uS로 워드당 10us 정도이다. NAND의 경우 8-비트 버스를 통해 512-바이트를 기록하였을 때, 236uS로 이는 바이트당 50nS에 200uS의 기록시간과 10uS의 페이지 탐색시간을 합한 수치이다. NAND Flash는 NOR Flash에 비해 저렴한데다 작은 인터페이스이므로 대용량의 비 휘발성 저장 매체를 필요로하는 어플리케이션에서는 가장 적합한 선택이될 수 있다.


NAND Types

There are various types of NAND Flash available. Bare NAND chips, SmartMediaCards, DiskOnChip.

SmartMediaCards are bare NAND chips covered by thin plastic. They are very common in digital cameras and MP3 players. The card itself contains nothing smart at all. It gets smart by software.

DiskOnChip is NAND Flash with additional glue logic as a drop in replacement for NOR Flash chips. The glue logic provides direct memory access to a small address window, which contains a boot loader stub, which loads the real boot code from the NAND device. The logic contains also control registers for the static NAND chip control lines and a hardware ECCgenerator.

NAND flash의 종류에는 깡짜 NAND 칩, SmartMediaCard, DiskOnChip등이 있다.
SmartMediaCard는 깡짜 NAND에 껍데기를 입혀놓은 놈으로 디카와 MP3 플레이어에 주로 사용된다. 카드 자체에는 smart한 기능이 전혀 들어가 있지 않으며 SW에 의해서 smart 해진다.
DiskOnChip은 NOR Flash를 대체할 수 있도록 글루 로직이 추가되어있다. 이 글루 로직은 아주 작은 메모리윈도우를 CPU의 주소 공간에서 직접적으로 바라 볼 수 있도록 해주며 이 메모리 윈도우에는 NAND 디바이스에 저장된 실제 부트 코드를 로드하는 코드가 저장된다. 또한 여기에는 NAND chip 제어 라인과 HW ECC 제너레이터를 제어할 때 사용되는 레지스터가 포함되어 있다.


NAND technical view

The memory is arranged as a array of pages. A page consists of 256 / 512 Byte data and 8 / 16 Byte spare (out of band) area. Newer chips have 2048 Bytes data and and 64 Bytes spare area sizes. The spare area is used to store ECC (error correction code), bad block information and filesystem dependend data. n pages build one block. The read / write access to data is on a per page basis. Erase is done on a per block basis. The commands to read / write / erase the chip is given by writing to the chip with the Command Latch Enable pin high. Address is given by writing with the Address Latch Enable pin high.

NAND Flash 메모리는 페이지들의 배열로 정렬되어 있다. 하나의 페이지는 256 혹은 512-바이트의 데이터와 8 혹은 16-바이트의 spare(혹은 Out Of Band) 영역으로 구성된다. 최근의 칩들은 2048-바이트 데이터에 64-바이트 spare 영역을 사용하기도 한다. Spare 영역에는 Error Correction Code(ECC), 불량블럭에 관한 정보, 파일 시스템과 관련된 데이터 등이 기록된다. 블럭은 n개의 페이지로 구성되는데 데이터에 대한 읽기/쓰기 동작은 페이지 단위로 수행되며 지우기 동작은 블럭단위로 수행된다. 칩에 대한 읽기/쓰기/지우기 명령은 Command Latch Enable 핀이 High인 상태에서 chip에 대한 write로 수행되며 주소는 Address Latch Enable 핀이 High 상태에서 write하여 전달한다.

There are only a few lines neccecary to access NAND Flashmemory.

16 bit buswidth chips are supported.

Pin(s) Function
I/O 0-7(15)Data Inputs/Outputs
/CE Chip Enable
CLE Command Latch Enable
ALE Address Latch Enable
/RE Read Enable
/WE Write Enable
/WP Write Protect
/SE Spare area Enable
R/B Ready / Busy Output

As it is neccecary to use the spare area, the /SE (Spare area Enable) pin should be tied to GND. /CE, CLE and ALE should be GPIO pins or latched signals. It's possible to use address lines for ALE and CLE, but you have to take care about the timing restrictions of the chip !

/RE and /WE can be tied to the corresponding lines of the CPU. Make sure, that they are logicaly combined with the corresponding chipselect. You can also use two different chipselects for /RE and /WE, but be aware of data hold time constraints of your NAND chip. Data hold time after rising edge of /WE is different to data hold timeafter rising edge of chipselect lines!

I/O 0-7(15) are connected to the databus D0-D7(D15). The /WP pin can be used for write protection or connected to VCC to enable writes unconditionally. As NAND flash uses a command driven programming and erasing, an accidential write or erase is not likely to happen. The Ready / Busy output is not neccecary for operation, but it can be tied to a GPIO or an interrupt line.


Filesystems supporting NAND

One major problem for using NAND Flash is, that you cannot write as often as you want to a page. The consecutive writes to a page, before erasing it again, are restricted to 1-3 writes, depending on the manufacturers specifications. This applies similar to the spare area. This makes it neccecary for the filesystem to handle a writebuffer, which contains data, that is less than a page

NAND Flash를 사용할 때, 가장 큰 문제점들 중 하나는 페이지에 대한 데이터 기록을 원하는만큼 자주할 수 없다는 것이다. NAND Flash 제조사에 따라 다르겠지만 지우지 않고 연속적으로 페이지에 write할 수 있는 회수는 1~3회로 제한되어 있다. 이 제한사항은 spare 영역도 크게 다르지 않다.

At the moment there are only a few filesystems, which support NAND

  • JFFS2 and YAFFS for bare NAND Flash and SmartMediaCards
  • NTFL for DiskOnChip devices
  • TRUEFFS from M-Systems for DiskOnChip devices
  • SmartMedia DOS-FAT as defined by the SSFDC Forum

JFFS2 and NTFL are Open Source, while TRUEFFS is a proprietary solution. SmartMedia DOS-Fat is a specification from SSFDC forum. It is somewhat open under a non disclosure agreement with Toshiba, who owns all rights on this specifications. NTFL is designed for the usage of DiskOnChip devices. JFFS2 supports raw NAND chips and SmartMediaCards at the moment. A JFFS2 support for DiskOnChip devices, based on the NAND code, is planned. There are some other Open Source projects for NAND filesystem support, but there's no other working solution than JFFS2 and YAFFS at the moment of this writing. YAFFS is available from YAFFS-Homepage. YAFFS is faster than JFFS2 and consumes less RAM, JFFS2 provides on the fly file compression and decompression, which is very helpfull for small FLASHs.

There is currently no support for the wide spread SmartMedia DOS-FAT filesystem, mainly because it's not a reliable filesystem for industrial usage. It's ok for multimedia applications. The hardware support layer is designed to support an implementation of SmartMedia DOS-FAT, but nobody has made an attempt to implement it really. There are a couple of SmartMedia Card adaptors for USB, PCMCIA, FireWire ... with Linux drivers available, which support the SmartMedia DOS-FAT.

JFFS2 and YAFFS include bad block management, wear leveling, error correction and provide reliable filesystems for industrial use on top of NAND Flash.

JFFS2/YAFFS
Open Source
Bad block management
Wear leveling
Error correction


JFFS2
깡짜 NAND 칩, SmatMediaCard 지원.
파일 압축/해제를 지원

YAFFS
JFFS2보다 빠르고 RAM을 작게 사용


Technical information for filesystem implementation

Multiple filesystems on different partitions

You can mount different filesystems on different partitions of the same chip.

OOB usage

As the OOB usage of the filesystems differs, the OOB usage can be selected on runtime from the filesystem driver. The parameter is given to the functions mtd->read_ecc and mtd->write_ecc. This parameter specifies the location of the ECC-data inside the oob area. The parameter is a structure named nand_oobinfo.
struct nand_oobconfig {
int useecc;
int eccbytes
int eccpos[24];
int oobfree[8][2];
}
With this structure the usage of ecc and the position of ecc-data in the oob area are given. The content of useecc selects the ecc operation mode:

  • MTD_NANDECC_OFF
    Do not use ECC
  • MTD_NANDECC_PLACE
    Use ECC and place the ECC bytes at the position given by the eccpos array
  • MTD_NANDECC_AUTOPLACE
    Use ECC and place the ECC bytes at the position given by the autoplacement defaults in the nand driver

All non ecc functions like mtd->read and mtd->write use an internal structure, which can be set by an ioctl. This structure is preset to the autoplacement default
ioctl (fd, MEMSETOOBSEL, oobsel);, where oobsel is a pointer to a user supplied structure of type oobconfig. The contents of this structure must match the criteria of the filesystem, which will be used. See an example in utils/nandwrite.c.

OOB autoplacement layout

Nand chips with 256 byte pagesize and 8 byte OOB size

OffsetContentComment
0x00ECC byte 0Error correction code byte 0
0x01ECC byte 1Error correction code byte 1
0x02ECC byte 2Error correction code byte 2
0x03Autoplace 0
0x04Autoplace 1
0x05Bad block markerIf any bit in this byte is zero, then this block is bad. This applies only to the first page in a block. In the remaining pages this byte is reserved
0x06Autoplace 2
0x07Autoplace 3

Nand chips with 512 byte pagesize and 16 byte OOB size

OffsetContentComment
0x00ECC byte 0Error correction code byte 0 of the lower 256 Byte data in this page
0x01ECC byte 1Error correction code byte 1 of the lower 256 Bytes of data in this page
0x02ECC byte 2Error correction code byte 2 of the lower 256 Bytes of data in this page
0x03ECC byte 3Error correction code byte 0 of the upper 256 Bytes of data in this page
0x04reservedreserved
0x05Bad block markerIf any bit in this byte is zero, then this block is bad. This applies only to the first page in a block. In the remaining pages this byte is reserved
0x06ECC byte 4Error correction code byte 1 of the upper 256 Bytes of data in this page
0x07ECC byte 5Error correction code byte 2 of the upper 256 Bytes of data in this page
0x08 - 0x0FAutoplace 0 - 7

Nand chips with 2048 byte pagesize and 64 byte OOB size

OffsetContentComment
0x00Bad block markerIf any bit in this byte is zero, then this block is bad. This applies only to the first page in a block. In the remaining pages this byte is reserved
0x01ReservedReserved
0x02-0x27Autoplace 0 - 37
0x28ECC byte 0Error correction code byte 0 of the first 256 Byte data in this page
0x29ECC byte 1Error correction code byte 1 of the first 256 Bytes of data in this page
0x2AECC byte 2Error correction code byte 2 of the first 256 Bytes data in this page
0x2BECC byte 3Error correction code byte 0 of the second 256 Bytes of data in this page
0x2CECC byte 4Error correction code byte 1 of the second 256 Bytes of data in this page
0x2DECC byte 5Error correction code byte 2 of the second 256 Bytes of data in this page
0x2EECC byte 6Error correction code byte 0 of the third 256 Bytes of data in this page
0x2FECC byte 7Error correction code byte 1 of the third 256 Bytes of data in this page
0x30ECC byte 8Error correction code byte 2 of the third 256 Bytes of data in this page
0x31ECC byte 9Error correction code byte 0 of the fourth 256 Bytes of data in this page
0x32ECC byte 10Error correction code byte 1 of the fourth 256 Bytes of data in this page
0x33ECC byte 11Error correction code byte 2 of the fourth 256 Bytes of data in this page
0x34ECC byte 12Error correction code byte 0 of the fifth 256 Bytes of data in this page
0x35ECC byte 13Error correction code byte 1 of the fifth 256 Bytes of data in this page
0x36ECC byte 14Error correction code byte 2 of the fifth 256 Bytes of data in this page
0x37ECC byte 15Error correction code byte 0 of the sixt 256 Bytes of data in this page
0x38ECC byte 16Error correction code byte 1 of the sixt 256 Bytes of data in this page
0x39ECC byte 17Error correction code byte 2 of the sixt 256 Bytes of data in this page
0x3AECC byte 18Error correction code byte 0 of the seventh 256 Bytes of data in this page
0x3BECC byte 19Error correction code byte 1 of the seventh 256 Bytes of data in this page
0x3CECC byte 20Error correction code byte 2 of the seventh 256 Bytes of data in this page
0x3DECC byte 21Error correction code byte 0 of the eigth 256 Bytes of data in this page
0x3EECC byte 22Error correction code byte 1 of the eigth 256 Bytes of data in this page
0x3FECC byte 23Error correction code byte 2 of the eigth 256 Bytes of data in this page

OOB access

Read back OOB data together with main area

If the fs driver needs to read the oobdata together with the raw data, then the fs-driver has to supply a big enough buffer.
size = 12 bytes * number of pages to read (256B pagesize) or 24 bytes* number of pages to read (512B pagesize)
The buffer contains 8/16 byte oobdata and 4/8 byte returncode from correct_ecc
oobbuf [0-15] oob-data 1st read page
oobbuf [16-19] return code from correct_ecc byte 0-255
oobbuf [20-23] return code from correct_ecc byte 256-511
oobbuf [24-39] oob-data 2nd read page
oobbuf [40-31] return code from correct_ecc byte 0-255
.....
The returnvalue of read_ecc is -EIO, if any correct_ecc returned -1. But retlen is equal to the requested length, so fs-driver can decide what to do.

Write OOB data together with main area

Oob data can be given from filesystem to program them in one go together with the raw data. ECC codes are filled in at the place selected by oobsel. This supports multipage programming.
oobbuf[0-15] 1st page to write
oobbuf[16-31] 2nd page to write
.....
ECC is filled in at the appropriate place selected by the above mentioned constants.


JFFS2 specific information

JFFS2 Out of Band usage

JFFS2 uses the default autoplacement scheme. The only JFFS2 specific usage of the oob area is the storage of the cleanmarker

Nand chips with 256 byte pagesize and 8 byte OOB size

OffsetContentComment
0x06Clean marker byte 0This byte indicates that a block was erased under JFFS2 control. If the page was succesfully erased this byte in the first page of a block is programmed to 0x85. In the remaining pages this byte is reserved
0x07Clean marker byte 1This byte indicates that a block was erased under JFFS2 control. If the page was succesfully erased this byte in the first page of a block is programmed to 0x19. In the remaining pages this byte is reserved

Nand chips with 512 byte pagesize and 16 byte OOB size

OffsetContentComment
0x08Clean marker byte 0This byte indicates that a block was erased under JFFS2 control. If the page was succesfully erased this byte in the first page of a block is programmed to 0x85. In the remaining pages this byte is reserved
0x08Clean marker byte 1This byte indicates that a block was erased under JFFS2 control. If the page was succesfully erased this byte in the first page of a block is programmed to 0x19. In the remaining pages this byte is reserved
0x08Clean marker byte 2This byte indicates that a block was erased under JFFS2 control. If the page was succesfully erased this byte in the first page of a block is programmed to 0x03. In the remaining pages this byte is reserved
0x08Clean marker byte 3This byte indicates that a block was erased under JFFS2 control. If the page was succesfully erased this byte in the first page of a block is programmed to 0x20. In the remaining pages this byte is reserved
0x08Clean marker byte 4This byte indicates that a block was erased under JFFS2 control. If the page was succesfully erased this byte in the first page of a block is programmed to 0x08. In the remaining pages this byte is reserved
0x08Clean marker byte 5This byte indicates that a block was erased under JFFS2 control. If the page was succesfully erased this byte in the first page of a block is programmed to 0x00. In the remaining pages this byte is reserved
0x08Clean marker byte 6This byte indicates that a block was erased under JFFS2 control. If the page was succesfully erased this byte in the first page of a block is programmed to 0x00. In the remaining pages this byte is reserved
0x08Clean marker byte 7This byte indicates that a block was erased under JFFS2 control. If the page was succesfully erased this byte in the first page of a block is programmed to 0x00. In the remaining pages this byte is reserved

Nand chips with 2048 byte pagesize and 64 byte OOB size

OffsetContentComment
0x10Clean marker byte 0This byte indicates that a block was erased under JFFS2 control. If the page was succesfully erased this byte in the first page of a block is programmed to 0x85. In the remaining pages this byte is reserved
0x11Clean marker byte 1This byte indicates that a block was erased under JFFS2 control. If the page was succesfully erased this byte in the first page of a block is programmed to 0x19. In the remaining pages this byte is reserved
0x12Clean marker byte 2This byte indicates that a block was erased under JFFS2 control. If the page was succesfully erased this byte in the first page of a block is programmed to 0x03. In the remaining pages this byte is reserved
0x13Clean marker byte 3This byte indicates that a block was erased under JFFS2 control. If the page was succesfully erased this byte in the first page of a block is programmed to 0x20. In the remaining pages this byte is reserved
0x14Clean marker byte 4This byte indicates that a block was erased under JFFS2 control. If the page was succesfully erased this byte in the first page of a block is programmed to 0x08. In the remaining pages this byte is reserved
0x15Clean marker byte 5This byte indicates that a block was erased under JFFS2 control. If the page was succesfully erased this byte in the first page of a block is programmed to 0x00. In the remaining pages this byte is reserved
0x16Clean marker byte 6This byte indicates that a block was erased under JFFS2 control. If the page was succesfully erased this byte in the first page of a block is programmed to 0x00. In the remaining pages this byte is reserved
0x17Clean marker byte 7This byte indicates that a block was erased under JFFS2 control. If the page was succesfully erased this byte in the first page of a block is programmed to 0x00. In the remaining pages this byte is reserved

HOWTO implement NAND support

Where can you get the code ?

The latest changes to JFFS2 and the underlying NAND code are not in the kernel code at the moment. The latest code is available from CVS and daily snapshots

There are four layers of software

  1. JFFS2: filesystem driver
  2. MTD: Memory Technology Devices driver
  3. NAND: generic NAND driver
  4. Hardware specific driver

the MTD driver just provides a mount point for JFFS2. The generic NAND driver provides all functions, which are neccecary to identify, read, write and erase NAND Flash. The hardware dependend functions are provided by the hardware driver. They provide mainly the hardware access informations and functions for the generic NAND driver. For YAFFS applies the same.

Hardware driver

To implement it on your hardware, you will have to write a new hardware driver. Copy one of the existing hardware drivers and modify it to fit your hardware. These basic functions have to be modified:

  1. Hardware specific control function
  2. Device ready function
  3. Init function
To provide enough flexibilty for all kind of devices, there can be supplied additional functions optionally. Almost everything can be overridden.
  1. Hardware specific command function
  2. Hardware specific wait function
  3. Hardware ECC functions
  4. Hardware specific chip select function, which supports chiparrays
  5. Hardware specific read, write and verify functions
  6. Hardware specific bad block management

Hardware specific control function

This function sets and resets the control pins CLE, ALE and CE of the NAND device depending on the function argument. The argument constants are defined in nand.h and explained in the example function below.

void yourboard_hwcontrol(int cmd)
{
switch(cmd){
case NAND_CTL_SETCLE: Hardware specific code to set CLE line to 1; break;
case NAND_CTL_CLRCLE: Hardware specific code to set CLE line to 0; break;
case NAND_CTL_SETALE: Hardware specific code to set ALE line to 1; break;
case NAND_CTL_CLRALE: Hardware specific code to set ALE line to 0; break;
case NAND_CTL_SETNCE: Hardware specific code to set CE line to 0; break;
case NAND_CTL_CLRNCE: Hardware specific code to set CE line to 1; break;
}
}

Device ready function

If your hardware interface has the ready busy pin of the NAND chip connected to a GPIO or other accesible I/O pin, this function is used to read back the state of the pin. The function has no arguments and should return 0, if the device is busy (R/B pin is low) and 1, if the device is ready (R/B pin is high). If your hardware interface does not give access to the ready busy pin, you can delete this function and set the function pointer this->dev_ready during init to NULL.

int yourboard_device_ready(void)
{
return The state of the ready/busy pin of the chip;
}

Init function

This function is called, when the driver is initialized either on kernel boot or when you load your driver as a module. The function remaps the I/O area, through which your NAND chip can be accessed, allocates all neccecary memory chunks for the device structure and data cache. The structure of the device has to be zeroed out first and then filled with the neccecary information about your device. See example code for the most important members of the device structure you have to set.

int __init yourboard_init (void)
{
SNIP
/* Allocate memory for MTD device structure and private data */
yourboard_mtd = kmalloc (sizeof(struct mtd_info) + sizeof (struct nand_chip),GFP_KERNEL);
SNIP
/* map physical adress */
yourboard_fio_base=(unsigned long)ioremap(yourboard_fio_pbase,SZ_1K);
SNIP
/* Set address of NAND IO lines */
this->IO_ADDR_R = yourboard_fio_base; The address to read from the chip
this->IO_ADDR_W = yourboard_fio_base; The address to write to the chip
this->hwcontrol = yourboard_hwcontrol;Your function for accessing the controllines
this->dev_ready = yourboard_device_ready; Your function for accessing the ready/busy line or NULL, if you don't have one
this->chip_delay = 20;The delay time (us), after writing a command to the chip, according to datasheet (tR)
this->eccmode = NAND_ECC_XXX; Set the correct ECC generator mode for your board. This defaults to NAND_ECC_SOFT. Notes about hardware ECC can be found below.
SNIP
}

Hardware specific command function

Some new CPU's like Samsungs ARM based S3SC2410 provide a hardware based NAND interface. For them and ugly designed hardware interfaces it may be neccecary to have a customized command write function. You can supply such a function by setting
this->cmdfunc = yourboard_cmdfunc;
This must be done in yourboard_init before calling nand_scan.

The function is defined as
void yourboard_cmdfunc (struct mtd_info *mtd, unsigned command, int column, int page_addr);

Hardware specific wait function

If you have connected the ready/busy pin to an interrupt line, you could supply a own interrupt driven waitfunction for erase and program wait for ready. In this case set

this->waitfunc = yourboard_waitfunction;
This must be done in yourboard_init before calling nand_scan.

The function is defined as
int yourboard_waitfunction (struct mtd_info *mtd, struct nand_chip *this, int state);
Please take care of the functionality, which is in standard nand driver wait function (nand_wait).

Hardware based ECC

If your hardware supplies a hardware based ECCgenerator, then fill out the following. If not, skip this topic.

this->eccmode =NAND_ECC_HW3_256;
or
this->eccmode = NAND_ECC_HW3_512;
or
this->eccmode = NAND_ECC_HW6_512;

NAND_ECC_HW3_256 is a hardware based ECC generator, which generates 3 byte ECCcode for 256 byte of data. Such a generator can be found on DOC devices and on passive SmartMedia adaptors.
NAND_ECC_HW3_512 is a hardware based ECCgenerator, which generates 3 byte ECCcode for 512 byte of data. Such a generator can be found e.g. on Samsungs ARM based S3SC2410 CPU.
NAND_ECC_HW6_512 is a hardware based ECCgenerator, which generates 6 byte ECCcode for 512 byte of data.

You have also to provide following functions:

Enable hardware ECC generator

void yourboard_enable_hwecc (int mode);

Your function to enable (reset) the hardware ECC generator. This function is called from the generic nand driver before reading or writing data from/to the chip. The function is called with NAND_ECC_READ or NAND_ECC_WRITE as argument.
Set the function pointer in init to
this->enable_hwecc =yourboard_enable_hwecc;

Enable hardware ECC generator

void yourboard_readecc(const u_char *dat, u_char *ecc_code);

Your function to read back the ECC bytes from your hardware ECCgenerator. Fill the data into the ecc_code array, which is given as argument. Ignore the first argument of this function, which is neccecary for software ecc only. Set the function pointer in init to
this->calculate_ecc =yourboard_readecc;

Error detection and data correction function

int xxxx_correct_data(u_char *dat, u_char *read_ecc, u_char *calc_ecc);

A function which implements error detection and data correction corresponding to your hardware ECCalgorithm. This function should be incorporated into nand_ecc.c with an appropriate function name, to make it public available for similar hardware drivers. Maybe the function you need is already there. If you implement a new one, please contact NAND driver maintainer to include it in the public source tree. Please consult current implementations in nand_ecc.c to provide a compatible solution. Set the function pointer in init to
this->correct_data =xxxx_correct_data;

All the function pointers must be set in yourboard_init before calling nand_scan.

Hardware specific chip select function for chip arrays

The driver supports chip arrays, which share the I/O lines and the controllines. There is no support for arrays which extend the buswidth.

The hw specific chip select function is called with the chipnr (0 - n-1) or with -1. -1 indicates that the chips must be deselected.

Supported chips

Most NAND chips actually available should be supported by the current code. If you have a chip, which is not supported, you can easily add it by extending the chiplist in drivers/mtd/nand/nand_ids.c. The chip name does not longer contain cryptic part numbers, as the device ID is just an information about size, erase block size, pagesize and operating voltage. Add an entry, which contains following information:
{ name, id, pagesize, chipsize, erasesize, options }

refcomment
namestring: "NAND 'size' 'voltage' 'bus-width'"
idchip device code. This code is read during nand_scan. Check datasheet for the code of your chip
pagesizePage size (0,256,512). 0 indicates that the pagesize can be read out from the chip in the extended ID
chipsizeThe total size of the chip in MiB
erasesizethe erasesize of your chip in bytes. 0 for chips with extended ID
optionsOptions. Bitfield to enable chip specific options. See nand.h

Please contact NAND driver maintainer to include it in the public source tree.

Manufacturer codes are scanned during nand_scan too. If the code is one of the known codes in the manufacturer ID table, the name of the manufacturer is printed out, else "Unknown" is printed. This happens when your hardware driver is loaded and calls nand_scan. Add codes, which are new and contact NAND driver maintainer to include it

Config settings

The following config switches have to be set. JFFS2 on NAND does not work, if one of these settings is missing.

CONFIG_MTD=y
CONFIG_MTD_PARTITIONS=y
CONFIG_MTD_CHAR=y
CONFIG_MTD_BLOCK=y
CONFIG_MTD_NAND=y
CONFIG_MTD_NAND_YOURBOARD=y
CONFIG_JFFS2_FS=y
CONFIG_JFFS2_FS_DEBUG=0
CONFIG_JFFS2_FS_NAND=y

Make sure that fs/Config.in contains the following lines:
dep_tristate 'Journalling Flash File System v2 (JFFS2) support' CONFIG_JFFS2_FS $CONFIG_MTD
if [ "$CONFIG_JFFS2_FS" = "y" -o "$CONFIG_JFFS2_FS" = "m" ] ; then
int 'JFFS2 debugging verbosity (0 = quiet, 2 = noisy)' CONFIG_JFFS2_FS_DEBUG 0
bool 'JFFS2 support for NAND chips' CONFIG_JFFS2_FS_NAND
fi


FAQ

Can I boot from NAND Flash?

Not from a bare NAND chip. You need a glue logic around, which gives you memory access to the chip on bootup, like the DiskOnChip devices do. This will be a quite complex CPLD. An alternative is to use a small e.g. 1MB NOR Flash, which contains the boot code and maybe a compressed kernel image. Then you can use JFFS2 on NAND as your root filesystem

Some newer chips make the first page available for reading after power up. This could be helpful for starting a small 256/512/2048 byte bootcode. At the time of this writing there is no tested implementation of this.

Samsungs S3C2410 ARM based SOC-CPU provides a mechanism to boot from NAND flash.

Is there support for 32bit wide NAND Flash ?

No. The generic NAND driver supports 8/16 bit wide NAND Flash only. 32 bit NAND Flash can be built by using 2 or 4 chips and connect them to D0-7, D8-D15, D16-D23 and D24-D31 on the data bus. You can tie all corresponding control signals together. But you have to build a new nand16 or nand32 driver, which can be derived from the existing nand.c. Be aware, that the writebuffer size is 2 or 4 times as big as on 8 bit NAND. This mean's, if you flush the buffer to ensure, that your data are on disk, you may waste much more memory space than on 8 bit NAND. Another point is bad block handling. When a block on 1 chip is bad, the corresponding blocks on the other chips are lost too, as you present them as one big block to the filesystem driver. The JFFS2 code, which handles the writebuffer and the out of band (spare) area of NAND doesn't support 32 bit neither.

How is ensured, that data is written to flash ?

As we have to handle a writebuffer for writing only full pages to the chips, there could be a loss of data, when the writebuffer is not flushed before power down. There are some mechanisms to ensure, that the writebuffer is flushed. You can force the flush of the writebuffer by using fsync() or sync() in your application. JFFS2 has a timed flush of the write buffer, which forces the flush of the buffer to flash, if there are no writes to the filesystem for more than 2 seconds. When you unmount the filesystem the buffer is flushed too.

If the partition is being used as a root filesystem, which obviously cannot be dismounted, the filesystem should be remounted read only on shutdown. In the case of JFFS2 this will cause the garbage collector to flush its write buffers. Failure to do this may cause the filesystem to generate warnings regarding bad CRC. These are partially collected garbage blocks which will be rescheduled for garbage collection some time later. This kind of behaviour may also be observed after a system crash.

Can I use mtdutils erase / eraseall

Yes, the latest nand driver code forces the protection of bad block information. It's safe to erase a NANDflash with erase(all) /dev/mtdX. It's recommended to use eraseall with -j or --jffs2 option set. This will write the cleanmarker to the out of band area. So you can mount the filesystem and no further formatting is needed. This formatting is also neccecary before you copy a fs-image to the chip.

Can I copy a JFFS2 Image to NAND via /dev/mtdX ?

Yes, as long as your chip does not contain bad blocks. Make sure, that the erasesize you set to mkfs.jffs2 is the same as the erasesize of your chip. Data will only be written with ECC, if your default settings for oob-layout selection are set for JFFS2. For bad block aware copying, use nandwrite from mtd-utils.
nandwrite -j /dev/mtdX image

Can I use seek/read/write on /dev/mtdX ?

Yes, as long as your program is aware of bad blocks. Make sure to set the desired ECC layout by ioctl (MEMSETOOBSEL). A example for bad block handling and usage of ioctl (MEMOOBSEL) can be found in util/nandwrite.c

Recent changes to the NAND layer now make it possible to read/write across a block boundary.

JFFS2 generates messages, is there a problem ?

JFFS2 adopts the philosophy of keeping the user completely appraised of what is going on. This can catch out the unwary novice. The following messages can be moved to a higher log level once you are sure that they are benign.

Empty flash at 0xXXXXXXXX ends at 0xXXXXXXXX

This message is generated if a block of data is partially written. It is generally not a sign of any problem.

jffs2: Erase block size too small (XXKiB). Using virtual blocks size(XXKiB) instead

Output for larger NAND devices to reduce memory allocation.

jffs2: No clean, dirty _or_ erasable blocks to GC from! Where are they all?
jffs2: Couldn't find erase block to garbage collect!

These two messages are generally output together. They are usually output on dismount and simply indicate that the garbage collector has nothing to do. This is more likely to be seen for filesystems which have few files or no activity.

Must my bootloader be aware of NAND FLASH?

Yes, if you use your bootloader to erase the FLASH chip and copy a filesystem image to it. For erase make sure, that you don't erase factory-marked bad blocks. They are marked in the 6th byte (offset 0x5) in the out of band area of the first page of a block. The block is bad, if any bit in this byte is zero. If you erase such a block, the bad block information is erased too and lost. Further use of this block will lead to erroneous results

After the erase it's recommended to programm the JFFS2 erased marker into the out of band area of the first page in each erased block. Do not program it into the data area of the page !

For 256 byte pagesize devices program the following data into the out of band area:

Offset0x060x07
Data0x850x19

For 512 byte pagesize devices program the following data into the out of band area:

Offset0x080x090x0a0x0b0x0c0x0d0x0e0x0f
Data0x850x190x030x200x080x000x000x00

If you copy a filesystem image to the chip, it's recommended to write it with ECC. You can use the ECC code in the nand driver to do this. If you have a bad block on your chip, just skip this block and copy the data to the next block. JFFS2 is able to handle this gap.


References:

Open Source

JFFS2 and NTFL are located on this website.
YAFFS is located at YAFFS-Homepage.

Hardware

Toshiba

Samsung

SSFDC Forum

M-Systems


Maintainers

JFFS2 is maintained by David Woodhouse

The generic NAND driver is maintained by Thomas Gleixner

Please don't contact them direct. Ask your questions on the mtd-mailing-list.

Any suggestions, improvements, bug-reports and bug-fixes are welcome


Thomas Gleixner $Id: nand.html,v 1.18 2004/05/06 09:09:27 gleixner Exp $