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