Flash filesystems
Block devices vs flash devices
- Block devices:
- Allow for random data access using fixed size blocks
- Do not require special care when writing on the media
- Block size is relatively small (minimum 512 bytes, can be increased for performance reasons)
- Considered as reliable (if the storage media is not, some hardware or software parts are supposed to make it reliable)
- Flash devices:
- Allow for random data access too
- Require special care before writing on the media (erasing the region you are about to write on)
- Erase, write and read operation might not use the same block size
- Reliability depends on the flash technology
NAND flash chips
- Encode bits with voltage levels
- Start with all bits set to 1
- Programming implies changing some bits from 1 to 0
- Restoring bits to 1 is done via the ERASE operation
- Programming and erasing is not done on a per bit or per byte basis
Organization
- Page: minimum unit for PROGRAM operation
- Block: minimum unit for ERASE operation
NAND flash storage: constraints
- Reliability
- Far less reliable than NOR flash
- Reliability depends on the NAND flash technology (SLC, MLC)
- Require additional mechanisms to recover from bit flips: ECC (Error Correcting Code)
- ECC information stored in the OOB (Out-of-band area)
- Lifetime
- Short lifetime compared to other storage media
- Lifetime depends on the NAND flash technology (SLC, MLC): between 1000000 and 1000 erase cycles per block
- Wear leveling mechanisms are required
- Bad block detection/handling required too
- Despite the number of constraints brought by NAND they are widely used in embedded systems for several reasons:
- Cheaper than other flash technologies
- Provide high capacity storage
- Provide good performance (both in read and write access)
ECC (Error Correcting Code)
- ECC partly addresses the reliability problem on NAND flash
- Operates on blocks (usually 512 or 1024 bytes)
- ECC data are stored in the OOB area
- Three algorithms:
- Hamming: can fixup a single bit per block
- Reed-Solomon: can fixup several bits per block
- BCH: can fixup several bits per block
- BCH and Reed-Solomon strength depends on the size allocated for ECC data, which in turn depends on the OOB size
- NAND manufacturers specify the required ECC strength in their datasheets: ignoring these requirements might compromise data integrity
MTD (Memory Technology Devices)
- MTD stands for Memory Technology Devices
- Generic subsystem dealing with all types of storage media that are not fitting in the block subsystem
- Supported media types: RAM, ROM, NOR flash, NAND flash, Dataflash
- Independent of the communication interface (drivers available for parallel, SPI, direct memory mapping, ...)
- Abstract storage media characteristics and provide a simple API to access MTD devices
- MTD device characteristics exposed to users:
- erasesize: minimum erase size unit
- writesize: minimum write size unit
- oobsize: extra size to store metadata or ECC data
- size: device size
- flags: information about device type and capabilities
- Various kind of MTD users: file-systems, block device emulation layers, user space interfaces...
MTD partitioning
- MTD devices are usually partitioned
- It allows to use different areas of the flash for different purposes: read-only filesystem, read-write filesystem, backup areas, bootloader area, kernel area, etc.
- Unlike block devices, which contains their own partition table, the partitioning of MTD devices is described externally (don't want to put it in a flash sector which could become bad)
- Specified in the board Device Tree
- Hard-coded into the kernel code (if no Device Tree)
- Specified through the kernel command line
- Each partition becomes a separate MTD device
- Different from block device labeling (hda3, sda2)
- /dev/mtd1 is either the second partition of the first flash device, or the first partition of the second flash device
- Note that the master MTD device (the device those partitions belongs to) is not exposed in /dev
Definition of MTD partitions
The Device Tree is the standard place to define MTD partitions for platforms with Device Tree support. Example from arch/arm/boot/dts/omap3-igep.dtsi:
- U-Boot also provides a way to define MTD partitions on flash devices
- Named partitions are easier to use, and much less error prone than using offsets.
- U-Boot partition definitions can also be used by Linux too, eliminating the risk of mismatches between Linux and U-Boot.
- Use flash specific commands (detailed soon), and pass partition names instead of numerical offsets
- Example: nand erase.part
- Example: setenv mtdids nand0=omap2-nand.0 setenv mtdparts mtdparts=omap2-nand.0:512k(X-Loader)ro,1536k(U-Boot)ro,512k(Env),4m(Kernel),-(RootFS)
- This defines 5 partitions in the omap2-nand.0 device:
- 1st stage bootloader (512 KiB, read-only)
- U-Boot (1536 KiB, read-only)
- U-Boot environment (512 KiB)
- Kernel (4 MiB)
- Root filesystem (Remaining space)
- Partition sizes must be multiple of the erase block size. You can use sizes in hexadecimal too. Remember the below sizes: 0x20000 = 128k, 0x100000 = 1m, 0x1000000 = 16m
- ro lists the partition as read only
- is used to use all the remaining space.
- Details about the two environment variables needed by U-Boot:
mtdids attaches an mtdid to a flash device. setenv mtdids
= [, = ] - devid: U-Boot device identifier (from nand info or flinfo)
- mtdid: Linux mtd identifier. Displayed when booting the Linux kernel:
mtdparts defines partitions for the different devices setenv mtdparts mtdparts=
: [,partition] partition format: <size>@offset[ro]
Use the mtdparts command to setup the configuration specified by the mtdids and mtdparts variables
U-Boot: sharing partition definitions with Linux
Linux understands U-Boot's mtdparts partition definitions. Here is a recommended way to pass them from U-Boot to Linux:
- Define a bootargs_base environment variable: setenv bootargs_base console=ttyS0 root=....
- Define the final kernel command line (bootargs) through the
bootcmd environment variable:
setenv bootcmd 'setenv bootargs ${bootargs_base} ${mtdparts};
'
- Managing flash storage with Linux: http://free-electrons.com/blog/managing-flash-storage-with-linux/
- Documentation on the linux-mtd website: http://www.linux-mtd.infradead.org/
- Details about creating UBI and UBIFS images: http://free-electrons.com/blog/creating-flashing-ubi-ubifs-images/