李中,周加誼,曹睿
(中國兵器裝備集團自動化研究所有限公司,四川 綿陽 621000)
在大數據時代的今天,數據傳輸量越來越大,數據傳輸速度要求越來越高,機械硬盤的傳輸速度已經不能滿足現狀,固態硬盤迎來了發展機會,使用場景越來越多。固態硬盤存儲介質NAND Flash 與傳統磁性存儲介質相比,具有低功耗、抗震動、無噪聲的特點。但是NAND Flash 存在擦除壽命限制,當擦除次數超過閾值時,NAND Flash 變得不可靠;MLC NAND Flash 的Block 最大擦除次數僅3 000 次,TLCNAND Flash Block 擦除壽命只有1 000 次;同時由于制造工藝和使用環境等因素,NAND Flash 出廠時就存在壞塊,隨著使用過程中擦除Block 次數的增加,產生了新的壞塊,導致壞塊不斷增加。這些壞塊不能可靠存放數據,因此在使用時需要先對壞塊進行管理。
從固態硬盤結構圖可知,固態硬盤(solid state disk)[1]由控制單元(主控芯片)和存儲單元(NAND Flash)組成,主控芯片和NAND Flash 之間一般采用多通道(channel)連接,數據最終存放在NAND Flash顆粒中。固態硬盤存儲數據,在NAND Flash 顆粒上體現為電荷的存儲。固態硬盤對數據的讀、寫、擦操作,其最終在NAND Flash 顆粒上表現為顆粒單元的充電放電;而顆粒單元不斷的充電放電會導致顆粒單元絕緣層被擊穿,不能可靠存儲電荷,從而出現壞塊。壞塊不能可靠地存儲數據,需要進行管理。為避免數據存儲在壞塊中,該文提出NAND Flash 壞塊管理算法,通過在固態硬盤主控芯片內部RAM 中分配空間,采用1 位信息與一個Block 對應(“0”表示好塊,“1”表示壞塊),建立壞塊表標記所有Block 狀態的方法,對固態硬盤的高速傳輸、多通道傳輸進行了改進和優化,可以避免在讀寫過程中操作到壞塊。固態硬盤結構圖如圖1 所示。

圖1 固態硬盤結構圖
圖2 所示是鎂光一款NAND Flash 顆粒結構圖,以此為基礎簡單介紹NAND Flash,僅用作參考,不同型號的NAND Flash 顆粒存在差異[2]。

圖2 NAND Flash 顆粒結構圖
由圖2 NAND Flash 結構圖可知,NAND Flash 由Logic Unit(LUN)、plane、Block、page 組成。page:對于固態硬盤,page 是讀和寫操作的最小單位,一個page 大小等于4 K 加224 byte;224 byte 數據空間又名spare data 區域,用于存放ECC 校驗數據和固態硬盤算法信息,同時標記NAND Flash 的出廠壞塊信息和使用過程中該Block 的屬性;Block:NAND Flash擦除是以Block 為單位,一個Block 中存放著256 個page;固態硬盤軟件算法采用邏輯Block 和物理Block 映射,能夠解決NAND Flash 讀寫單位和擦除單位不對稱的問題,同時也能提高固態硬盤的讀寫性能。plane:是將LUN 中所有Block 分為兩個部分,1 plane 有2 048 個Block,偶數部分為plane0,奇數部分為plane1;plane 通過“乒乓操作”原理,提高NAND Flash 接口的讀寫性能;LUN:是Logic Unit NAND Flash 的一個邏輯單元,一個LUN 有4 096 個Block,一個NAND Flash 有多個LUN。
固態硬盤對讀寫速度的要求,使得固態硬盤主控芯片都支持多通道(Channel)操作,可以提高讀寫性能。但是壞塊的出現會影響固態硬盤的讀寫性能和數據的一致性。多通道操作實際上是操作RaidBlock,提高接口數據的并發能力。該文提出的固態硬盤壞塊管理方法,主要針對多通道、多NAND Flash 的壞塊管理,致力于減少壞塊出現對讀寫性能的影響和保護硬盤數據的一致性。該文提出的壞塊管理方法主要包括四個部分:出廠壞塊的統計、壞塊表的建立和RaidBlock 的建立、RaidBlock 更新和壞塊表的更新。
NAND Flash 的壞塊包括出廠壞塊和使用過程中新增的壞塊。出廠壞塊由NAND Flash 廠商標記。不同的NAND Flash 廠商存放的位置可能存在差異。對于Micron MT29F32G08CBABB 顆粒,是用每個Block 的第一個page spare 區域的第一個byte 來表示該Block 是壞塊還是好塊,00 表示該Block 是壞塊,0xFF 表示該Block 是好塊。對于使用過程中新增壞塊有三個產生源頭:1)編程(program)過程中發生錯誤;2)擦除(erase)過程中發生錯誤;3)讀(read)過程中出現ECC 無法糾正的錯誤[3-5]。
初始化壞塊表的建立是在固態硬盤量產時,通過掃描全盤Block 的方法實現的;初始化壞塊表建立之后,固態硬盤在使用過程中,新增的壞塊采用增量方式,向初始化壞塊表進行添加。固態硬盤完成上電后,壞塊表會讀取到主控芯片內存,當壞塊表更新時,先更新主控芯片內存中的壞塊表,再把內存中的壞塊表備份到NAND Flash 顆粒的固定位置;這種策略可以保證壞塊表的準確性和實時性不受固態硬盤上、下電的影響,不用每次都采用掃描全盤來建立壞塊表。壞塊表建立流程圖如圖3 所示。

圖3 壞塊表建立流程圖
由圖3 壞塊表的建立流程可知,通過掃描固態硬盤所有的Block,讀取每個Block 第一個page 的spare data 區域的第一個byte 的值與0xFF 進行比較;從而確定該Block 是好塊還是壞塊,并建立壞塊表[6-8]。壞塊表以byte 數組形式進行保存,數組的每一個元素表示相鄰的8 個Block,每個Block 塊屬性用一個bit表示,bit 值1 表示該Block 是壞塊,bit 值0 表示該Block 是好塊;這樣一個byte 可以對應8 個Block,采用每個bit 來映射一個Block,可以減小壞塊表的大小,節約存儲資源。
RaidBlock 是由每個通道(channel)、每個CE 的Block 共同組成的邏輯Block 層,是一個抽象的Block[9-10]。由圖4 RaidBlock 與物理Block 映射圖可知,該固態硬盤有兩個通道,每個通道連接的NAND Flash 有4 個CE,每個CE 有8 196 個Block。因此一個RaidBlock 組成元素有{Block(0,0),Block(0,1),Block(0,2),Block(0,3),Block(1,0),Block(1,1),Block(1,2),Block(1,3)},其中Block(0,1)表示通道0的CE 1 的Block,元素0 表示通道,元素1 表示CE。在實際使用時,RaidBlock 表存儲的是不規則的RaidBlock 元素,規則的RaidBlock 元素不作記錄,可以減少RaidBlock 表大小,節約內存空間。同時RaidBlock 命名通常都是以Channel 0 和CE 0 的Block 為基準。如RaidBlock 表中存在如下內容:{3,3,100,3,3,3,3,235},該內容表示RaidBlock 3 中Block3(0,2)和Block3(1,3)的Block 都是壞塊,分別采用各自Block100(0,2)和Block235(1,3)來替換。在固態硬盤向RaidBlock3 讀寫數據時,先查詢RaidBlock 表,再對應RaidBlock 表操作Block100(0,2)和Block235(1,3),然后讀寫數據;RaidBlock 構建的原理是依據NAND Flash 各個通道和各個CE 之間讀寫數據相對獨立互不干擾,同時還能最大程度地提高通道并發能力,提高固態硬盤的讀寫性能,不受壞塊影響。
RaidBlock 的建立是在固態硬盤量產時和壞塊表建立同時完成的[11]。先將所有通道和CE 沒有壞塊的組建成RaidBlock,并統計所有存在壞塊的通道和CE,以數組形式進行保存;找到壞塊最多的通道和CE,確定最多組成RaidBlock 的個數;以通道0 和CE 0 為基準,建立RaidBlock表[12-13],如圖5 RaidBlock結構圖所示。從行上看,有5 個行存在壞塊,分別分布在不同CE 與通道上。從列上看,通道0 與CE 2 上存在最多壞塊,個數為3;通過計算可知,最多形成8 193(8 196-3)個RaidBlock;其中8 191(8 196-5)個RaidBlock 是默認狀態,不需要保存到RaidBlock 表,僅兩個RaidBlock 需要建立RaidBlock 表,表中數據如{3,3,2,3,3,3,3,3}{200,200,895,200,200,200,200,895}。
RaidBlock 的個數會隨著使用過程中壞塊的增加而減少,但是存在一個閾值,當RaidBlock 個數小于這個閾值時,固態硬盤不能正常工作。該閾值一般由固態硬盤容量決定,超出閾值的RaidBlock 可以稱作spare RaidBlock,該類Block主要用于提高固態硬盤垃圾回收(Garbage Collection)和磨損均衡(Wear-Leveling)效率。由圖5 可知,基準線一的RaidBlock閾值是16,表示RaidBlock 總個數不能小于8 180(8 196-16)個,剩余的是spare RaidBlock 和壞塊;基準線二表示該固態硬盤的某個通道和CE 存在最大的壞塊數;基準線二的閾值是3,表示在通道0、CE 2上存在三個壞塊。隨著固態硬盤的使用,壞塊增加基準線二逐漸向基準線一靠擾,當二者重合時,表示該固態硬盤已經不能正常使用。

圖5 RaidBlock結構圖
固態硬盤在使用過程中,新增壞塊可以分為以下三種情況[14-15]:
1)當操作NAND Flash 出現page program 操作失敗時,先把有效數據轉移到spare RaidBlock,然后進行erase RaidBlock,若在erase 操作過程中出現錯誤,找到擦除失敗的Block,記錄好通道數和CE 數,標記為壞塊;若擦除RaidBlock 完成,表示該RaidBlock 不存在壞塊;
2)當操作NAND Flash 出現erase RaidBlock 失敗時,找到擦除失敗的Block,記錄好通道數和CE 數,標記為壞塊;
3)當read 操作出現ECC 無法糾正的錯誤,先把RaidBlock 有效數據轉移到spare RaidBlock,然后進行erase RaidBlock,再進行program 數據并校驗,若操作過程中出現失敗,表示RaidBlock 存在壞塊,再擦除RaidBlock,找到擦除失敗的Block,標記為壞塊;若操作成功,表示該RaidBlock 不存在壞塊
當確定某個Block是壞塊時,先標記壞塊,更新壞塊表;然后確認Block 所在的通道和CE,并確認通道和CE 的壞塊數;如果大于最大通道和CE 的壞塊數,則最大通道和CE 的壞塊數增加1,spare RaidBlock 減少1;如果小于最大通道和CE 的壞塊數,則更新Raid Block 表;最后將更新的表同步到NAND Flash[16]。
該文提出的壞塊處理方法主要針對于主控芯片連接多通道NAND Flash 架構的固態硬盤。依據壞塊表區分壞塊和好塊,達到管理Block 的目的。通過RaidBlock 的操作,可以確保在不操作到壞塊的前提下,滿足固態硬盤數據的并發需求,提高固態硬盤的讀寫效率。壞塊表和RaidBlock 表的相互配合可以到達壞塊管理的基本要求,確保數據的可靠性。