The Memory Technology Devices (MTD) layer in the kernel is used to provide an abstraction layer for memory devices (most often, flash devices). This allows higher levels (such as filesystems like jffs or yaffs) to not care about the physical backing. It could be on a parallel NOR flash chip hooked up to the asynchronous memory bus, or a serial flash chip on the SPI bus, or a NAND flash chip hooked up a variety of ways.

All options here are found under the MTD menu. The parent nodes have been omitted for brevity. Keep in mind that there is no restriction on using different flash types simultaneously (parallel and SPI and NAND and …).

Also keep in mind that these options only turn on drivers. They do not include the other half of the equation: board resources. Your board will have to declare appropriate resources in your Board Resources file. Consult other boards (such as the BF537-STAMP or BF548-EZKIT) for good examples.

Has a full address/data (memory) interface that allows random access to any location. It is block-erasable (many words will be erased at once), but is typically programmable as words or bytes at a time. Typically connected via the asynchronous memory bus.

To use this type of flash under Linux, you probably want these options:

The ideal solution for applications requiring a large amount of data storage memory. The common densities are much larger such as sizes from 128Mbit (16Mbytes) to 8Gbit (1Gbyte), but requires bad block handling. May be connected via the asynchronous memory bus or a dedicated controller.

To use this type of flash under Linux, you probably want one of these options:

Since each flash chip vendor designs their own communications protocol (for telling the chip to read/write/erase/protect regions of the flash), all of this logic is hidden away at the chip driver level. This presents to the next MTD layer a simple abstract interface of common operations. Higher levels can then write to this common interface and so work with a variety of flash chips without needing to change anything.

Nowadays, flash technologies in the same field tend to support the same instruction set (for example, CFI on parallel NOR flashes). This allows the same software chip driver to support a wide variety of arbitrary flash chips. You should, however, verify that the flash chip you're planning on using is actively supported before designing it into your board.

This also means that, unless you ignore the aforementioned advice, you probably will not need to write your own chip driver for an exotic flash part.

A mapping driver is used as the “glue” driver. It is used to manage how the flash device is actually hooked up to the processor. In other words, it facilitates communication between the Blackfin and the flash chip, but it does not know anything about the actual communication (since that is the job of the chip driver). This feature tends to be specific to parallel flash chips however. You could consider the SPI bus the “mapping driver” for serial NOR flashes, but you need not worry about that layer as there is a common SPI framework. NAND devices tend to be very board specific already, so each driver provides its own method/degree of board customization.

The mapping driver is also how the partition layout is tied to a specific device, but more on that in the next section.

One of the common (and simplest) mapping drivers is the physical mapping driver (physmap). This driver is used for any CFI compliant flash which is completely directly addressable on the memory bus. For example, if an asynchronous memory bank is dedicated to a flash chip and you can access it without any other assistance, this common mapping driver would be used.

Some examples of when a custom mapping driver will be needed:

flash and another device (like ethernet on the BF533-STAMP) share a single asynchronous bank

flash uses GPIO's for additional addressing

The mapping driver allows you to hook every flash operation before calling down into the specific chip driver.

All mapping drivers are stored in the same location in linux-2.6.x/drivers/mtd/maps/. This may seem like an odd place for such a (usually) board-specific option, but it is how things are done. It also allows for mapping drivers which do very similar operations to be unified for multiple boards/architectures.

Often times, people do not want to use a flash device as just one big chunk of contiguous storage. Perhaps you want to store the bootloader, a kernel, a root filesystem, and reserve a small chunk for your own product-specific purpose. By defining a partition layout, you need not manage the storage yourself. The kernel will break up and enforce the specified boundaries for you. If you wanted, you could even mark some partitions with custom attributes (such as making a recovery partition as read-only).

Since this topic tends to be much easier to just copy and paste existing examples, please see the Board Examples section below.

While the MTD framework does sufficiently abstract the lower layers to allow you to format and use any file system type on flash media, you should only be using “flash friendly” file systems on them. Since flash media presents unique restrictions when compared to standard media (flash must be erased before writing, you have to erase/write in chunks rather than just bytes, limited number of erase/write cycles before flash goes bad, etc…), you should use a file system that is designed to work with these things in mind. Otherwise you risk arbitrary file system corruption or worse, premature flash failure.

Certainly any read-only file system (such as romfs or cramfs) would be OK as you only write it once, but if you want persistent backing (in other words, a writable file system), then you currently have two choices: jffs and yaffs. See the respective pages for more information on each type.

Not all boards will be shown, just a representative sampling. Keep in mind that the structures documented here are not the entire picture. The resources are often declared in a couple of related structures. Consult the relevant board resources file for the full picture.

Assuming you've enabled the kernel configuration option, you can override the default layout that is in the board resources by using the kernel command line. For example:

bootargs=mtdparts=FLASH-DRIVER:256k(uboot)ro,1792k(kernel),-(rootfs)

Replace the FLASH-DRIVER with whatever driver you are using. For the BF533-STAMP parallel flash, this will be bfin-async-flash. For the default physical mapping driver, this will be physmap-flash.0 (increment the number for each flash). For SPI flashes, replace with the driver name (such as m25p80 -- this is the driver name, not the type).

For the full command line syntax, consult the linux-2.6.x/drivers/mtd/cmdlinepart.c file. It will be documented at the top.

There are optional flags which can be set for each partition. The variable mask_flags can be set to (from linux-2.6.x/include/mtd/mtd-abi.h):

MTD_CAP_ROM - No write

MTD_CAP_RAM - Bits can be cleared, Bits can be set, Direct I/O is possible

MTD_CAP_NORFLASH - Bits can be cleared, Has an erase function

MTD_CAP_NANDFLASH - Bits can be cleared, Has an erase function, Out-of-band data

Assuming everything works out, you should see messages from the kernel about creating MTD partitions. The exact output is dependent on your partition table, but you should be able to gloss the details.

Here we see three partitions being setup for the parallel NOR flash (declared via the command line), two partitions for the SPI flash (declared via the board resources), and two partitions for the NAND flash (declared via the board resources).

You could hook up a NAND flash via the asynchronous memory bank. We've created and documented such an example cf-ide-nand board. For Blackfins that include an on-chip NAND flash controller, you can just use that.

Note
The Input speed may be invalid.
Since there is only 2MB SPI flash on BF548-Ezkit, the file size cannot be very large. According to bonnie++, file size should double RAM size in order to get a good result.