Linux MTD Subsystem with Xilinx EMC core - HOWTO

Linux MTD Subsystem with

Xilinx EMC core - HOWTO

Version 1.0

Author(s):

Table of Contents

Summary

1Introduction

1.1Chip drivers

1.2Map drivers

1.3User modules

1.4MTD utilities

2Configuring the MTD Subsystem

2.1 Enabling the MTD support

2.2Choosing the Chip driver

2.3Choosing the Map driver

2.3.1CFI Flash device in physical memory map

2.3.2Flash device in physical memory map based on OF description

2.4Emulating a char or block device

3Working with the MTD enabled Flash

3.1Erasing the flash

3.2Writing to the flash

3.3Reading from the flash

3.4Creating partitions on the flash

3.4.1Command line partition table parsing

3.4.2Redboot partition table parsing

3.4.3Flash partition map based on OF description

4Mounting jffs2 filesystem on the MTD device

5Unsorted Block Images (UBI)

5.1Features of the UBI

5.2UBI Utilities

5.3Attaching a MTD device to UBI

5.4Creating UBI volumes

5.5Mounting JFFS2 on UBI volume

6References

7Revision History

Table of Figures

Figure 1 Linux MTD Subsystem

Figure 2 Enabling the MTD subsystem

Figure 3 Choosing the Chip driver

Figure 4 Choosing the Map driver

Figure 5 CFI Flash device in physical memory map

Figure 6 Setting buswidth/chip-interleave for CFI Flash device in physical memory map

Figure 7 Flash device in physical memory map based on OF description

Figure 8 Char device Emulation

Figure 9 Command line partition table parsing

Figure 10 Enabling UBI support

Figure 11 Enabling UBI debug support

Figure 12 Emulating MTD device on UBI volume

Summary

This document describes the usage of the Memory Technology Device (MTD) Subsystem of Linux in conjunction with Xilinx EMC core and external NORflash chips. It starts with a basic view of the MTD in kernel and proceeds through enabling the MTD support in your kernel, working with the MTD enabled flash devices, and mounting filesystems onto the flash devices, etc. This document doesn’t provide information about the usage of MTD with NAND chips.

This document consists of the following sections:

Chapter 1,“Introduction”, provides a view of the MTD Subsystem in the kernel and information about the basic components of the MTD Subsystem.

Chapter 2,“Configuring the MTD Subsystem”, takes a look at enabling the MTD support and accessing the NOR Flash chips connected through the Xilinx EMC core.

Chapter 3,“Working with the MTD enabled Flash”, examines performing I/O and creating dynamic partitions on the MTD enabled flash.

Chapter 4,“Mounting jffs2 filesystem on the MTD device”, provides information about mounting jffs2 filesystem on to the MTD enabled flash device.

Chapter 5,“Unsorted Block Images (UBI)”, explains the features of UBI along with the creation of UBI volumes and mounting jffs2 filesystem on a UBI volume.

1

Linux MTD Subsystem with Xilinx EMC core - HOWTO

1Introduction

This document describes the usage of the Linux Memory Technology Device (MTD) Subsystem of Linux in conjunction with Xilinx EMC core and external NOR flash chips.

The Linux MTD subsystem provides support for flash (NOR and NAND) and similar non-volatile storage devices.MTD uses a layered approach; it is easy to add new devices and have them functional. MTD is integrated into Linux kernel and also provides mechanisms to mountfilesystems on to the flash. The Figure 1 Linux MTD Subsystemprovides a detailed view of the MTD Subsystem in the Linux kernel.

Figure 1 Linux MTD Subsystem

MTD can be broadly classified into

  • Chip drivers
  • Map drivers
  • User modules
  • MTD utilities

The MTD also consists of libraries and structures which are used by the rest of the MTD.

1.1Chip drivers

Chip drivers implement low level support for the NAND and NOR flash devices. MTD has drivers for the NOR flash devices that implement standard specifications such as CFI and JEDEC. MTD supports various CFI command sets defined by CFI specification, as kernel modules. The command set supportedbya flash device can be enabled from the kernel configuration.

1.2Map drivers

The MTD subsystem uses map drivers to access the flash devices. A map driver maps the flash device for CPU access and informs the MTD about the storage partitions available on the flash device. We can either use the existing map drivers in the MTD or write our own drivers, to access a standard flash device.

1.3User modules

MTD provides certain drivers which can emulate a block device or a char device over the MTD enabled flash devices, for the higher layers to work with. The block driver allows the user applications to perform file I/O on the flash, while the char driver provides raw I/O access. Device nodes created by block driver are named as mtdblockX, whereas as char driver names them as mtdX, where X stands for the partition number.

1.4MTD utilities

The MTD utilities can be used to work with the MTD enabled flash memory. They provide several tools to erase the flash, create a filesystem image, etc.

2Configuring the MTD Subsystem

2.1 Enabling the MTD support

To enable MTD support in your kernel, go to Kernel configuration -> Device Drivers and enable “MTD support”(CONFIG_MTD).

Figure 2 Enabling the MTD subsystem

2.2Choosing the Chipdriver

Now that we have enabled MTD support, the next step is to chose the appropriate chipdriverto probe your flash device. Since we have a cfi flash, we need to enable support for it. To do this, in Kernel configuration -> Device Drivers -> MTD support -> go to sub-menu for RAM/ROM chip drivers and enable the following.

Detect flash chips by CFI probe (CONFIG_MTD_GEN_PROBE).

Support for your flash chip (Intel chip incase of ML403).

Figure 3 Choosing the Chip driver

2.3Choosing the Map driver

Once you have selected the probe method, the next step is to select a map driver to map the flash device for CPU access.Thecfi flash connected to a EMC core on Xilinx boards can be accessed in one of the following ways.

  • CFI Flash device in physical memory map - Select this option if you want to physically configure the flash device for CPU access.
  • Flash device in physical memory map based on OF description - Select this option if you want the map driver to configure the flash device for CPU access, based on device tree.

2.3.1CFI Flash device in physical memory map

In Kernel configuration -> Device Drivers -> MTD support -> go to sub-menu for “Mapping Drivers for chip access” and enable “CFI Flash device in physical memory map”(CONFIG_MTD_PHYSMAP)andspecify the physical start address, physical length, and bank width. This option uses physmap.c(/drivers/mtd/maps/) driver to register the flash device.

Figure 4 Choosing the Map driver

Figure 5 CFI Flash device in physical memory map

If you have chosen to physically configure the flash device, go to Kernel configuration -> Device Drivers -> MTD support ->RAM/ROM chip drivers and enable ‘Flash chip driver advanced configuration options’-> ‘Specific CFI flash geometry selection’ and enter the bus width and chip interleave based on your hardware configuration.

Figure 6 Setting buswidth/chip-interleave for CFI Flash device in physical memory map

2.3.2Flash device in physical memory map based on OF description

In Kernel configuration -> Device Drivers -> MTD support -> go to sub-menu for “Mapping Drivers for chip access” and enable “Flash device in physical memory map based on OF description”(CONFIG_MTD_PHYSMAP_OF).

This is the preferred method of accessing the EMC flash, as it doesn’t involve any overhead. The associated driver (drivers/mtd/maps/physmap_of.c) parses the device tree and registers the EMC flash, based on the information from the device tree. All the subsequent features discussed in this document assume that user has selected this option to access the flash (though most of the features work with the other option too).

Figure 7 Flash device in physical memory map based on OF description

2.4Emulating a char or block device

Once we have configured the MTD, we should let the higher layers to access the flash. User applications which perform file I/O on the flash device need to see it as a block device,whereas applications which need raw I/O access to the flash, should be able to see it as a char device.

  • Enable “Direct char device access to MTD devices”(CONFIG_MTD_CHAR) or “Caching block device access to the MTD devices”(CONFIG_MTD_BLOCK)to emulate a char device or a block device over the MTD device.
  • To start of with, enable debugging for MTD(CONFIG_MTD_DEBUG), and define the constant DEBUG_CFI in /drivers /mtd/chips/cfi-probe.c.

Figure 8 Char device Emulation

Save the kernel configuration and boot your kernel.You should be able to see messages similar to those below (they might slightly defer based on the map driver used), on your console.It gives the list of features supported by the flash device, mtd device id for the flash device/partition, etc.

80800000.flash: Found 2 x16 devices at 0x0 in 32-bit bank

Intel/Sharp Extended Query Table at 0x0031

Using buffer write method

Extended Query version 1.1

Feature/Command Support: 00C6

- Chip Erase: unsupported

- Suspend Erase: supported

- Suspend Program: supported

- Legacy Lock/Unlock: unsupported

- Queued Erase: unsupported

- Instant block lock: unsupported

- Protection Bits: supported

- Page-mode read: supported

- Synchronous read: unsupported

- Simultaneous operations: unsupported

- Extended Flash Array: unsupported

Supported functions after Suspend: 01

- Program after Erase Suspend: supported

Block Status Register Mask: 0001

- Lock Bit Active: yes

- Lock-Down Bit Active: no

- EFA Lock Bit: no

- EFA Lock-Down Bit: no

Vcc Logic Supply Optimum Program/Erase Voltage: 3.3 V

cfi_cmdset_0001: Erase suspend on write enabled

cmdlinepart partition parsing not available

RedBoot partition parsing not available

mtd: Giving out device 0 to 80800000.flash

After booting the kernel, try cat /proc/mtd. This gives a list of MTD enabled devices.

cat /proc/mtd

[----output------]

dev: size erasesize name

mtd0: 00800000 00040000 "80800000.flash"

The name of your MTD enabled flash depends on the map driver you are using. CONFIG_MTD_PHYSMAP (physmap.c) uses the format phys_mapped_flash, while CONFIG_MTD_PHYSMAP_OF (physmap_of.c) uses the format address.flash, where address is the physical memory area to which your flash device is mapped.

3Working with the MTD enabled Flash

To start working on the MTD enabled flash memory; download the mtd-utils from ftp://ftp.infradead.org/pub/mtd-utils/. Compile the utils with your toolchain. You might also need the library files libz*, used for data compression, if you want to make a jffs2 image and mount the jffs2 filesystem. Copy all the compiled utility executables on to your target.

3.1Erasing the flash

The flash can be erased using the flash_earse or flash_earseall utilities.

flash_eraseall [OPTION] MTD_DEVICE – erases the entire flash

" -j, --jffs2 format the device for jffs2"

" -q, --quiet don't display progress messages"

" --silent same as --quiet"

" --help display this help and exit"

Ex:

flash_eraseall /dev/mtd0

[----output------]
MTD_open
MTD_ioctl

Erasing 256 Kibyte @ 0 -- 0 % complete.

CMTD_ioctl

Erasing 256 Kibyte @ 40000 -- 3 % complete.

CMTD_ioctl

---continue---

Erasing 256 Kibyte @ 7c0000 -- 96 % complete.

MTD_close

[----output------]

flash_erase MTD_DEVICE [start] [# erase blocks] [lock] – erases the specified blocks

flash_erase MTD_DEVICE offset num_sectors

flash_erase -h | --help

Ex:

./flash_erase /dev/mtd0 0x00000 1

[----output------]

MTD_open

MTD_ioctl

MTD_ioctl

MTD_ioctl

Total 1 Units

Region 0 is at 0 of 32 sector and with sector size 40000

Performing Flash Erase of length 262144 at offset 0x0 MTD_close

Done

[----output------]

3.2Writing to the flash

A file can be written to the flash using the following command.

cat file_name > MTD_DEVICE

Ex:

cat /usr/mtd.txt > /dev/mtd0

[----output------]

MTD_open

MTD_write

MTD_close

[----output------]

3.3Readingfrom the flash

The contents of the flash can be read using the following command.

cat MTD_DEVICE > file_name

Ex:

cat /dev/mtd0 > usr.txt

[----output------]

MTD_open

MTD_read

MTD_close

[----output------]

3.4Creating partitions on the flash

To create partitions enable “MTD partitioning support” (CONFIG_MTD_PARTITIONS)in In Kernel configuration -> Device Drivers -> MTD support. Partitions can be dynamically created on the flash device through one of the following three ways.

  • Command Line partition table parsing
  • Redboot partition table parsing
  • Flash partition map based on OF description

3.4.1Command line partition table parsing

To create partitions on the flash through command line do the following.

  • In MTD support, enable “Command line partition table parsing”(CONFIG_MTD_CMDLINE_PARTS).

Figure 9 Command line partition table parsing

  • In the device tree, add the partition table to “bootargs”. The format for the command line partition table is as follows:

mtdparts=<mtddef>[;<mtddef]

where:

<mtddef> := <mtd-id>:<partdef>[,<partdef>]

<mtd-id> := unique id used in mapping driver/device

<partdef> := <size>[@offset][<name>][ro]

<size> := standard linux memsize OR "-" to denote all remaining space

<name> := (NAME)

Ex:Let’s assume that you have a cfi-flash,of size 8MB, mapped to physical memory at 0x80800000 and have enabled CONFIG_MTD_PHYSMAP_OF. If you want to create three partitions named bootloader (size=512K), kernel (size=1M) and rootfs (size=rest of the flash), then add the following to the kernel command line. The parameter ro makes a partition read-only.

mtdparts=80800000.flash:512K(bootloader)ro,1M(kernel)ro,-(rootfs)

The kernel boot-up messages should look similar to those below.

3 cmdlinepart partitions found on MTD device 80800000.flash

Creating 3 MTD partitions on "80800000.flash":

0x00000000-0x00080000 : "bootloader"

mtd: Giving out device 0 to bootloader

0x00080000-0x00180000 : "kernel"

mtd: Giving out device 1 to kernel

0x00180000-0x00800000 : "rootfs"

mtd: Giving out device 2 to rootfs

3.4.2Redboot partition table parsing

The Redboot bootloader maintains a partition table that holds flash layout, so if you are using Redboot on your embedded device, you can configure your flash partitions in the bootloader.To do this, turn on CONFIG_MTD_REDBOOT_PARTSalong with the MTD partitioning support during kernel configuration.

3.4.3Flash partition map based on OF description

To create partitions from device tree enable CONFIG_MTD_OF_PARTS in the kernel configuration. The partitions have to be manually defined in the device tree. The map driver parses the device tree and creates partitions accordingly.

Ex:

FLASH_2Mx32: flash@80800000 {

bank-width = <4>;

compatible = "xlnx,xps-mch-emc-1.00.a", "cfi-flash";

reg = < 80800000 800000 >;

partition@0 {

label = "fs";

reg = <0 380000>;};

partition@380000 {

label = "firmware";

reg = <380000 480000>;

read-only;};

};

4Mounting jffs2 filesystem on the MTD device

To mount any filesystem, first enable support for that filesystem in the kernel configuration. The procedure for mounting jffs2 filesystem is discussed here.

Use the mkfs.jffs2 utility (available from mtd-utilities) to create a jffs2 image of the directory you want to mount on to the flash device. The step-by-step procedure is listed below.

  • Erase the flash through the flash_eraseall utility (use the –j option).

flash_eraseall –j /dev/mtd0 – this formats the flash for jffs2 (assuming that /dev/mtd0 is your MTD device).

  • Create a jffs2 image of the directory you want to put under jffs2.

mkfs.jffs2 -d root_folder -o image_name

-e sector_erase_size

where, root_folder is the directory you want to put under jffs2

image_name is the name of the resultant jffs2 image

sector_erase_size is the sector erase size fo your flash device

  • Write the image on to the flash.

cat image_name > /dev/mtd0

  • Mount the jffs2 filesystem on to the flash.

mount -t jffs2 /dev/mtdblock0 /mnt/jffs2

Note the use of /dev/mtdblock0, NOT /dev/mtd0. "mount" needs a block device interface and /dev/mtdblock0, 1, 2, 3... are provided for that purpose. /dev/mtd0, 1, 2, 3 are char devices and are provided for things like copying the binary image onto the raw flash devices (create the /mnt/jffs2 directory if it doesn’t exist).

Once the filesystem is mounted, verify that the contents of the /mnt/jffs2 directory are same as the directory for which the jffs2 image has been created above. We can create/modifythe files within the /mnt/jffs2 directory and these changes will be reflected on to the flash.

More information on jffs2 filesystem can be found at and the FAQ page for JFFS2 on MTD website is at

5Unsorted Block Images (UBI)

UBI is a volume management system for the flash devices (specifically for NAND flash devices) which manages multiple logical volumes on a single flash device. A UBI volume is a set of consecutive logical eraseblocks. UBI maps logical erase blocks to physical erase blocks and implements wear-leveling and I/O error handling.

UBI volumes can be created statically or dynamically. Static volumes are read-only and their contents are protected by CRC. Dynamic volumes are read-write and the upper layer is responsible for data integrity. UBI volume size is specified when a volume is created and they are dynamically re-sizable.

UBI takes care of the I/O errors on the volumes and the upper layer is free from any error handling. UBI has a pool of reserved physical erase blocks and substitutes a bad physical erase block with a good one and moves the data from the newly appeared bad physical erase block to the good physical erase block.

Note: UBI currently doesn’t support flash devices with multiple erase regions.

To enable UBI support in your kernel, go to Kernel configuration -> Device Drivers -> MTD support -> UBI and select “Enable UBI” (CONFIG_MTD_UBI).To start of with, enable UBI debugging (CONFIG_MTD_UBI_DEBUG).

Figure 10 Enabling UBI support

Figure 11 Enabling UBI debug support