一. 閃存
我們常說的閃存其實(shí)只是一個(gè)籠統(tǒng)的稱呼,準(zhǔn)確地說它是非易失隨機(jī)訪問存儲(chǔ)器(NVRAM)的俗稱,特點(diǎn)是斷電后數(shù)據(jù)不消失,因此可以作為外部存儲(chǔ)器使用。而所謂的內(nèi)存是揮發(fā)性存儲(chǔ)器,分為DRAM和SRAM兩大類,其中常說的內(nèi)存主要指DRAM,也就是我們熟悉的DDR、DDR2、SDR、EDO等等。閃存也有不同類型,其中主要分為NOR型和NAND型兩大類。
閃存的分類
NOR型與NAND型閃存的區(qū)別很大,打個(gè)比方說,NOR型閃存更像內(nèi)存,有獨(dú)立的地址線和數(shù)據(jù)線,但價(jià)格比較貴,容量比較?。欢鳱AND型更像硬盤,地址線和數(shù)據(jù)線是共用的I/O線,類似硬盤的所有信息都通過一條硬盤線傳送一般,而且NAND型與NOR型閃存相比,成本要低一些,而容量大得多。因此,NOR型閃存比較適合頻繁隨機(jī)讀寫的場合,通常用于存儲(chǔ)程序代碼并直接在閃存內(nèi)運(yùn)行,手機(jī)就是使用NOR型閃存的大戶,所以手機(jī)的“內(nèi)存”容量通常不大;NAND型閃存主要用來存儲(chǔ)資料,我們常用的閃存產(chǎn)品,如閃存盤、數(shù)碼存儲(chǔ)卡都是用NAND型閃存。
這里我們還需要端正一個(gè)概念,那就是閃存的速度其實(shí)很有限,它本身操作速度、頻率就比內(nèi)存低得多,而且NAND型閃存類似硬盤的操作方式效率也比內(nèi)存的直接訪問方式慢得多。因此,不要以為閃存盤的性能瓶頸是在接口,甚至想當(dāng)然地認(rèn)為閃存盤采用USB2.0接口之后會(huì)獲得巨大的性能提升。
前面提到NAND型閃存的操作方式效率低,這和它的架構(gòu)設(shè)計(jì)和接口設(shè)計(jì)有關(guān),它操作起來確實(shí)挺像硬盤(其實(shí)NAND型閃存在設(shè)計(jì)之初確實(shí)考慮了與硬盤的兼容性),它的性能特點(diǎn)也很像硬盤:小數(shù)據(jù)塊操作速度很慢,而大數(shù)據(jù)塊速度就很快,這種差異遠(yuǎn)比其他存儲(chǔ)介質(zhì)大的多。這種性能特點(diǎn)非常值得我們留意。
NAND型閃存的技術(shù)特點(diǎn)
內(nèi)存和NOR型閃存的基本存儲(chǔ)單元是bit,用戶可以隨機(jī)訪問任何一個(gè)bit的信息。而NAND型閃存的基本存儲(chǔ)單元是頁(Page)(可以看到,NAND型閃存的頁就類似硬盤的扇區(qū),硬盤的一個(gè)扇區(qū)也為512字節(jié))。每一頁的有效容量是512字節(jié)的倍數(shù)。所謂的有效容量是指用于數(shù)據(jù)存儲(chǔ)的部分,實(shí)際上還要加上16字節(jié)的校驗(yàn)信息,因此我們可以在閃存廠商的技術(shù)資料當(dāng)中看到“(512+16)Byte”的表示方式。目前2Gb以下容量的NAND型閃存絕大多數(shù)是(512+16)字節(jié)的頁面容量,2Gb以上容量的NAND型閃存則將頁容量擴(kuò)大到(2048+64)字節(jié)。
NAND型閃存以塊為單位進(jìn)行擦除操作。閃存的寫入操作必須在空白區(qū)域進(jìn)行,如果目標(biāo)區(qū)域已經(jīng)有數(shù)據(jù),必須先擦除后寫入,因此擦除操作是閃存的基本操作。一般每個(gè)塊包含32個(gè)512字節(jié)的頁,容量16KB;而大容量閃存采用2KB頁時(shí),則每個(gè)塊包含64個(gè)頁,容量128KB。
每顆NAND型閃存的I/O接口一般是8條,每條數(shù)據(jù)線每次傳輸(512+16)bit信息,8條就是(512+16)×8bit,也就是前面說的512字節(jié)。但較大容量的NAND型閃存也越來越多地采用16條I/O線的設(shè)計(jì),如三星編號K9K1G16U0A的芯片就是64M×16bit的NAND型閃存,容量1Gb,基本數(shù)據(jù)單位是(256+??×16bit,還是512字節(jié)。
尋址時(shí),NAND型閃存通過8條I/O接口數(shù)據(jù)線傳輸?shù)刂沸畔堪鼈魉?位地址信息。由于閃存芯片容量比較大,一組8位地址只夠?qū)ぶ?56個(gè)頁,顯然是不夠的,因此通常一次地址傳送需要分若干組,占用若干個(gè)時(shí)鐘周期。NAND的地址信息包括列地址(頁面中的起始操作地址)、塊地址和相應(yīng)的頁面地址,傳送時(shí)分別分組,至少需要三次,占用三個(gè)周期。隨著容量的增大,地址信息會(huì)更多,需要占用更多的時(shí)鐘周期傳輸,因此NAND型閃存的一個(gè)重要特點(diǎn)就是容量越大,尋址時(shí)間越長。而且,由于傳送地址周期比其他存儲(chǔ)介質(zhì)長,因此NAND型閃存比其他存儲(chǔ)介質(zhì)更不適合大量的小容量讀寫請求。
二.MTD
MTD是memory technology Device的縮寫。MTD支持類似于內(nèi)存的存儲(chǔ)器,它是底層硬件和上層軟件之間的橋梁。對底層來說,它無論對nor型或是nandflash都有很好的驅(qū)動(dòng)支持,對上層來說,它抽象出文件系統(tǒng)所需要的接口函數(shù)。同時(shí)由于flash自身的特別之處(既有類似塊設(shè)備的特點(diǎn),又有類似字符設(shè)備的特點(diǎn)),MTD可以把flash同時(shí)為塊設(shè)備和字符設(shè)備。有了MTD,編寫flash的驅(qū)動(dòng)變得十分輕松,因?yàn)樯蠈拥募軜?gòu)都已經(jīng)做好,我們只用看看flash的datasheet,寫最底層的控制時(shí)序即可。?
以下內(nèi)容為翻譯自mtd官方網(wǎng)站http://www.linux-mtd.infradead.org/archive/index.html
mtd致力于為存儲(chǔ)器,尤其是flash,設(shè)計(jì)一個(gè)通用的linux下的子系統(tǒng)。
設(shè)計(jì)這個(gè)系統(tǒng)的目標(biāo)在于,通過這個(gè)系統(tǒng)所提供的硬件驅(qū)動(dòng)和上層系統(tǒng)之間的接口,我們可以方便的為新的硬件編寫驅(qū)動(dòng)。
對于底層的硬件驅(qū)動(dòng)來說,它們所以提供是讀,寫,擦除的流程。而文件的存儲(chǔ)形式是和他們無關(guān)的(如FTL,FFS2等等),用恰當(dāng)?shù)男问酱鎯?chǔ)用戶的數(shù)據(jù)那時(shí)上層系統(tǒng)關(guān)注的事情。
MTD的用戶模塊
MTD為用戶提供五種可以直接在用戶空間使用的模塊
字符設(shè)備
塊設(shè)備
flash轉(zhuǎn)換層
nandflash轉(zhuǎn)換層
JFFS2文件系統(tǒng)
三.yaffs2文件系統(tǒng)
針對于flash的文件系統(tǒng)有很多,據(jù)我了解有jffs(1,2,3),yaffs(1,2)。還有商業(yè)的三星開發(fā)的RFS(健壯文件系統(tǒng)),專門針對三星自己的nand和onenand,從底層驅(qū)動(dòng)到上層文件系統(tǒng)一條龍服務(wù),而且號稱和fat格式100%兼容。當(dāng)時(shí)看得我直流口水,心里把三星恨的咬牙切齒。 下面主要介紹一下開源的yaffs文件系統(tǒng)。
Yaffs(Yet Another Flash File System)文件系統(tǒng)是專門針對NAND閃存設(shè)計(jì)的嵌入式文件系統(tǒng),目前有YAFFS和YAFFS2兩個(gè)版本,一般說來,YAFFS對512byte/page以下都有很好的支持,而更大的頁就需要YAFFS2了,如2K/page。
Yaffs文件系統(tǒng)有些類似于JFFS/JFFS2文件系統(tǒng),與之不同的是JFFS1/2文件系統(tǒng)最初是針對NOR FLASH的應(yīng)用場合設(shè)計(jì)的,而NOR FLASH和NAND FLASH本質(zhì)上有較大的區(qū)別,所以盡管JFFS1/2 文件系統(tǒng)也能應(yīng)用于NAND FLASH,但由于它在內(nèi)存占用和啟動(dòng)時(shí)間方面針對NOR的特性做了一些取舍,所以對NAND來說通常并不是最優(yōu)的方案。
Yaffs對文件系統(tǒng)上的所有內(nèi)容(比如正常文件,目錄,鏈接,設(shè)備文件等等)都統(tǒng)一當(dāng)作文件來處理,每個(gè)文件都有一個(gè)頁面專門存放文件頭,文件頭保存了文件的模式、所有者id、組id、長度、文件名、Parent Object ID等信息。因?yàn)樾枰谝豁搩?nèi)放下這些內(nèi)容,所以對文件名的長度,符號鏈接對象的路徑名等長度都有限制。
前面說到對于NAND FLASH上的每一頁數(shù)據(jù),都有額外的空間用來存儲(chǔ)附加信息,通常NAND驅(qū)動(dòng)只使用了這些空間的一部分,YAFFS正是利用了這部分空間中剩余的部分來存儲(chǔ)文件系統(tǒng)相關(guān)的內(nèi)容。同時(shí)由于支持的page變大,YAFFS2使用更多的spare space來存儲(chǔ)這些信息。在結(jié)構(gòu)上YAFFS和YAFFS2有一定的不同,具體結(jié)構(gòu)可以去看一看這篇文檔http://www.aleph1.co.uk/node/38
那么這個(gè)文件系統(tǒng)是如何運(yùn)作起來呢。
操作文件系統(tǒng)的第一步自然是取得SuperBlock了,Yaffs文件系統(tǒng)本身在NAND Flash上并不存在所謂的SuperBlock塊,完全是在文件系統(tǒng)mount的過程中由read_super函數(shù)填充的,不過有意思的一點(diǎn)是,由于物理上沒有存儲(chǔ)superblock塊,所以NAND Flash上的yaffs文件系統(tǒng)本身沒有存儲(chǔ)filesystem的魔數(shù)(MagicNum),在內(nèi)存中superblock里的s_magic參數(shù)也是直接賦值的,所以存儲(chǔ)在NAND FLASH上的任何文件系統(tǒng)都能被當(dāng)作yaffs文件系統(tǒng)mount上來,只是數(shù)據(jù)都會(huì)被當(dāng)作錯(cuò)誤數(shù)據(jù)放在lost+found目錄中,不知道這算不算yaffs文件系統(tǒng)的一個(gè)bug。
通常一個(gè)具體的文件系統(tǒng)在VFS的Super_block結(jié)構(gòu)中除了通用的數(shù)據(jù)外,還有自己專用的數(shù)據(jù),Yaffs文件系統(tǒng)的專用數(shù)據(jù)是一個(gè)yaffs_DeviceStruct結(jié)構(gòu),主要用來存儲(chǔ)一些相關(guān)軟硬件配置信息,相關(guān)函數(shù)指針和統(tǒng)計(jì)信息等。
在mount過程執(zhí)行read_super的過程中,Yaffs文件系統(tǒng)還需要將文件系統(tǒng)的目錄結(jié)構(gòu)在內(nèi)存中建立起來。由于沒有super塊,所以需要掃描Yaffs分區(qū),根據(jù)從OOB中讀取出的yaffs_tags信息判斷出是文件頭page還是數(shù)據(jù)page。再根據(jù)文件頭page中的內(nèi)容以及數(shù)據(jù)page中的ObjectID/ChunkID/serial Number等信息在內(nèi)存中為每個(gè)文件(Object)建立一個(gè)對應(yīng)的yaffs_object對象。
在yaffs_object結(jié)構(gòu)中,主要包含了:
??? 如修改時(shí)間,用戶ID,組ID等文件屬性;
??? 用作yaffs文件系統(tǒng)維護(hù)用的各種標(biāo)記位如臟(dirty)標(biāo)記,刪除標(biāo)記等等;
??? 用作組織結(jié)構(gòu)的,如指向父目錄的Parent指針,指向同級目錄中其他對象鏈表的???? siblings雙向鏈表頭結(jié)構(gòu)
此外根據(jù)Object類型的不同(目錄,文件,鏈接),對應(yīng)于某一具體類型的Object,在Yaffs_object中還有其各自專有的數(shù)據(jù)內(nèi)容
?????? 普通文件:文件尺寸,用于快速查找文件數(shù)據(jù)塊的yaffs_Tnode 樹的指針等
?????? 目錄:目錄項(xiàng)內(nèi)容雙向鏈表頭(children)
?????? 鏈接:softlink的alias,hardlink對應(yīng)的ObjectID
除了對應(yīng)于存儲(chǔ)在NAND FLASH上的object而建立起來的yaffs_object以外,在read_super執(zhí)行過程中還會(huì)建立一些虛擬對象(Fake Object),這些Fake Object在NAND FLASH上沒有對應(yīng)的物理實(shí)體,比如在建立文件目錄結(jié)構(gòu)的最初,yaffs會(huì)建立四個(gè)虛擬目錄(Fake Directory):rootDir, unlinkedDir, deleteDir, lostNfoundDir分別用作根目錄,unlinked對象掛接的目錄,delete對象掛接的目錄,無效或零時(shí)數(shù)據(jù)塊掛接的目錄。
通過創(chuàng)建這些yaffs_object,yaffs文件系統(tǒng)就能夠?qū)⒋鎯?chǔ)在NAND FLASH上數(shù)據(jù)系統(tǒng)的組織起來,在內(nèi)存中維護(hù)一個(gè)完整的文件系統(tǒng)結(jié)構(gòu)
另外,我在看YAFFS2的源代碼的時(shí)候發(fā)現(xiàn),YAFFS2再mount和umount和YAFFS有所區(qū)別,增加一個(gè)checkpoint機(jī)制,每次在umount的時(shí)候,YAFFS2會(huì)開辟專門幾個(gè)block用來存取一些信息,等待下次mount的時(shí)候就不需要掃描整個(gè)flash,而只有找出這幾個(gè)塊就可以了,這樣可以大大加速mount的時(shí)間。不過仔細(xì)的原理我也沒有研究過。
?
評論
查看更多