ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

从浮栅晶体管到阵列架构:读懂NAND Flash的内部世界

从浮栅晶体管到阵列架构:读懂NAND Flash的内部世界 做了这么多年存储相关的开发和数据恢复我越来越觉得读NAND Flash芯片和读硬盘完全是两码事。硬盘的物理结构是机械的、直观的而NAND是一个纯粹的半导体黑盒只有真正搞懂芯片内部那些存储单元是怎么排布、怎么读写、怎么擦除的你才敢说自己“会玩”NAND。最近重新翻经典书籍《Inside NAND Flash Memories》读到第二章2.1到2.2.1部分正好是把NAND芯片内部宏观架构和阵列组织方式讲清楚的关键章节。这部分的收获不仅仅是搞懂原理更重要的是它能直接解释我们在实际工程里遇到的很多现象为什么块是最小擦除单位、为什么写入之前必须擦除、为什么NOR做不到这么大的密度、为什么用编程器读全片时要先跳过坏块……这章读明白之后很多过去“就这么干”的操作突然就有了理论依据。这篇就把这部分的精髓拆开揉碎结合我自己的实际经验讲清楚NAND Flash从外部引脚到内部存储单元阵列的完整逻辑。1. 从芯片外引脚回到内部NAND的宏观组装方式是理解一切的前提拿到一颗NAND Flash芯片先看引脚就明白了它的外部接口和NOR Flash、和DRAM都不一样地址线和数据线是分时复用的。这意味着芯片内部根本不存在“按字节寻址”的概念数据不是按内存那样一个地址一个字节去访问的。这种接口设计本身就暗示了它的存储阵列一定是分块、分页组织的而不是线性排布的。1.1 芯片、平面、块、页的俄罗斯套娃关系NAND芯片的宏观结构是一个典型的俄罗斯套娃一颗芯片Chip内部包含一个或多个平面Plane每个平面又被划分成成千上万个块Block每个块由若干页Page组成而每个页就是一次读写操作的最小单位。以一颗比较常见的8Gb芯片为例实际内部结构大致是1个Chip里有4个Plane每个Plane有2048个Block每个Block有64个Page每个Page的容量是4KB加上备用区Spare Area通常是128字节或者更多。层级关系可以这样理解Page页读写的最小单位一次Read/Program操作至少操作一个Page。Block块擦除的最小单位一次Erase操作整块一起擦。Plane平面可以并行操作的区域单位支持多平面交错读写。Chip芯片多颗Chip可以封装在一起通过片选信号CE来区分。我在最初接触NAND的时候犯过一个困惑很久的错误我以为“页”就像内存里的“页”一样是一个软件概念。实际上完全不是页是芯片物理结构上真实存在的划分一条字线Word Line上挂着的所有存储单元算下来正好对应一个或几个物理页。所以一次读一个Page本质上是同时检测一条字线上成百上千个存储单元的状态。1.2 为什么“块”才是擦除的最小单位物理划线的结果这个问题值得认真琢磨为什么偏偏是块而不是页成为擦除的最小单位原因出在浮栅晶体管的物理结构上。擦除操作的本质是把电子从浮栅里“拽”出来这个动作需要在整个衬底区域P-well上施加一个很高的电压通常在20V左右。而同一个块内的所有存储单元它们的衬底是连在一起的工艺上根本做不到给同一个块里的不同页单独施加不同的衬底电压。这就好比一整栋楼的供水管道是共用的你没法只给其中一层停水要停就得整栋楼一起停。块就是这栋“楼”页就是“层”物理管线决定了擦除必须整块进行。这个特性带来一个非常实际的工程约束如果你想更新某个页里的数据不能直接覆盖写必须先把整个块擦干净再把原数据和更新数据一起写回去。这就是为什么NAND需要FTLFlash Translation Layer做垃圾回收也是为什么会有写入放大Write Amplification这个概念存在。2. 存储单元的物理本质与电荷的“存”与“漏”宏观排布看完了接下来要钻进最小单元去看也就是2.1节里最核心的存储单元结构。如果只停留在“块和页”的层面你能看懂芯片手册但看不懂为什么NAND会有读干扰、为什么数据会保持不住、为什么TLC比SLC更容易出错。2.1 浮栅晶体管一个藏在氧化层里的“电容”NAND的存储单元本质上是个特殊的MOSFET关键点在于它的栅极和沟道之间多夹了一层导体——浮栅Floating Gate或者在某些先进工艺里是电荷俘获层Charge Trap Layer。这层浮栅和它上下两层的氧化绝缘层构成了一个能够储存电荷的结构。可以把浮栅想象成一个完全密封的桶桶壁是氧化层电子就是储存在桶里的水。写数据时往桶里注入电子代表存储了“0”不注入电子代表存储了“1”。而桶的密封性决定了电子能在里面待多久——这就是数据保持能力Data Retention的物理基础。关键点在于浮栅和衬底之间这层隧道氧化层Tunnel Oxide只有不到10纳米的厚度要在这么薄的绝缘层上实现电子的“注入”和“拉出”靠的是一种叫做Fowler-Nordheim隧穿FN隧穿的量子力学效应。当施加足够高的电压时电子可以直接“穿”过看似绝缘的氧化层进入浮栅或者从浮栅中出来。在我自己的理解里FN隧穿这个机制是理解NAND一切特性的钥匙。它决定了编程和擦除都必须用高电压决定了编程擦除会有次数限制氧化层穿来穿去会损坏也决定了为什么NAND不能无限次擦写。2.2 阈值电压分布一个Cell能存几比特取决于怎么切“档位”存储单元存的是电子但电子“多”和“少”不是靠直接数数来读的。实际读取时是看这个晶体管的阈值电压Vth处于哪个区间。当浮栅里电子很少时晶体管很容易导通阈值电压低当浮栅里电子很多时需要更高的栅极电压才能导通阈值电压就高。所以读操作实际上是在给晶体管加不同的栅极电压看它导没导通据此判断阈值电压范围再映射成数字值。SLCSingle-Level Cell只有两个阈值电压区间要么是“0”要么是“1”最简单的档位。MLCMulti-Level Cell四个区间一个单元存2比特。TLCTriple-Level Cell八个区间一个单元存3比特。QLCQuad-Level Cell十六个区间一个单元存4比特。这里就有一个工程上的残酷现实阈值电压的分布不是一个单点而是一个带状的分布曲线。同一个状态下由于制造工艺偏差、电荷泄漏、读取干扰等因素不同存储单元的阈值电压会有浮动。所以厂商必须在相邻两个状态之间留出“保护间隔”Read Margin。状态越多间隔越窄容错空间越小就需要更复杂的ECC纠错算法。这也是我在做数据恢复时最深的体会SLC的老片子放个十年拿出来读数据大概率还在但QLC的盘放个半年不开机可能已经冒出一堆ECC校正不了的错误块了。这不是玄学就是阈值电压分布被电荷泄漏渐渐抹平的结果。2.3 为什么NAND怕“漏电”数据保持与读干扰的根源电荷泄漏有两条路径一条是纵向的浮栅中的电子穿过隧道氧化层漏到衬底。氧化层在反复编程擦除过程中会积累损伤缺陷越来越多漏电通道就越来越多。这就是P/E Cycle编程擦除循环次数有限的根本原因。SLC一般号称10万次QLC往往只有1000次甚至更低就是因为它对阈值电压漂移的容忍度完全不同。另一条是横向的读操作时同一行字线上其他未被选中的存储单元也会承受一定的偏压。虽然电压不足以让它们发生隧道效应但长时间、高频率的读取相当于对氧化层进行慢性磨损会让电子一点点跑掉。这就是读干扰Read Disturb的物理来源。在我用编程器读整片NAND的时候这种效应体现得非常明显。如果反复读同一个块隔一段时间再读它相邻的块可能会发现相邻块的错误比特数在增加。所以正规做法是完成一次完整镜像之后把芯片放到防静电袋里收好不要在读取台上反复通电更不要为了验证数据反复读同一区域。3. 串与阵列字线、位线如何把千万个Cell“织”成网格单个存储单元理解了接下来最关键的问题是怎样把几千万个存储单元高效地连接起来既保证密度又让读写擦操作能准确定位到某个具体的单元。这正好是2.1后半部分和2.2.1要解决的核心问题——阵列的编织方式。3.1 串结构32/64/96个Cell串联的真正原因NAND阵列的一个标志性结构就是“串”String把几十个存储单元在垂直方向沟道方向上串联起来然后整串的两端分别接上选择管Select Transistor。这跟NOR Flash的结构形成鲜明对比。NOR是每个存储单元都独立连接到位线和地线好处是可以按字节随机读坏处是每个单元都要占用一根金属线单元尺寸做不小。NAND的结构则是让一堆单元共享同一条位线共用同一个衬底区密度能比NOR高好几倍。代价就是无法随机访问任意字节只能按页来读。串结构里的串联方式是这样的同一串上的所有存储单元它们的栅极分别接到不同的字线Word Line。同一串两端的两个选择管分别是串选择管SST接到SSL线和地选择管GST接到GSL线。串的上端连接到位线Bit Line下端连接到公共源极线Common Source Line。当需要读取某一个页时先把这个页所在的那条字线电压设为读电压然后把同一串上其他所有字线电压设为一个“通过电压”Pass Voltage这个电压足够高让这些单元无论存储什么数据都表现为导通。最后真正决定整条串是否导通的就是目标单元的状态了。这里我特别想强调一点我之前一直以为NAND串结构里的“串”是一个很玄乎的事但实际上做个简单计算就知道了。一个64层的3D NAND垂直方向堆叠64层每一层就是一条字线也就是一个page的栅极层。而水平方向上一个块里可能包含几千条串每条串就是一个垂直的孔洞里面填满了电荷俘获层和沟道材料。所以“串”不是抽象概念它就是你在SEM照片里看到的那些密密麻麻的孔。3.2 选择管与共用线的代价一条坏串如何拖累一块选择管是整个阵列能够工作的前提。SST负责连接或断开这串单元与位线的通路GST负责连接或断开这串单元与源极线的通路。编程时只有选中的串让SST打开让电流通过未选中的串则通过关闭SST把位线电压传递到沟道里实现自举抑制后面细说。但共用的结构必然带来一个代价如果一个Block里有一条串出了毛病这整条串上的所有存储单元都废了而因为块是擦除单位这个块的其他串也基本没法单独利用。所以厂商出厂时就要标记坏块控制器则要在逻辑上跳过这些坏块。实际工程中我对这个“拖累”的感受非常具体做数据恢复时经常发现某些块从某个物理页开始错误数一路飙升读出来的数据全是FF或者乱码。这种情况往往不是控制器逻辑问题而是那条串上的某一个存储单元氧化层击穿了导致整条串彻底完蛋。所以遇到一个块里部分页读不出来时千万别一个个页去硬读直接把这个块视为坏块跳过去。省下的时间足够你再做几个扇区的映射分析。3.3 NOR与NAND的架构差异为什么NAND能做的密度NOR做不了顺着阵列结构往下推就能彻底搞清楚NOR和NAND的区别从哪来。先看连接方式NOR每个Cell一端接位线Bit Line另一端接源线Source Line栅极接字线Word Line。相当于每个Cell都能独立寻址类似于内存。NAND多个Cell串联成串只有串的两端接位线和源线Cell在串内部是“手拉手”的。所以NOR可以按字节读取甚至可以直接在上面执行代码XIP这对嵌入式系统很方便。但也是因为这种连接方式NOR的面积利用率很低同样工艺下成本是NAND的数倍容量也做不大。市场上NOR一般到256Mb或512MbNAND轻松到256Gb甚至1Tb根本不是一个量级。再来看编程和擦除方式的区别NOR写入用热电子注入Channel Hot Electron Injection速度慢电流大擦除依然用FN隧穿。NAND编程和擦除都用FN隧穿编程时虽然也是逐页写但电流小、速度快很适合大容量数据存储。我之前接触过一个工程师非要在NOR里存几十MB的日志数据理由是NOR稳、寿命长。结果做出来的产品不仅成本高得离谱擦写速度还慢到让人抓狂。这就是没想清楚“架构决定用途”的最好例子。NOR就是用来存代码的NAND才是用来存数据的。4. 编程、擦除、读取的三条电路路径以及最容易被忽略的细节理解了阵列结构下一步就是把阵列“用起来”。2.2.1节里讲的就是这些操作在物理层面究竟是怎么完成的。这段内容特别适合那些已经在用NAND但没深究过“为什么”的工程师因为这三个操作背后有大量的魔鬼细节。4.1 编程FN隧穿与“先擦后写”的硬约束编程操作的目标是往指定存储单元的浮栅里注入电子让它的阈值电压抬高从而记录不同的状态。整个流程是这样的首先保证目标块已经处于擦除状态电子被清空阈值电压全部较低。在选中的字线上施加一个编程电压Program Voltage通常为15~20V。在选中的位线上施加0V接地让目标串形成从位线到沟道的导通路径。没有选中的位线则施加一个较高的电压Vcc让对应的串沟道电位抬升抑制编程自举抑制。编程操作实际上是反复的“加压-校验”循环Incremental Step Pulse ProgrammingISPP每次增加一点电压直到目标单元的阈值电压达到目标范围内。为什么要用ISPP这种“小步慢跑”的方式因为直接一锤子定音很容易把阈值电压打过头状态就越界了。每次只加一点点校验一次不够就再加这样可以把最终阈值电压的分布控制得很窄。分布越窄留给相邻状态的间隔就越大数据可靠性越高。我在实际调NAND主控的时候经常需要读芯片内部的状态寄存器来看P/E状态也会通过编程器手动执行单页编程来验证芯片好坏。用ISPP流程调试时最直观的感受是好芯片很快收敛几次脉冲就编程成功快报废的芯片编程脉冲打到很高电压还校验不过去甚至直接报Program Fail。4.2 自举抑制编程时为什么不会误写同串其他Cell很多第一次接触NAND编程的人都会问一个问题一条串上串联了几十个Cell编程电压只加在选中的那条字线上但同一串上其他Cell和选中Cell是公共同一条沟道的为什么它们不会被误编程答案就在自举抑制Self-Boosting效应。具体来说当选中字线施加高编程电压时同一条串上其他字线会施加一个“通过电压”Pass Voltage比如10V左右这个电压能让这些Cell完全导通但不发生隧穿。此时如果位线是0V整条串的沟道都接地选中Cell两侧存在高电压差于是发生FN隧穿电子注入浮栅。如果这条串没被选中位线为高电平情况就完全不同了。位线的Vcc电压通过选通管传到沟道加上各字线通过电压的电容耦合效应空穴导电沟道电位会被抬升到很高的水平。这样选中字线和沟道之间的电压差就被大大缩小不足以产生隧穿效应电子也就不会注入浮栅。这个效应让我想起一个很常见的误区用编程器给NAND单个Page编程时如果位线电压配置有误或者编程器固件的老版本有bug很容易出现“写一个页结果旁边几个页也坏了”的现象。这就是自举抑制被破坏的结果。我遇到过几次最后查下来都是因为编程器的驱动没有正确设置未选中位线的电压导致沟道电位没被抬起来。所以如果你也用编程器手动操作NAND最好先熟悉芯片手册上关于Unselected Bit Line Voltage的推荐值。买了好编程器但不会配这些偏压参数跟拿锤子砸芯片没什么区别。4.3 读操作从位线电流变化判断Cell状态读取操作的核心是“感测”Sense。NAND在读取时并不直接测量电荷多少而是借助位线上的电流或电压变化来判断目标单元的阈值电压状态。标准读取流程所有串的GST导通把源极线接地。所有字线先施加通过电压Pass Voltage保证同串上非目标单元全部导通。目标字线施加一个或多个参考电压Read Voltage这个电压落在两个状态分布之间的间隔里。SST导通位线开始充放电。如果目标单元的阈值电压低于参考电压晶体管导通位线被放电或被拉低如果高于参考电压晶体管不导通位线保持高电位。通过感测放大器Sense Amplifier比较位线的电位变化读出这一页的数据。对于SLC一次参考电压比较就够了对于MLC/TLC/QLC需要多个参考电压做多次比较才能把完整的2/3/4比特解析出来。这也是为什么TLC读速度低于SLC的原因之一——它要比较的档位更多。还有一点很关键读操作采用“正电压读取”机制。读某一页时其他字线加的通过电压会造成前文提到的读干扰。工程师在设计文件系统或FTL策略时有时会做“读刷新”Read Refresh——把经常被读取的块的数据重写到别的块再把原块擦掉就是为了防止某一个块因为被反复读取而错误率飙升。5. 从阵列结构回到工程现场坏块、冗余块与编程器的“读全片”逻辑从结构上讲清楚了阵列排布和读写擦原理但这些知识如果只停在脑子里就浪费了。我们最终目的是要用好这些NAND芯片不管你是做产品开发还是像我一样偶尔做数据恢复都需要把架构知识翻译成实际操作策略。5.1 出厂坏块与新增坏块结构特性决定管理策略NAND内部不是所有块都能用的。芯片出厂时厂商就已经把一些在测试阶段不合格的块标记为坏块出厂坏块在块内某个固定位置比如Page 0或Page 1的Spare Area写入坏块标记。这是正常现象出厂坏块数量通常在总块数的1%~2%左右。随着芯片使用还会出现新增坏块运行坏块。原因可以是反复擦写导致氧化层击穿、读干扰积累、数据保持失败等。结合前文的架构特点可以推导出坏块的几个规律坏块是成块出现的不会出现“块里坏半页”的可用状态虽然个别页错误多的情况可能存在。坏块的位置没有规律所以控制器必须动态管理块映射。同一个盘不同批次的坏块分布千差万别绝对不能拿一张表的坏块信息套到另一颗芯片上。这给生产环节提了个醒如果做产品设计NAND颗粒来料一定要做全片扫描不能用出厂坏块标记就完事。因为原厂只保证“坏块标记存在”不保证“未标记的块全部健康”。程序上直接跳过带标记的块遇到没标记但有严重错误的新增坏块就必须靠ECC去兜底了。5.2 用编程器的视角理解读ID、擦除整片、坏块表为什么不固定在“0号块”很多用过编程器比如BeeProg2读NAND的人都知道有个“Auto-Read”功能但未必清楚它背后的逻辑。结合结构知识来看就清楚了。编程器读全片时实际上是逐Block、逐Page地把数据镜像出来。但有个绕不开的问题坏块怎么办如果直接读坏块出来的数据是垃圾如果跳过坏块又会导致镜像文件的物理地址和逻辑地址对不上。所以编程器层面的解决思路是先读芯片的ID确认厂商、制程、容量、电压等参数匹配正确的读取时序。扫描全片的坏块标记建立坏块表。正常块逐页读取坏块单独标记或填填充数据有些编程器支持把坏块数据全部填FF。如果是做完整克隆就必须连同坏块表一起复制到目标芯片因为目标芯片即使型号相同坏块分布也完全不同。这里有个容易踩的坑不要把坏块表“默认”放在0号块。虽然很多芯片的0号块一般质量有保证但这不是绝对的。如果0号块恰好是坏块你按固定偏移去找坏块表找到的只会是垃圾数据。做法是扫描每个块的固定页的固定偏移根据奇偶规则有的用0xFF表示好块0x00表示坏块判断。扫描之前先通过ID信息确认芯片支持哪一种坏块标记格式。5.3 基于阵列结构的常识反推主控FTL该做什么从阵列结构往回调很多主控层的设计决策就有了必然性。写入粒度既然Page是编程最小单位FTL映射表就必须以Page为单位管理至少也要以Page对齐。写入数据小于一个Page时会产生部分编程Partial Programming的困扰所以要用日志式写入先写到空页里。垃圾回收既然块是擦除最小单位FTL就必须在后台维护一批“干净块”。脏块要回收时把有效页搬运走再整块擦除这就产生了写入放大。磨损均衡既然P/E次数有限FTL要尽量让所有块的擦写次数接近避免一部分块先死掉。读干扰处理既然读操作会干扰邻近单元FTL要监测块的读计数超出阈值就做数据搬移。这些东西在主控datasheet里是一堆配置选项但你从阵列架构出发就能自己推导出来不需要死记硬背。我后来看各种主控的FTL源码时越来越觉得所有功能模块本质上都是在给浮栅晶体管的物理特性“擦屁股”。从最初的宏观排布到单个浮栅晶体管的物理特性再到串与阵列的编织方式最后回到读写擦的三条电路路径这章内容就像给NAND Flash画了一张完整的“内部地图”。有了这张地图你再拿起编程器、再调FTL、再做数据恢复心态都会变因为你不再是被芯片手册里的参数推着走而是能理解每个参数背后的物理逻辑了。顺便说个小技巧如果你需要深入学习某一颗具体芯片的行为最好同时看三份资料——芯片手册了解指令和时序、应用笔记了解推荐配置、以及用示波器实测验证时序。单纯看《Inside NAND Flash Memories》这类书框架是有了但落地还是要靠动手对照。书里的架构图和你示波器上抓到的信号对上了那才是真正吃透了。
返回列表