第2章 NAND Flash物理结构:页、块、平面、芯片的组织关系
好,咱们今天聊聊NAND Flash的物理结构。说实话,我刚入行那会儿,被这些层级关系搞得有点晕——页、块、平面、芯片,到底谁套着谁?后来亲手调过几块芯片,才真正搞明白。你想想看,搞懂这个结构,就像拿到了一张地图,后面做坏块管理、磨损均衡,心里才有底。
2.1 最小的读写单位:页(Page)
页,是NAND Flash里最小的读写单位。注意,我说的是读写,不是擦除。
一个页有多大?常见的有三种:
- 小页(Small Page):512字节数据 + 16字节备用区(OOB)——老古董了,现在基本见不到
- 标准页(Standard Page):2KB数据 + 64字节OOB——很多MLC芯片还在用
- 大页(Large Page):4KB、8KB甚至16KB数据 + 对应的OOB——TLC、QLC的主流选择
核心要点:页是读写的最小单位。你要读数据,至少读一页;你要写数据,至少写一页。不能只读写半个页。
我在项目中遇到过一个问题:某次做文件系统优化,想只修改一个字节,结果发现必须先把整页读出来,改完再写回去。嗯,这就是页的粒度带来的限制。你想想看,如果频繁做这种小修改,性能会很难看。
2.2 擦除的最小单位:块(Block)
块,是擦除的最小单位。一个块包含多个页。
为什么擦除不能按页来?说白了,这是NAND Flash的物理特性决定的。擦除操作需要施加高电压,把整个块的浮栅晶体管复位到“1”状态。按页擦除的话,相邻页会互相干扰,可靠性没法保证。
常见的块大小:
| 芯片类型 | 每块页数 | 块大小(典型值) |
|---|---|---|
| SLC | 64页 | 128KB |
| MLC | 128页 | 256KB |
| TLC | 256页 | 1MB |
| QLC | 512页 | 2MB |
避坑指南:我曾经在项目里犯过一个低级错误——试图按页擦除数据。结果芯片直接返回错误状态。后来查手册才发现,擦除命令只接受块地址。记住:写可以按页,擦必须按块。
2.3 并行操作的单元:平面(Plane)
平面,是NAND Flash内部实现并行操作的关键。一个芯片通常包含2个、4个或8个平面。
每个平面有自己的页缓存(Page Buffer),可以独立执行读写操作。这意味着什么?你可以同时往两个平面写数据,速度翻倍。
我个人的习惯是,在做驱动设计时,优先考虑平面间的并行性。比如:
- 平面0写数据的同时,平面1可以读数据
- 多个平面可以同时执行擦除操作
- 支持多平面编程(Multi-Plane Program)的芯片,可以一次写入多个平面
为什么会这样设计?你想想看,NAND Flash的读写速度本来就不快,如果串行操作,性能更惨。平面并行是提升吞吐量的关键手段。
2.4 独立的物理单元:芯片(Die)
芯片,也叫Die,是NAND Flash最顶层的物理单元。一个封装里可能包含多个Die,通过片选信号(CE#)来区分。
每个Die是独立的:
- 有自己的控制逻辑
- 有自己的地址寄存器
- 可以独立执行命令
- Die之间互不干扰
多Die设计的好处很明显:你可以把多个Die当成独立的存储设备来用,进一步增加并行度。我在做SSD主控时,就经常利用多Die特性做交错访问——一个Die在忙,另一个Die可以立即响应。
2.5 层级关系总结
好了,咱们把四个层级串起来:
芯片(Die)
└── 平面(Plane)
└── 块(Block)
└── 页(Page)
└── 数据 + OOB
一个Die包含多个平面,一个平面包含多个块,一个块包含多个页。页是最小读写单位,块是最小擦除单位,平面和Die是并行操作单位。
实用技巧:做坏块管理时,我建议你以块为单位做映射。为什么?因为擦除是按块的,如果按页映射,擦除时还得处理多个映射条目,复杂度飙升。以块为单位,映射表小,管理简单,性能也好。
2.6 地址映射关系
最后,咱们看看地址是怎么组织的。一个完整的NAND Flash地址包含:
- Die地址:选择哪个芯片
- 平面地址:选择哪个平面
- 块地址:选择哪个块
- 页地址:选择块里的哪个页
- 列地址:选择页内的哪个字节(用于读写)
举个例子,假设一个芯片有2个平面,每个平面1024个块,每个块128页,每页2KB:
地址格式(从高位到低位):
[Die:1位] [Plane:1位] [Block:10位] [Page:7位] [Column:11位]
嗯,这里要注意:不同芯片的地址位宽不一样,具体要看数据手册。我习惯在驱动里用宏定义把这些位域拆开,方便调试。
好了,这一章就到这里。下一章咱们聊聊坏块的产生原因和检测方法——这可是做NAND Flash开发绕不开的硬骨头。