Memory Tecnology Device (MTD)
Memory Technology Devices (MTD)
MTD subsystem (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 (NOR and NAND in particular). Please refer to the official documentation for detailed information.
The mapping driver can either specify a hard-coded partition layout or read the partition layout from the kernel command line passed in from the boot loader. With partition support, each MTD partition will be exported as a separate MTD device. Each device has a descriptive name which can be viewed using the following command:
Command line configured MTD partitions
You can interact with the MTD subsystem using the MTD Utilities, a collection of tools that can be used to perform operations on Flash devices. For further information on this package, plese refer to http://processors.wiki.ti.com/index.php/MTD_Utilities
Usually the mtd-utils collection is provided as a pre-built binary package. Anyway, it can also be cross-compiled for the specific target.
UBI (Unsorted Block Images) is a volume management system for raw flash devices which manages multiple logical volumes on a single physical flash device and spreads the I/O load (i.e, wear-leveling) across whole flash chip. UBI/UBIFS is the recommended solution when using large flash partitions. For further information on UBI, plase refer to http://www.linux-mtd.infradead.org/doc/ubi.html
File systems on MTD
Because of the particular characteristics of flash memory, it is best used with a specifically designed flash file systems, which handles the read/write/erase operations and the wear-leveling algorithms.
At the moment there are only a few filesystems which support NAND:
- JFFS2 and YAFFS for bare NAND Flash and SmartMediaCards
- NTFL for DiskOnChip devices
- TRUEFFS from M-Systems for DiskOnChip devices
- SmartMedia DOS-FAT as defined by the SSFDC Forum
- UBIFS for bare NAND flash
The most common solutions are JFFS2 and UBI/UBIFS.
The Journaled Flash File System v.2 provides non-volatile storing and compression of data on flash devices. For more details about is please see http://www.linux-mtd.infradead.org/doc/jffs2.html. It can be a good choice for not too big flash partitions (as a reference, not bigger than 128 MByte).
Let's assume the MTD partition associated to the NAND flash is mapped as number 5. Please note that the same technique can be used with the NOR Flash partitions.
Let’s assume we run the kernel by using the net_nfs configuration. From the target shell, run
This command lists all the MTD partitions. For example, the mtd4 partition can be used.
bash-2.05b# eraseall /dev/mtd5 Erasing 16 Kibyte @ nand_erase: attempt to erase a bad block at page 0x0000a740 Erasing 16 Kibyte @ 14e8000 -- 65 % complete. eraseall: /dev/mtd5: MTD Erase failure: Input/output error Erased 32768 Kibyte @ 0 -- 100% complete.
This operation is a sort of formatting. The error shown above refers to a bad block found in the device. These bad block are common for NAND flashes. They resemble somehow bad block of hard disk.
mount -t jffs2 /dev/mtdblock5 /mnt/nand
Linux should print something like this:
/dev/nfs on / type nfs (rw) none on /proc type proc (rw) usbdevfs on /proc/bus/usb type usbdevfs (rw) /dev/mtdblock5 on /mnt/nand type jffs2 (rw)
This means than the device is correctly mounted on /mnt/nand.
To see how much space is left on the device please run the df command:
bash-2.05b# df Filesystem 1K-blocks Used Available Use% Mounted on /dev/nfs 99077740 44983688 54094052 46% / /dev/mtdblock5 32768 912 31856 3% /mnt/nand
Now it is possibile to create create files and directories in /mnt/nand. This stuff will be permanently stored in the NAND flash chip.
Mount root filesystem from MTD JFFS2 partition
First of all it is necessary to have the root file system available on a directory, for example /mnt/rfs (user can mount it throug NFS or loop-mount an ext2 image). Then:
cd /mnt/rfs/ cp -aRv . /mnt/nand/
You should see something like this:
bash-2.05b# cp -aRv . /mnt/nand/ `./bin' -> `/mnt/nand/./bin' `./bin/login' -> `/mnt/nand/./bin/login' `./bin/application' -> `/mnt/nand/./bin/application' `./bin/busybox' -> `/mnt/nand/./bin/busybox' ... `./var/run' -> `/mnt/nand/./var/run' bash-2.05b#
Now reboot the system in order to access the U-Boot shell and modify the root and rootfstype kernel command line parameters on the nandargs environment variable:
setenv nandargs 'setenv bootargs root=/dev/mtdblock5 rw rootflags=noatime rootfstype=jffs2'
Now run the kernel with this command:
When kernel completed boot process, you can verify that the root file system is the one stored in the NAND flash:
# mount rootfs on / type rootfs (rw) /dev/mtdblock5 on / type jffs2 (rw,noatime) /proc on /proc type proc (rw,nodiratime)
UBIFS can be considered as the next-generation of the JFFS2 file system. It is a new journaled flash file system which works on top of the UBI (Unsorted Block Images) subsystem, a wear-leveling and volume management system for raw flash devices. UBI volumes are higher level entities than MTD devices, which represents the raw flash devices (/dev/mtdX) and provide the interface to access flash chips. The following figure shows the involved subsystems:
For more information on UBIFS, please refer to http://www.linux-mtd.infradead.org/doc/ubifs.html
Let's assume the MTD partition associated to the NAND flash is mapped as number X and that we run the kernel by using the net_nfs configuration.
To access and use UBIFS:
- Erase the MTD partition:
- Launch the following command to create the UBI volume:
ubiattach /dev/ubi_ctrl -m X
- The device /dev/ubi0 is now available. To create the UBI volume, launch the following command (-N sets the name and -s sets the size of the volume):
ubimkvol /dev/ubi0 -N rootfs -s 128MiB
- The device /dev/ubi0_0 is now available and can be mounted with one of the following comands:
mount -t ubifs ubi0_0 /mnt/ubifs mount -t ubifs ubi0:rootfs /mnt/ubifs
- To mount the UBI file system as root file system, the binding between MTD and UBI must be specified from the kernel command line, adding the following parameters:
ubi.mtd=X root=ubi0_0 rootfstype=ubifs rw
Please note that
- the file system is formatted automatically the first time it is mounted
- the mount command don't use the /dev/ prefix before ubi0_0 device