2015年1月19日 星期一

SLC Nand Flash driver

這次由於公司硬體平台原本的三星Nand Flash(K9F1G08U0D)即將停產,因此將更換別的廠牌的Nand Flash。由於更換過後的Nand Flash無法在linux運作正常,但卻可以於uboot上正常讀寫,為了可以讓新的Nand Flash可以運作正常,藉由此次機會深入nand flash linux driver的研究。

平台介紹
OS:Linux 2.6.21
SOC:S3C2416 (ARM9 400MHZ)

Nand Flash規格簡介
原本Nand Flash 型號是三星的K9F1G08U0D,更換成Zentel的A5U1GA31ATS-BC。
這兩個Nand Flash都是同樣規格。規格列示如下:
1. SLC (Single Level Cell)
2. 資料容量: 128MByte
3. Page大小:(2K+64) Byte (2K屬於Large Page的Flash,64Byte是spare area的大小)
4. 每個Block有128個Page。
5. Block大小:(128K+4K) Byte  (同理4K是spare area的大小==>64*128=4K)
6. 1 bit HW ECC , HW ECC
7. 8 bit I/O (進行資料/命令/位址的傳輸)

Nand Flash硬體特性
1. SLC / MLC

Nand Flash按照內部存資料單元的單個記憶體單元中,是儲1位元資料,還是多位元資料,可以分為SLC和MLC。


項目
SLC
MLC
名稱
Single Level Cell
Multi Level Cell
儲存單元位元數
一位元
二位元(4 Level Cell;22次方)
四位元(16 Level Cell;24次方)
使用壽命(eraseprogram的次數)
1萬或五千次
10萬次
寫入速度
較快
讀的速度接近SLC,但是寫的速度大概是SLC的四分之一
單位價格
較高
較低
ECC
1Bit ECC(修正1bit,檢測2bit)
24Bit ECC

雖從上表中,可以看到SLC的寫入速度和使用壽命明顯優於MLC,然而由於MLC成本較低,且儲存容量較大,體積較小,因此今後的發展方向還是以MLC為主。且目前已經有許多的方式可以解決MLC的讀寫次數的壽命問題,例如,有些SOC已經有提供wear leveling技術,平均分散每次寫資料的區域,避免某個單一區域過多的寫資料,提高MLC的壽命問題。而2bit 或是4bit的ECC,可以解決資料正確性問題,如此可以解決MLC的缺點。


2. ECC (Error Correction Code)
Nand Flash由於物理特性,Nand Flash中cell的電荷會慢慢漏電,導致資料不正確;抹除和寫資料次數越多,漏電的情形會更嚴重。為了確保資料的正確性,Nand Flash需要ECC功能來偵測糾正Nand Flash內部的隨機位元錯誤。通常Nand Flash本身並不提供ECC功能,而是由SOC的Nand Flash Controller來提供。

3. Spare Area
Flash的每一個頁,除了main area存放資料之外,還有另一個區域,稱為spare area。此在Linux系統中,稱此為OOB(Out Of Band),會有這個區域的原因,最初是因為Nand Flash資料在讀寫時候容易出錯,為了確保資料的正確性,此區域,用於放置ECC。除此之外,也會放置如下資訊: 
    1. 標記目前此頁所在的block是否是bad block。
    2.儲存一些檔案系統相關的資料。


4. Flash名稱的由來
Flasherase操作是以block為單位的, 在每次進行program operation時,Flash會先進行erase operation,會抹除整個block,全部抹除為1,即block的資料全部都是0xFF了,由於瞬間抹除,可以用一閃(flash)而過來比擬,所以叫做Flash Memory

5. 讀寫單位
讀取/寫入的最小單位 : page
擦除(Erase)操作的最小單位 : block


6. Nand Flash  組織圖 (此圖來至三星K9K8G08U0A Datasheet)



從上圖可以知道,一塊Nand Flash被分為若干Block,每個Block又被分為若干Page.

K9F1G08U0D共有128M Bytes,每個Page2K Byte,一個Block有64個Page,因此一個Block共有128K Bytes的容量,因此一個Nand Flash 共有1024個Block (128M Bytes /  128K Bytes = 1024)。


Nand Flash Read/Write Protocol

//to do

Nand Flash 控制器

由於與Flash Chip通訊需要遵守時序問題,且又為了簡化與Flash溝通,並藉由Nand Flash提供ECC機制,因此現今的SOC大都有Nand Flash Controller。

1.重要暫存器簡介(以下只討論SLC的Nand Flash):

NFCONF: 為 Configuration register,用來設定Nand Flash Controller與目標Nand Flash Chip的通訊相關設定。設定的項目有ECCType設定(1 bit ecc),時序相關設定(時序相關議題會在後面描述),PageSize設定(2K Byte),AddrCycle設定(4 address cycle)。NFCONF需在Nand Flash driver的nand_probe裡面設定完成,以便初始化Nand Flash Driver的設定。

NFCONT 為 Control register,在Nand Flash driver中,最主要用來控制Nand Flash Controller ECC模組的運作。由於Nand Flash的讀跟寫與ECC模組的運作密切相關,因此藉由此Register的介紹並搭配driver在此的運作流程。

執行Write Operation分為兩個step
   1.先執行main area的寫入
   2.再執行spare area(linux driver 稱為 oob)的寫入。

上述兩步驟,運作方式大致都相同,差別只在於資料不同而已(Main area / spare area)。在執行Write Operation之前,先Init Main Area ECC module(將NFCONT[5]設為1),再將Main Area ECC module unlock(將NFCONT[7]設為0),之後開始執行Write Operation便會在NFMECC0這個Register產生ECC碼(供下次讀取資料時,可以做資料驗證用途),在讀取ECC碼之前,必須將Main Area ECC module lock(將NFCONT[7]設為1),以防止已經產生好的ECC碼會因為其它操作而改變。於是Driver便會將NFMECC0這個Register產生的ECC碼,寫到oob buffer的main area ecc區域(第40個byte到第55個byte)。 (註: spare area的寫入也會產生ecc碼,稱為secc==>spare area ecc,這個ecc碼會寫入oob buffer的第60個byte到第63byte。另外比較奇怪的一點是,NFCONT有提供main area ecc和spare area ecc 兩個不同的module,然而driver中,有讀寫spare area,但在寫spare area的過程中,僅使用main ecc module產生的ecc碼,而非spare ecc module,這點倒是挺奇怪的)。




執行Read Operation分為兩個step
   1.先執行spare area的讀取。
   2.再執行main area的讀取。

執行Read Operation在採用ECC Module的方式與Write Operation相同,先Init Main Area ECC module(將NFCONT[5]設為1),再將Main Area ECC module unlock(將NFCONT[7]設為0), 由於所讀取的資料是當初寫進去的,在當初寫進去的過程中,都會將當時產生的ecc碼寫入oob的第40~55 bytes(main area ecc)和60~63(spare area ecc),因此在讀取過程中,會再將之前寫入時所產生的ecc碼拿出來作驗證,並填入NFMECCD0NFMECCD1這兩個Register作驗證,此時驗證的結果會產生於NFECCERR0。此Register會將驗證結果呈現出來,例如NFECCERR0[1:0]會指明如下錯誤:

00 = No Error
01 = 1-bit error(correctable)
10 = Uncorrectable
11 = ECC area error

然而由於SLC採用的是1 bit ecc,即假設有一個bit錯誤時,可以更正,但是當有兩個以上的bit錯誤,便無法更正了。