Eboot中應用NandFlash

注:本文nand flash 是基於K9F1G08U0B

 

K9F1G08U0B的陣列結構圖如下

 

圖1

Nand flash存儲操作特點:

以頁爲單位進行讀寫,以block爲單位進行擦除

 

我們基於usb來download鏡像的eboot來學習nandflash的應用,download的菜單一般如下所示:

 

圖2

基於usb來download內核映像的步驟是:F -> 9 -> U,那麼我們先來看F對應的功能

 

1.       格式化nandflash

 

1.1   ECC校驗

 

nandflash的每一頁有兩區:main區和spare區,main區用於存儲正常的數據,spare區用於存儲其他附加信息,其中就包括ECC校驗碼。當我們在寫入數據的時候,我們就計算這一頁數據的ECC校驗碼,然後把校驗碼存儲到spare區的特定位置中,在下次讀取這一頁數據的時候,同樣我們也計算ECC校驗碼,然後與spare區中的ECC校驗碼比較,如果一致則說明讀取的數據正確,如果不一致則不正確。ECC的算法較爲複雜,好在s3c2440能夠硬件產生ECC校驗碼,這樣就省去了不少的麻煩事。s3c2443即可以產生main區的ECC校驗碼,也可以產生spare區的ECC校驗碼。因爲K9F1G08U0B是8位IO口,因此s3c2443共產生4個字節的main區ECC碼和2個字節的spare區ECC碼。在這裏我們規定,在每一頁的spare區的第0個地址到第3個地址存儲main區ECC,第4個地址和第5個地址存儲spare區ECC。產生ECC校驗碼的過程爲:在讀取或寫入哪個區的數據之前,先解鎖該區的ECC,以便產生該區的ECC。在讀取或寫入完數據之後,再鎖定該區的ECC,這樣系統就會把產生的ECC碼保存到相應的寄存器中。main區的ECC保存到NFMECC0/1中(因爲K9F1G08U0B是8位IO口,因此這裏只用到了NFMECC0),spare區的ECC保存到NFSECC中。對於讀操作來說,我們還要繼續讀取spare區的相應地址內容,已得到上次寫操作時所存儲的main區和spare區的ECC,並把這些數據分別放入NFMECCD0/1和NFSECCD的相應位置中。最後我們就可以通過讀取NFESTAT0/1(因爲K9F1G08U0B是8位IO口,因此這裏只用到了NFESTAT0)中的低4位來判斷讀取的數據是否正確,其中第0位和第1位爲main區指示錯誤,第2位和第3位爲spare區指示錯誤。

 

1.2 寫sector的SectorInfo結構數據到spare field中。

對應於代碼的實現部分如下所示:

 

圖3

下面我們來看看這部分是如何格式化nand flash的,先看結構體SectorInfo的定義:

typedef struct _SectorInfo

{

    DWORD dwReserved1;     2         // Reserved - used by FAL,爲FAL保留的字節

    BYTE  bOEMReserved;     3        // For use by OEM,爲OEM保留的字節

    BYTE  bBadBlock;         1     // Indicates if block is BAD,壞塊標識

    WORD  wReserved2;     4          // Reserved - used by FAL,爲FAL保留的字節

   

}SectorInfo, *PSectorInfo;

對這個結構體的初始化代碼如下:

 

圖4

我們知道nandflash主要以page(頁)爲單位進行讀寫,以block(塊)爲單位進行擦除。每一頁中又分爲main區和spare區,main區用於正常數據的存儲,spare區用於存儲一些附加信息,如塊好壞的標記、塊的邏輯地址、頁內數據的ECC校驗和等。K9F1G08U0B中關於一頁中main field和spare field的結構如下:

 

圖5

下面接下來通過調用函數來把第0到第3個block標識爲只讀與保留的壞塊,如下代碼如下:

 

 

圖6

這裏主要是通過調用函數FMD_WriteSector來實現的,這個函數會調用FMD_LB_WriteSector()

主要部分如下所示:

 

圖7

下面就來看看NAND_LB_WriteSectorInfo的函數體吧

 

圖8

下面合適接着看NAND_LB_WriteSectorInfo函數的後部分

 

圖9

下圖是大頁面的nandflash一頁的結構圖:

 

 

10

下圖是K9F1G08U0B編程和讀狀態的操作時序圖

 

圖11

 

1.3   調用函數FMD_GetBlockStatus來獲取存放eboot之後的所有的blcok的狀態

 

該函數獲得nandflash中某一個block的狀態。參數爲nandflash的block地址。由於nandflash中可能有壞塊,所以針對nandflash,這個函數首先會檢查當前塊是否是壞塊,這個一般通過讀取當前block的第0個page和第1個page的帶外數據。對於小page nandflash一般是讀取第5個byte,對於大page nandflash一般讀取第0個byte,如果不爲0xff表示該塊是壞塊。當然,至於具體該讀哪個byte,最好還是看一下所用nandflash的datasheet,確認一下,不同的廠家可能有所不同。如果發現該塊是壞塊,應該返回BLOCK_STATUS_BAD。如果不是壞塊,需要讀取這個塊的起始扇區的扇區信息。如果讀該扇區信息出錯,應該返回BLOCK_STATUS_UNKNOWN,否則,判斷獨到的信息,返回相應結果。

 

具體是如何實現的呢,我們先來看函數的調用關係:

FMD_GetBlockStatus() -> FMD_LB_GetBlockStatus() -> FMD_LB_ReadSector() -> NAND_LB_ReadSectorInfo(),主要是通過NAND_LB_ReadSectorInfo函數來實現的,下面就來看看這個函數的內容:

 

圖12

下圖是讀操作的時序圖中的一部分:

 

圖13

接着看NAND_LB_ReadSectorInfo函數的後半部分的實現:

 

圖14

下面接着看ECC_CorrectData函數的實現

 

圖15

下面我們回到FMD_LB_GetBlockStatus函數中來

 

圖16

 

1.4   擦除eboot之後的非壞塊

 

圖17

下圖是判讀K9F1G08U0B某一塊爲壞塊的根據和流程圖

 

圖18

下面來看看是如何擦除塊的,函數的調用關係是:FMD_EraseBlock() -> FMD_LB_EraseBlock(),在看FMD_LB_EraseBlock函數之前,先來看看K9F1G08U0B對擦除塊的操作時序圖

 

圖19

擦除是以塊爲單位進行的,因此在寫地址週期是,只需寫兩個行週期,在擦除結束前還要判斷是否擦除操作成功,FMD_LB_EraseBlock函數體如下:

 

圖20

到此在下載NK.bin之前的格式化動作已經完成。

 

2. 在nandflash上建立BINFS分區,通過USB下載的NK.bin會保存在這個分區中。

代碼入下圖所示:

 

圖21

這部分的內容見我的另一篇博文:

http://blog.csdn.net/LoongEmbedded/archive/2010/11/02/5981033.aspx

 

3.下載NK.bin

至於如何下載可以參考我的博文:WINCE6.0+S3C2443的啓動過程系列博文

http://blog.csdn.net/LoongEmbedded/archive/2010/11/02/5981033.aspx

 

 

一些概念說明:

 

FAL及FMD做基本定義的說明如下:

 

FMD(FLASH Media Driver)可針對特定廠商的Flash作Driven、Read、Write、Erase等動作,實際上去對Flash做讀寫的操作。

 

FAL(FLASH Abstraction Layer):File System對Flash讀寫,必須透過此層操作。而此層則再更加FMD所提供的Interface再對Flash做讀寫。

 

NFSECC:Whenever data is read or written, the spare area ECC module generates ECC parity code on register

 

NFSECCD is for ECC in the spare area (Usually, the user will write the ECC value generated from main data area to Spare area, which value will be the same as NFMECC0/1) and which is generated from the main data area.

 

NFSECCD(nandflash的spare區ECC寄存器),NFMECCD0/1(nandflash的main區ECC寄存器),NFSECC(nandflash用於IO的ECC寄存器)。


 

參考鏈接:

http://blog.csdn.net/renpine/archive/2009/09/20/4572347.aspx

壞塊http://apps.hi.baidu.com/share/detail/15657923

s3c2440對nandflash的操作(轉載)http://www.360doc.com/showWeb/0/0/70026701.aspx



轉自:LoongEmbedded的博客http://blog.csdn.net/loongembedded/article/details/6015302


發佈了34 篇原創文章 · 獲贊 12 · 訪問量 16萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章