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}; '

results matching ""

    No results matching ""