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.
UBI 使用了一个 flash 的抽象模型, 简单来说, 从UBI角度来看, flash 由擦除块组成, 这有优点也有缺点, 每一个好的擦除块都可以执行读写或擦除操作, 也可以标记为坏块。
flash的读写可以以 最小 IO 单元大小的倍数进行, 这取决于flash的类型。
The min. I/O unit size is a very important characteristic of the MTD device. It affects many things, e.g.:
如之前所述, 所有的 UBI I/O 操作都是以最小 I/O 单元大小的倍数进行, 在NAND flash中该最小单元与 NAND page大小相等。 然而有些 SLC NAND flash 允许更小的 I/O 单元, 这在 MTD 术语中称为 子页。 并不是所有的 NAND 都有子页。
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 中这个概念不存在。