General MTD documentation

Table of contents

  1. MTD overview
  2. MTD API
  3. MTD tests
  4. The mtdblock driver
  5. Old MTD documentation

MTD overview

MTD subsystem (stands for Memory Technology Devices) provides an abstraction layer for raw flash devices. It makes it possible to use the same API when working with different flash types and technologies, e.g. NAND, OneNAND, NOR, AG-AND, ECC'd NOR, etc.

MTD subsystem does not deal with block devices like MMC, eMMC, SD, CompactFlash, etc. These devices are not raw flashes but they have a Flash Translation layer inside, which makes them look like block devices. These devices are the subject of the Linux block subsystem, not MTD. Please, refer to this FAQ section for a short list of the main differences between block and MTD devices. And the raw flash vs. FTL devices UBIFS section discusses this in more details.

MTD subsystem has the following interfaces.

MTD subsystem supports bare NAND flashes with software and hardware ECC, OneNAND flashes, CFI (Common Flash Interface) NOR flashes, and other flash types.

Additionally, MTD supports legacy FTL/NFTL "translation layers", M-Systems' DiskOnChip 2000 and Millennium chips, and PCMCIA flashes (pcmciamtd driver). But the corresponding drivers are very old and not maintained very much.


The MTD subsystem API is defined in include/linux/mtd/mtd.h. The methods and data structures in this file are used by higher layer kernel code such as flash file systems to access and control the mtd devices, and also by device driver authors to interface their device to the mtd subsystem. The various methods by which a driver provides access to the device are defined within struct mtd_info. Prior to kernel version 3.4, higher layers called the driver methods directly by way of a pointer to struct mtd_info. As of kernel 3.4, these methods are implemented within the mtd subsystem core code, which then calls the corresponding driver methods. Users of kernel 3.4 and later should not call the driver methods directly, but instead use those prototyped in mtd.h outside of struct mtd_info. These methods include mtd_read(), mtd_write(), etc.

Absent an error, the API methods will return zero, with two notable exceptions. mtd_read() and mtd_read_oob() may return -EUCLEAN in some circumstances. This return code is applicable mainly to NAND flash devices, and is used to indicate that some bit errors were corrected by the device's ECC facility. Prior to kernel version 3.4, -EUCLEAN was returned if one or more bit errors were corrected during the read operation. As of kernel 3.4, the meaning is more nuanced, and can be broadly interpreted to mean "a dangerously high number of bit errors were corrected". The -EUCLEAN return code is intended to help higher layers detect degradation of erase blocks. The conditions by which mtd_read() and mtd_read_oob() return -EUCLEAN can be tuned using the bitflip_threshold element of the sysfs interface. Please see the kernel documentation for the MTD sysfs interface (referenced above) before adjusting this value.

MTD tests

The MTD subsystem includes a set of tests which you may run to verify your flash hardware and drivers. The tests are available in the mainline kernels starting from kernel version 2.6.29 and they live in the drivers/mtd/tests directory of the linux kernel source codes. You may compile the tests as kernel modules by enabling them in the kernel configuration menu by marking: "Device Drivers" -> "Memory Technology Device (MTD) support" -> "MTD tests support" (or the MTD_TESTS symbol in the .config file).

If you have a pre-2.6.29 kernel, you may find the tests here:


The MTD test-suite contains the following tests:

The mtdblock driver

The mtdblock driver available in the MTD is an archaic tool which emulates block devices on top of MTD devices. It does not even have bad eraseblock handling, so it is not really usable with NAND flashes. And it works by caching a whole flash erase block in RAM, modifying it as requested, then erasing the whole block and writing back the modified. This means that mtdblock does not try to do any optimizations, and that you will lose lots of data in case of power cuts. And last, but not least, mtdblock does not do any wear-leveling or bit-flips handling.

Often people consider mtdblock as general FTL layer and try to use block-based file systems on top of bare flashes using mtdblock. This is wrong in most cases. In other words, please, do not use mtdblock unless you know exactly what you are doing.

There is also a read-only version of this driver, mainly for use with uCLinux where the extra RAM requirement was considered too large. However, just like the R/W version of the driver, there is no wear-levelling and bit-flips handling.

Instead of using this old driver, you may check the R/O block device emulation provided by UBI useful. Please refer to the UBI section for more details.

Old MTD documentation

Old MTD web site and old MTD documentation is available here. Old NAND flash interface description is available here.

Last updated: 14 Oct 2008, dedekind Valid XHTML 1.0! Valid CSS!