Nand Flash基础知识与坏块管理机制的研究
概述
Flash名稱(chēng)的由來(lái),Flash的擦除操作是以block塊為單位的,與此相對(duì)應(yīng)的是其他很多存儲(chǔ)設(shè)備,是以bit位為最小讀取/寫(xiě)入的單位,Flash是一次性地擦除整個(gè)塊:在發(fā)送一個(gè)擦除命令后,一次性地將一個(gè)block,常見(jiàn)的塊的大小是128KB/256KB,全部擦除為1,也就是里面的內(nèi)容全部都是0xFF了,由于是一下子就擦除了,相對(duì)來(lái)說(shuō),擦除用的時(shí)間很短,可以用一閃而過(guò)來(lái)形容,所以,叫做Flash Memory。所以一般將Flash翻譯為 (快速)閃存。
NAND Flash 在嵌入式系統(tǒng)中有著廣泛的應(yīng)用,負(fù)載平均和壞塊管理是與之相關(guān)的兩個(gè)核心議題。Uboot 和 Linux 系統(tǒng)對(duì) NAND 的操作都封裝了對(duì)這兩個(gè)問(wèn)題的處理方法。 本文首先講述Nandflash基礎(chǔ)知識(shí),然后介紹現(xiàn)有的幾類(lèi)壞塊管理(BBM)方法,通過(guò)分析典型嵌入式系統(tǒng)的 NAND 存儲(chǔ)表,指出了輕量級(jí)管理方法的優(yōu)勢(shì)所在,分析了當(dāng)前廣泛使用的輕量級(jí)管理方法,指出其缺陷所在并詳細(xì)說(shuō)明了改進(jìn)方法。
基礎(chǔ)知識(shí)
Flash的硬件實(shí)現(xiàn)機(jī)制
Flash的內(nèi)部存儲(chǔ)是MOSFET,里面有個(gè)懸浮門(mén)(Floating Gate),是真正存儲(chǔ)數(shù)據(jù)的單元。
在Flash之前,紫外線(xiàn)可擦除(uv-erasable)的EPROM,就已經(jīng)采用了Floating Gate存儲(chǔ)數(shù)據(jù)這一技術(shù)了。
典型的Flash內(nèi)存物理結(jié)構(gòu)數(shù)據(jù)在Flash內(nèi)存單元中是以電荷(electrical charge) 形式存儲(chǔ)的。存儲(chǔ)電荷的多少,取決于圖中的外部門(mén)(external gate)所被施加的電壓,其控制了是向存儲(chǔ)單元中沖入電荷還是使其釋放電荷。而數(shù)據(jù)的表示,以所存儲(chǔ)的電荷的電壓是否超過(guò)一個(gè)特定的閾值Vth來(lái)表示,因此,Flash的存儲(chǔ)單元的默認(rèn)值,不是0(其他常見(jiàn)的存儲(chǔ)設(shè)備,比如硬盤(pán)燈,默認(rèn)值為0),而是1,而如果將電荷釋放掉,電壓降低到一定程度,表述數(shù)字0。
NandFlash的簡(jiǎn)介
Nand flash成本相對(duì)低,說(shuō)白了就是便宜,缺點(diǎn)是使用中數(shù)據(jù)讀寫(xiě)容易出錯(cuò),所以一般都需要有對(duì)應(yīng)的軟件或者硬件的數(shù)據(jù)校驗(yàn)算法,統(tǒng)稱(chēng)為ECC。但優(yōu)點(diǎn)是,相對(duì)來(lái)說(shuō)容量比較大,現(xiàn)在常見(jiàn)的Nand Flash都是1GB,2GB,更大的8GB的都有了,相對(duì)來(lái)說(shuō),價(jià)格便宜,因此適合用來(lái)存儲(chǔ)大量的數(shù)據(jù)。其在嵌入式系統(tǒng)中的作用,相當(dāng)于PC上的硬盤(pán),用于存儲(chǔ)大量數(shù)據(jù)。
SLC和MLC
Nand Flash按照內(nèi)部存儲(chǔ)數(shù)據(jù)單元的電壓的不同層次,也就是單個(gè)內(nèi)存單元中,是存儲(chǔ)1位數(shù)據(jù),還是多位數(shù)據(jù),可以分為SLC和MLC。那么軟件如何識(shí)別系統(tǒng)上使用過(guò)的SLC還是MLC呢?
Nand Flash設(shè)計(jì)中,有個(gè)命令叫做Read ID,讀取ID,讀取好幾個(gè)字節(jié),一般最少是4個(gè),新的芯片,支持5個(gè)甚至更多,從這些字節(jié)中,可以解析出很多相關(guān)的信息,比如此Nand Flash內(nèi)部是幾個(gè)芯片(chip)所組成的,每個(gè)chip包含了幾片(Plane),每一片中的頁(yè)大小,塊大小,等等。在這些信息中,其中有一個(gè),就是識(shí)別此flash是SLC還是MLC。
?oob / Redundant Area / Spare Area
每一個(gè)頁(yè),對(duì)應(yīng)還有一塊區(qū)域,叫做空閑區(qū)域(spare area)/冗余區(qū)域(redundant area),而Linux系統(tǒng)中,一般叫做OOB(Out Of Band),這個(gè)區(qū)域,是最初基于Nand Flash的硬件特性:數(shù)據(jù)在讀寫(xiě)時(shí)候相對(duì)容易錯(cuò)誤,所以為了保證數(shù)據(jù)的正確性,必須要有對(duì)應(yīng)的檢測(cè)和糾錯(cuò)機(jī)制,此機(jī)制被叫做EDC(Error Detection Code)/ECC(Error Code Correction, 或者 Error Checking and Correcting),所以設(shè)計(jì)了多余的區(qū)域,用于放置數(shù)據(jù)的校驗(yàn)值。
Oob的讀寫(xiě)操作,一般是隨著頁(yè)的操作一起完成的,即讀寫(xiě)頁(yè)的時(shí)候,對(duì)應(yīng)地就讀寫(xiě)了oob。
關(guān)于oob具體用途,總結(jié)起來(lái)有:
Bad Block Management壞塊管理
Nand Flash由于其物理特性,只有有限的擦寫(xiě)次數(shù),超過(guò)那個(gè)次數(shù),基本上就是壞了。在使用過(guò)程中,有些Nand Flash的block會(huì)出現(xiàn)被用壞了,當(dāng)發(fā)現(xiàn)了,要及時(shí)將此block標(biāo)注為壞塊,不再使用。于此相關(guān)的管理工作,屬于Nand Flash的壞塊管理的一部分工作。
Wear-Leveling負(fù)載平衡
Nand Flash的block管理,還包括負(fù)載平衡。
正是由于Nand Flash的block,都是有一定壽命限制的,所以如果你每次都往同一個(gè)block擦除然后寫(xiě)入數(shù)據(jù),那么那個(gè)block就很容易被用壞了,所以我們要去管理一下,將這么多次的對(duì)同一個(gè)block的操作,平均分布到其他一些block上面,使得在block的使用上,相對(duì)較平均,這樣相對(duì)來(lái)說(shuō),可以更能充分利用Nand Flash。
?ECC錯(cuò)誤校驗(yàn)碼
Nand Flash物理特性上使得其數(shù)據(jù)讀寫(xiě)過(guò)程中會(huì)發(fā)生一定幾率的錯(cuò)誤,所以要有個(gè)對(duì)應(yīng)的錯(cuò)誤檢測(cè)和糾正的機(jī)制,于是才有此ECC,用于數(shù)據(jù)錯(cuò)誤的檢測(cè)與糾正。Nand Flash的ECC,常見(jiàn)的算法有海明碼和BCH,這類(lèi)算法的實(shí)現(xiàn),可以是軟件也可以是硬件。不同系統(tǒng),根據(jù)自己的需求,采用對(duì)應(yīng)的軟件或者是硬件。
相對(duì)來(lái)說(shuō),硬件實(shí)現(xiàn)這類(lèi)ECC算法,肯定要比軟件速度要快,但是多加了對(duì)應(yīng)的硬件部分,所以成本相對(duì)要高些。如果系統(tǒng)對(duì)于性能要求不是很高,那么可以采用軟件實(shí)現(xiàn)這類(lèi)ECC算法,但是由于增加了數(shù)據(jù)讀取和寫(xiě)入前后要做的數(shù)據(jù)錯(cuò)誤檢測(cè)和糾錯(cuò),所以性能相對(duì)要降低一些,即Nand Flash的讀取和寫(xiě)入速度相對(duì)會(huì)有所影響。
其中,Linux中的軟件實(shí)現(xiàn)ECC算法,即NAND_ECC_SOFT模式,就是用的對(duì)應(yīng)的海明碼。
而對(duì)于目前常見(jiàn)的MLC的Nand Flash來(lái)說(shuō),由于容量比較大,動(dòng)輒2GB,4GB,8GB等,常用BCH算法。BCH算法,相對(duì)來(lái)說(shuō),算法比較復(fù)雜。
筆者由于水平有限,目前仍未完全搞懂BCH算法的原理。
BCH算法,通常是由對(duì)應(yīng)的Nand Flash的Controller中,包含對(duì)應(yīng)的硬件BCH ECC模塊,實(shí)現(xiàn)了BCH算法,而作為軟件方面,需要在讀取數(shù)據(jù)后,寫(xiě)入數(shù)據(jù)之前,分別操作對(duì)應(yīng)BCH相關(guān)的寄存器,設(shè)置成BCH模式,然后讀取對(duì)應(yīng)的BCH狀態(tài)寄存器,得知是否有錯(cuò)誤,和生成的BCH校驗(yàn)碼,用于寫(xiě)入。
其具體代碼是如何操作這些寄存器的,由于是和具體的硬件,具體的nand flash的controller不同而不同,無(wú)法用同一的代碼。如果你是nand flash驅(qū)動(dòng)開(kāi)發(fā)者,自然會(huì)得到對(duì)應(yīng)的起nand flash的controller部分的datasheet,按照手冊(cè)說(shuō)明,去操作即可。
不過(guò),額外說(shuō)明一下的是,關(guān)于BCH算法,往往是要從專(zhuān)門(mén)的做軟件算法的廠(chǎng)家購(gòu)買(mǎi)的,但是Micron之前在網(wǎng)上放出一個(gè)免費(fèi)版本的BCH算法。
位反轉(zhuǎn)
Nand Flash的位反轉(zhuǎn)現(xiàn)象,主要是由以下一些原因/效應(yīng)所導(dǎo)致:
漂移效應(yīng)指的是,Nand Flash中cell的電壓值,慢慢地變了,變的和原始值不一樣了。
此現(xiàn)象有時(shí)候也叫做,過(guò)度編程效應(yīng)(over-program effect)。
對(duì)于某個(gè)頁(yè)面的編程操作,即寫(xiě)操作,引起非相關(guān)的其他的頁(yè)面的某個(gè)位跳變了。
此效應(yīng)是,對(duì)一個(gè)頁(yè)進(jìn)行數(shù)據(jù)讀取操作,卻使得對(duì)應(yīng)的某個(gè)位的數(shù)據(jù),產(chǎn)生了永久性的變化,即Nand Flash上的該位的值變了。
對(duì)應(yīng)位反轉(zhuǎn)的類(lèi)型,Nand Flash位反轉(zhuǎn)的類(lèi)型和解決辦法,有兩種:
以上兩種類(lèi)型的位反轉(zhuǎn),其實(shí)對(duì)于從Nand Flash讀取出來(lái)的數(shù)據(jù)來(lái)說(shuō),解決其中的錯(cuò)誤的位的方法,都是一樣的,即通過(guò)一定的校驗(yàn)算法,常稱(chēng)為ECC,去檢測(cè)出來(lái),或檢測(cè)并糾正錯(cuò)誤。
如果只是單獨(dú)檢測(cè)錯(cuò)誤,那么如果發(fā)現(xiàn)數(shù)據(jù)有誤,那么再重新讀取一次即可。
實(shí)際中更多的做法是,ECC校驗(yàn)發(fā)現(xiàn)有錯(cuò)誤,會(huì)有對(duì)應(yīng)的算法去找出哪位錯(cuò)誤并且糾正過(guò)來(lái)。
其中對(duì)錯(cuò)誤的檢測(cè)和糾正,具體的實(shí)現(xiàn)方式,有軟件算法,也有硬件實(shí)現(xiàn),即硬件Nand Flash的控制器controller本身包含對(duì)應(yīng)的硬件模塊以實(shí)現(xiàn)數(shù)據(jù)的校驗(yàn)和糾錯(cuò)的。
Nand Flash引腳功能的中文說(shuō)明
| I/O0 ~ I/O7 | 用于輸入地址/數(shù)據(jù)/命令,輸出數(shù)據(jù) |
| CLE | Command Latch Enable,命令鎖存使能,在輸入命令之前,要先在模式寄存器中,設(shè)置CLE使能 |
| ALE | Address Latch Enable,地址鎖存使能,在輸入地址之前,要先在模式寄存器中,設(shè)置ALE使能 |
| CE# | Chip Enable,芯片使能,在操作Nand Flash之前,要先選中此芯片,才能操作 |
| RE# | Read Enable,讀使能,在讀取數(shù)據(jù)之前,要先使CE#有效。 |
| WE# | Write Enable,寫(xiě)使能, 在寫(xiě)取數(shù)據(jù)之前,要先使WE#有效 |
| WP# | Write Protect,寫(xiě)保護(hù) |
| R/B# | Ready/Busy Output,就緒/忙,主要用于在發(fā)送完編程/擦除命令后,檢測(cè)這些操作是否完成,忙,表示編程/擦除操作仍在進(jìn)行中,就緒表示操作完成 |
| Vcc | Power,電源 |
| Vss | Ground,接地 |
| N.C | Non-Connection,未定義,未連接 |
| ? | 在數(shù)據(jù)手冊(cè)中,你常會(huì)看到,對(duì)于一個(gè)引腳定義,有些字母上面帶一橫杠的,那是說(shuō)明此引腳/信號(hào)是低電平有效,比如你上面看到的RE頭上有個(gè)橫線(xiàn),就是說(shuō)明,此RE是低電平有效,此外,為了書(shū)寫(xiě)方便,在字母后面加“#”,也是表示低電平有效,比如我上面寫(xiě)的CE#;如果字母頭上啥都沒(méi)有,就是默認(rèn)的高電平有效,比如上面的CLE,就是高電平有效。 |
Nand Flash的一些typical特性
Nand Flash控制器與Nand Flash芯片
我們寫(xiě)驅(qū)動(dòng),是寫(xiě)Nand Flash 控制器的驅(qū)動(dòng),而不是Nand Flash 芯片的驅(qū)動(dòng),因?yàn)楠?dú)立的Nand Flash芯片,一般來(lái)說(shuō),是很少直接拿來(lái)用的,多數(shù)都是硬件上有對(duì)應(yīng)的硬件的Nand Flash的控制器,去操作和控制Nand Flash,包括提供時(shí)鐘信號(hào),提供硬件ECC校驗(yàn)等等功能,我們所寫(xiě)的驅(qū)動(dòng)軟件,是去操作Nand Flash的控制器
然后由控制器去操作Nand Flash芯片,實(shí)現(xiàn)我們所要的功能。
由于Nand Flash讀取和編程操作來(lái)說(shuō),一般最小單位是頁(yè),所以Nand Flash在硬件設(shè)計(jì)時(shí)候,就考慮到這一特性,對(duì)于每一片(Plane),都有一個(gè)對(duì)應(yīng)的區(qū)域?qū)iT(mén)用于存放,將要寫(xiě)入到物理存儲(chǔ)單元中去的或者剛從存儲(chǔ)單元中讀取出來(lái)的,一頁(yè)的數(shù)據(jù),這個(gè)數(shù)據(jù)緩存區(qū),本質(zhì)上就是一個(gè)緩存buffer,但是只是此處datasheet里面把其叫做頁(yè)寄存器page register而已,實(shí)際將其理解為頁(yè)緩存,更貼切原意。
而正是因?yàn)橛行┤瞬涣私獯藘?nèi)部結(jié)構(gòu),才容易產(chǎn)生之前遇到的某人的誤解,以為內(nèi)存里面的數(shù)據(jù),通過(guò)Nand Flash的FIFO,寫(xiě)入到Nand Flash里面去,就以為立刻實(shí)現(xiàn)了實(shí)際數(shù)據(jù)寫(xiě)入到物理存儲(chǔ)單元中了,而實(shí)際上只是寫(xiě)到了這個(gè)頁(yè)緩存中,只有當(dāng)你再發(fā)送了對(duì)應(yīng)的編程第二階段的確認(rèn)命令,即0x10,之后,實(shí)際的編程動(dòng)作才開(kāi)始,才開(kāi)始把頁(yè)緩存中的數(shù)據(jù),一點(diǎn)點(diǎn)寫(xiě)到物理存儲(chǔ)單元中去。
數(shù)據(jù)的流向如圖
壞塊的標(biāo)記
具體標(biāo)記的地方是,對(duì)于現(xiàn)在常見(jiàn)的頁(yè)大小為2K的Nand Flash,是塊中第一個(gè)頁(yè)的oob起始位置的第1個(gè)字節(jié)(舊的小頁(yè)面,pagesize是512B甚至256B的Nand Flash,壞塊標(biāo)記是第6個(gè)字節(jié)),如果不是0xFF,就說(shuō)明是壞塊。相對(duì)應(yīng)的是,所有正常的塊,好的塊,里面所有數(shù)據(jù)都是0xFF的。
對(duì)于壞塊的標(biāo)記,本質(zhì)上,也只是對(duì)應(yīng)的flash上的某些字節(jié)的數(shù)據(jù)是非0xFF而已,所以,只要是數(shù)據(jù),就是可以讀取和寫(xiě)入的。也就意味著,可以寫(xiě)入其他值,也就把這個(gè)壞塊標(biāo)記信息破壞了。對(duì)于出廠(chǎng)時(shí)的壞塊,一般是不建議將標(biāo)記好的信息擦除掉的。
uboot中有個(gè)命令是
nand scrub就可以將塊中所有的內(nèi)容都擦除了,包括壞塊標(biāo)記,不論是出廠(chǎng)時(shí)的,還是后來(lái)使用過(guò)程中出現(xiàn)而新標(biāo)記的。
nand erase只擦除好的塊,對(duì)于已經(jīng)標(biāo)記壞塊的塊,不要輕易擦除掉,否則就很難區(qū)分哪些是出廠(chǎng)時(shí)就壞的,哪些是后來(lái)使用過(guò)程中用壞的了。
NAND 壞塊管理方法分類(lèi)
目前,NAND 壞塊管理方法可分為如下幾類(lèi):
- 基于 FTL 芯片的壞塊管理
它使用一個(gè)額外的 FTL (Flash Translation Layer)芯片對(duì) NAND 進(jìn)行管理,對(duì)外部屏蔽了壞塊信息,U 盤(pán)、SD 卡、MMC 卡以及固態(tài)硬盤(pán)都使用這種管理方法。這種方式簡(jiǎn)化了 NAND 操作,但也使壞塊信息對(duì)外部而言不可見(jiàn),如果系統(tǒng)中出現(xiàn)了可能和壞塊相關(guān)的問(wèn)題,定位和調(diào)試變得困難,另外,FTL 芯片也需要額外的硬件成本。
- 基于NAND 文件系統(tǒng)的壞塊管理
JFFS2、 YAFFS2、 FlashFx 這些專(zhuān)門(mén)針對(duì) NAND 的文件系統(tǒng)可以對(duì)壞塊進(jìn)行管理。
- NAND 管理中間件
有一些中間件(Middleware)專(zhuān)門(mén)用于 NAND 管理,比如 UBI。
- 輕量級(jí) NAND 壞塊管理
對(duì) NAND 進(jìn)行管理的硬件或軟件模塊,不僅提供壞塊管理,同時(shí)也支持對(duì) NAND 的擦寫(xiě)操作進(jìn)行負(fù)載平均。而輕量級(jí)的壞塊管理只專(zhuān)注于壞塊,并不提供擦寫(xiě)負(fù)載平均的支持,而且,它也不依賴(lài)于任何第三方的庫(kù)。因此,輕量級(jí)的壞塊管理方式降低了系統(tǒng)的復(fù)雜度,而且免去了加載文件系統(tǒng)或初始化中間件的時(shí)間,在嵌入式系統(tǒng)中有著廣泛的應(yīng)用。
圖 1 展示了幾種典型的嵌入式系統(tǒng)中 NAND 內(nèi)部的內(nèi)容布局。如果需要頻繁地對(duì) NAND 寫(xiě)入各種數(shù)據(jù),最好使用 NAND 文件系統(tǒng)或者 NAND 管理中間件對(duì)需要寫(xiě)入的區(qū)域進(jìn)行管理。而那些很少需要更新的區(qū)域,比如 bootloader、VPD 和 Kernel,只需進(jìn)行輕量級(jí)的壞塊管理,不需要進(jìn)行負(fù)載平均。很多的嵌入式系統(tǒng)中,需要寫(xiě)入 NAND 的數(shù)據(jù)量很少,頻度也較低,比如路由器、打印機(jī)、PLC 等,這些系統(tǒng)完全可以?xún)H使用輕量級(jí)的壞塊管理方式。
典型嵌入式系統(tǒng)的 Nand Memory MaP
Uboot 的輕量級(jí)壞塊管理方法
NAND 壞塊管理都是基于壞塊表(BBT)的,通過(guò)這張表來(lái)標(biāo)識(shí)系統(tǒng)中的所有壞塊。所以,不同的管理方法之間的差異可以通過(guò)以下幾個(gè)問(wèn)題來(lái)找到答案。
- 如何初始化和讀取壞塊表?
- 產(chǎn)生新的壞塊時(shí),如何標(biāo)記并更新壞塊表?
- 如何保存壞塊表?是否有保存時(shí)斷電保護(hù)機(jī)制?
- 對(duì) NAND 寫(xiě)入數(shù)據(jù)時(shí),如果當(dāng)前塊是壞塊,如何找到可替換的好塊?
Uboot 是目前使用最為廣泛的 bootloader,它提供了兩種輕量級(jí)壞塊管理方法,可稱(chēng)之為基本型和改進(jìn)型。通過(guò)下表,我們可以看到兩者的差異。
?Uboot 的兩種壞塊管理方法對(duì)比
| 初始化、讀取 BBT | 系統(tǒng)每次初始化時(shí),掃描整個(gè) NAND,讀取所有塊的出廠(chǎng)壞塊標(biāo)志,建立 BBT,占用較多啟動(dòng)時(shí)間。 | 系統(tǒng)第一次初始化時(shí),掃描整清單 1. BBM 頭信個(gè) NAND 建立 BBT。之后每次初始化時(shí),掃描 BBT 所在區(qū)域,如果發(fā)現(xiàn)當(dāng)前塊的簽名和壞塊表的簽名(一個(gè)特定的字符串)相符,就讀取當(dāng)前塊的數(shù)據(jù)作為 BBT。 |
| 更新 BBT | 擦寫(xiě)操作產(chǎn)生新的壞塊時(shí),更新內(nèi)存中的 BBT,同時(shí)將壞塊的出廠(chǎng)壞塊標(biāo)記從 0xFF 改為 0x00。 擦寫(xiě)出錯(cuò)后仍然對(duì)壞塊進(jìn)行操作—更改出廠(chǎng)壞塊標(biāo)記,存在安全風(fēng)險(xiǎn)。而且,也無(wú)法區(qū)分哪些是出廠(chǎng)壞塊,哪些是使用過(guò)程中產(chǎn)生的壞塊。 | 擦寫(xiě)操作產(chǎn)生新的壞塊時(shí),更新內(nèi)存中的 BBT,同時(shí)將更新后的 BBT 立刻寫(xiě)入 NAND 或其他 NVRAM 中。 |
| 保存 BBT | 不保存 | 在 NAND 或其他 NVRAM 中保存一份,無(wú)掉電保護(hù)機(jī)制。 |
| 壞塊替換方法 | 如果當(dāng)前塊是壞塊,將數(shù)據(jù)寫(xiě)入下一個(gè)塊。 | 如果當(dāng)前塊是壞塊,將數(shù)據(jù)寫(xiě)入下一個(gè)塊。 |
雖然 uboot 的改進(jìn)型壞塊管理方法的做了一些改進(jìn),但它仍然有三個(gè)主要的缺點(diǎn)。
改進(jìn)的輕量級(jí)壞塊管理方法
針對(duì)現(xiàn)有管理方法的缺陷,本文提出了一種更加安全高效的管理方法,將從以下三個(gè)方面闡述其實(shí)現(xiàn)原理。
共用好塊池機(jī)制
首先,使用一個(gè)統(tǒng)一的備用好塊池,為所有存放在 NAND 中的模塊提供可替換的好塊。這樣,就不需要在每個(gè)模塊后面放置一個(gè)保留區(qū),提高了 NAND 的空間利用率。
共用好塊池示意圖
為了實(shí)現(xiàn)共用好塊池,需要建立一個(gè)從壞塊到好塊的映射,所以,除了 BBT 之外,還需定義一個(gè)替換表(SBT)。這樣一來(lái),當(dāng)讀第 i 個(gè)塊的數(shù)據(jù)時(shí),如果發(fā)現(xiàn) BBT 中記錄該塊為壞塊,就去 SBT 中查詢(xún)其替換塊;如果寫(xiě)第 i 個(gè)塊出錯(cuò),需要在 BBT 中標(biāo)記該塊為壞塊,同時(shí)從好塊池中獲取一個(gè)新的好塊,假設(shè)其序號(hào)為 j,然后將此好塊的序號(hào) j 寫(xiě)入 SBT 中的第 i 個(gè)字節(jié),而且 SBT 的第 j 個(gè)字節(jié)寫(xiě)序號(hào) i。SBT 中的這種雙向映射可確保數(shù)據(jù)的可靠性。此外,好塊池中的塊也有可能成為壞塊,如果掃描時(shí)發(fā)現(xiàn)是壞塊,則將 SBT 中的對(duì)應(yīng)位置標(biāo)記為 0x00,如果是在寫(xiě)的過(guò)程中出錯(cuò),則除了在 SBT 對(duì)應(yīng)位置標(biāo)記 0x00 之外,還要更新雙向映射數(shù)據(jù)。
?BBT/SBT 映射示意圖
安全的 BBT/SBT 數(shù)據(jù)校驗(yàn)機(jī)制
傳統(tǒng)方法僅檢查 BBT 所在塊的簽名,將讀到的前幾個(gè)字節(jié)和一個(gè)特征字符串進(jìn)行比較,如果一致,就認(rèn)為當(dāng)前塊的數(shù)據(jù)為 BBT,然后讀取接下來(lái)的 BBT 數(shù)據(jù),但并不對(duì) BBT 的數(shù)據(jù)做校驗(yàn)。如果 BBT 保存在 NAND 中,數(shù)據(jù)的有效性是可以得到驗(yàn)證的,因?yàn)?NAND 控制器或驅(qū)動(dòng)一般都會(huì)對(duì)數(shù)據(jù)做 ECC 校驗(yàn)。但是,大多數(shù)控制器使用的 ECC 算法也僅僅能糾正一個(gè) bit、發(fā)現(xiàn) 2 兩個(gè) bit 的錯(cuò)誤。如果 BBT 保存在其他的沒(méi)有 ECC 校驗(yàn)機(jī)制的存儲(chǔ)體中,比如 NOR Flash,沒(méi)有對(duì) BBT 的數(shù)據(jù)進(jìn)行校驗(yàn)顯然是不安全的。
為了更加可靠和靈活地驗(yàn)證 BBT/SBT 數(shù)據(jù),定義下面這個(gè)結(jié)構(gòu)體來(lái)描述 BBM 信息。
BBM 頭信息
typedef struct { UINT8 acSignature[4];/* BBM 簽名 */ UINT32 ulBBToffset;/* BBT 偏移 */ UINT32 ulSBToffset;/* SBT 偏移 */ UINT16 usBlockNum;/* BBM 管理的 block 數(shù)目 */ UINT16 usSBTstart;/* SBT 所在位置的起始 block 序號(hào) */ UINT16 usSBtop;/* SBT top block */ UINT16 usSBnum;/* SBT number */ UINT32 ulBBTcrc;/* BBT 數(shù)據(jù) CRC 校驗(yàn)碼 */ UINT32 ulSBTcrc;/* SBT 數(shù)據(jù) CRC 校驗(yàn)碼 */ UINT32 ulHeadcrc;/* BBM 頭信息 CRC 校驗(yàn)碼 */ } BBM_HEADBBT/SBT 的保存形式
使用三重 CRC 校驗(yàn)機(jī)制,無(wú)論 BBT 保存在哪種存儲(chǔ)體中,都可以更加嚴(yán)格地驗(yàn)證數(shù)據(jù)的有效性。
安全的掉電保存機(jī)制
傳統(tǒng)的方法僅保存一份 BBT 數(shù)據(jù),如果在寫(xiě) BBT 時(shí)系統(tǒng)掉電,則 BBT 丟失,系統(tǒng)將可能無(wú)法正常啟動(dòng)或工作。為安全起見(jiàn),本文所述方法將同時(shí)保留三個(gè)備份,如果在寫(xiě)某個(gè)備份時(shí)掉電,則還有兩個(gè)完好的備份。最壞的情況是,如果在寫(xiě)第一個(gè)備份時(shí)掉電,則當(dāng)前最新的一個(gè)壞塊信息丟失。
讀取壞塊表時(shí),順序讀取三個(gè)備份,如果發(fā)現(xiàn)三個(gè)備份的數(shù)據(jù)不一致,用記錄的壞塊數(shù)最多的備份為當(dāng)前的有效備份,同時(shí)立刻更新另外兩備份。
總結(jié)
本文介紹了NandFlash基礎(chǔ)知識(shí)和幾類(lèi) NAND 壞塊管理方法,指出了 uboot 的輕量級(jí)管理方法的缺陷,提出了一種改進(jìn)的方法,提高了 NAND 的利用率及壞塊管理的安全性,可對(duì)嵌入式開(kāi)發(fā)起到有很好的借鑒作用。
轉(zhuǎn)自:?http://blog.csdn.net/luopingfeng/article/details/23621229?utm_source=tuicool&utm_medium=referral
頂總結(jié)
以上是生活随笔為你收集整理的Nand Flash基础知识与坏块管理机制的研究的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 数据转移-从MySQL到Hive
- 下一篇: SpringCloud Ribbon实战