最小 flash I/O单元 与 NAND flash 子页

Minimum flash IO unit

UBI uses an abstract model of flash. In short, from UBI's point of view the flash (or MTD device) consists of eraseblocks, which may be good or bad. Each good eraseblock may be read from, written to, or erased. Good eraseblocks may also be marked as bad.

Flash reads and writes may only be done in portions of minimum input/output unit size, which depends on flash type.

  • NOR flashes usually have min. I/O unit size of 1 byte, because NOR flashes usually allow reading and writing single bytes (in fact, it is even be possible to change individual bits).
  • Some NOR flashes may have other min. I/O unit sizes, e.g. 16 or 32 bytes in case of ECC'd NOR flashes.
  • NAND flashes usually have 512, 2048 or 4096 byte min. I/O. unit size, which corresponds to NAND page size. NAND flashes store per-NAND page ECC codes in the OOB area, which means that whole NAND page has to be written at once to calculate the ECC code, and whole NAND page has to be read at once to check the ECC code.

UBI 使用了一个 flash 的抽象模型, 简单来说, 从UBI角度来看, flash 由擦除块组成, 这有优点也有缺点, 每一个好的擦除块都可以执行读写或擦除操作,  也可以标记为坏块。

flash的读写可以以 最小 IO 单元大小的倍数进行, 这取决于flash的类型。

  • NOR flash 通常有最小 1 字节的 I/O 单元, 因为 NOR flash 通常允许读写单个字节(事实上, 甚至可能修改单个位)
  • 也有一些 NOR flash 含有最小16或32字节的 I/O 单元
  • NAND flash 通常含有 512, 2048 或 4096字节的最小 I/O 单元, 它与NAND页大小对应; NAND flash 存储每一个page的 ECC 码在OOB区, 这意味着整个 NAND 页面必须立即写入, 以计算 ECC 值, 同时也必须一次读出, 来检查 ECC 值。

The min. I/O unit size is a very important characteristic of the MTD device. It affects many things, e.g.:

  • physical position of the VID header depends on the min. I/O unit size, which means that LEB size also depends on it; generally, the larger is the min. I/O unit size, the less is LEB size, and the greater is UBI flash space overhead;
  • all writes to LEBs should be aligned to min. I/O unit size, and should be multiple of the min. I/O unit size; this does not apply to reads, but bear in mind that on the MTD level all reads are done in fractions of min. I/O unit size anyway; this is just hidden from users by buffering the read data and copying only the requested amount of bytes to the user buffer.
最小 I/O 单元的大小是 MTD 设备的重要特征, 它会影响很多方面, 例如:
  • VID header 的物理位置依赖 最小 I/O 单元大小, 这意味着 LEB 大小也依赖它; 总的来说, 比最小 I/O单元 大的越多, LEB size 就越小, UBI 空间的管理成本就越高
  • 所有写入到 LEB 的数据都应该以最小 I/O 单元大小对齐, 应该是最小单元的倍数, 这不适用于读操作; 但需要记住, 在MTD层, 所有的读操作都是以最小单元的比例进行的, 这是通过缓存和仅copy用户请求的那部分来达到对用户隐藏的目的。 

NAND flash sub-pages

As it is said here, all UBI I/O should be done in fractions of min. I/O unit size, which is equivalent to NAND page size in case of NAND flash. However, some SLC NAND flashes allow for smaller I/O units, which are called sub-pages in MTD terminology. Not all NANDs have sub-pages.

  • MLC NANDs do not have sub-pages, at least to the date of writing of this piece of documentation (April 2009).
  • SLC NANDs usually do have sub-pages. E.g., 512-byte NAND pages usually consist of 2x256-byte sub-pages, and 2048-byte NAND pages consist of 4x512-byte sub-pages.
  • SLC OneNAND chips with 2048 bytes NAND page size have 4x512-byte sub-pages.

如之前所述, 所有的 UBI I/O 操作都是以最小 I/O 单元大小的倍数进行, 在NAND flash中该最小单元与 NAND page大小相等。 然而有些 SLC NAND flash 允许更小的 I/O 单元, 这在 MTD 术语中称为 子页。 并不是所有的 NAND 都有子页。

  • MLC NANDs 不含有子页, 至少到写本文档时是这样(2009.04)
  • SLC NANDs 通常含有子页, 例如, 512 字节的 NAND page 通常由2个256字节的子页, 2048 字节的 NAND page 由 4个 512 字节的子页
  • 页大小为 2048 字节的SLC OneNAND 芯片有4个512字节的子页 


If the NAND flash supports sub-pages, then what can be done is ECC codes can be calculated on per-sub-page basis, instead of per-NAND page basis. In this case it becomes possible to read and write sub-pages independently.

But obviously, even though the NAND chip may support sub-pages, the NAND controller may disallow them. Indeed, if the flash is managed by a controller which calculates ECC codes on per-NAND page basis, then it is impossible to do I/O in sub-page fractions. E.g. this is the case for the OLPC XO-1 laptop) - its NAND chip supports sub-pages, but the NAND controller does not.

Note, sub-page is an MTD term, but this is also referred to as "NOP" which stands for "number of partial programs". NOP1 NAND flashes have no sub-pages - UBI treats them as NANDS with sub-page size equivalent to NAND page size. NOP2 NAND flashes have 2 sub-pages (half a NAND page each), NOP4 flashes have 4 sub-pages (quarter of a NAND page each).


如果 NAND flash 支持子页, 那么 ECC 码就可以基于每个子页进行计算, 而不是整页。 在这种情况下, 就可以独立的读写子页。

但很显然, 即使NAND芯片支持子页, NAND 控制器也可能不使用它们; 事实上, 如果flash由控制器管理, ECC 码基于页进行计算, 那么以子页进行I/O就是不可能的。

注意, 子页是 MTD 术语, 但UBI中它被称作 NOP(Number of Partial Programs), NOP1 代表没有子页, NOP2代表有2个子页, NOP4代表有4个子页。


UBI utilizes sub-pages to lessen flash space overhead. The overhead is less if NAND flash supports sub-pages (see here). Indeed, let's consider a NAND flash with 128KiB eraseblocks and 2048-byte pages. If it does not have sub-pages, UBI puts the the VID header at physical offset 2048, so LEB size becomes 124KiB (128KiB minus one NAND page which stores the EC header and minus another NAND page which stores the VID header. In opposite, if the NAND flash does have sub-pages, UBI puts the VID header at physical offset 512 (the second sub-page), so LEB size becomes 126KiB (128KiB minus one NAND page which is used for storing both UBI headers). See this section for more information about where the UBI headers are stored.

UBI 使用子页来减少维护 flash space的开支, 如果 NAND flash 支持子页, 开支会更少; 让我们考虑一下 128 KB 擦除块的flash, 它的页大小为2048字节; 如果不支持子页, UBI 把VID header 放在偏移量为2048的物理位置, 因此 LEB 大小变成了 124 KB(128KB减去4KB的EC header 页, 4KB 的VID header 页)。 相反, 如果NAND flash 支持子页, UBI 把 VID header 放在偏移量为512字节处(第二个子页), 因此 LEB 大小 为 126 KB(128 减去一个存储两个UBI头的页(2KB))。


Sub-pages are used by UBI only internally, and only for storing the headers. UBI API does not allow users doing I/O in sub-page units. One of the reasons for this is that sub-page writes may be slow. To write a sub-page, the driver may actually write whole NAND page, but put 0xFF bytes to the sub-pages which are not relevant to this operation. E.g., this means that writing 4 sub-pages may be 4 times slower than writing whole NAND page at once. Thus, UBI does use sub-pages for the headers, but this notion does not exist in the UBI API.

子页仅在 UBI 内部使用, 仅用于存储头信息。 UBI  API 不允许用户按子页进行 I/O进行读写,这样做的原因是子页读写可能较慢。要写一个子页, 驱动实际上可能写整个 NAND 页, 与本次操作无关的部分用 0xFF 填充;例如, 写4个子页可能比写整个页慢4慢。 因此, UBI 仅在存储头信息时使用子页, 在UBI API 中这个概念不存在。



你可能感兴趣的:(Linux)