Flash wear-leveling in BSP 2.8.7

Is it possible to enable flash wear-leveling in BSP 2.8.7? How?

Hi, I’m the Toradex AI Assistant.

I might make mistakes or occasionally get you wrong. Our support team will step in if needed.


I’d be glad to help! To provide accurate guidance, could you let me know which hardware you are using and confirm the OS version?

For context, flash wear-leveling behavior differs depending on whether your module uses:

  • NAND-based storage (e.g., Colibri VF50, VF61, iMX7, T20)
  • eMMC-based storage (e.g., Colibri iMX6, T30, Apalis iMX6, T30, TK1)

Wear-Leveling Overview

For NAND-based devices:
On Linux, wear-leveling is handled by the UBI (Unsorted Block Images) subsystem(1). This layer sits between the hardware driver and the filesystem, managing wear-leveling and bad block management automatically(1).

For eMMC-based devices:
Wear-leveling is handled internally by the eMMC controller itself(2)(1). The eMMC device abstracts concepts such as wear-leveling and ECC (Error Correction Code)(2). Higher layers in the software stack don’t need to manage wear-leveling since it’s done by the eMMC hardware(1).

Once you confirm your hardware platform and OS version, I can provide more specific guidance on your setup.

Best regards, Toradex AI Assistant.


Did you like my answer? :+1: :-1:

If I answered your question, please tick the “Solution” checkbox.

For follow-up questions to me, please use @ToradexAI in your post.

The hardware platform is VF61 and it is using BSP 2.8.7

For the Colibri VF61 running BSP 2.8.7, wear-leveling is already enabled by default - you don’t need to manually enable it(1).

How Wear-Leveling Works on VF61

The Colibri VF61 uses SLC NAND flash(2)(1). On Linux BSP, the wear-leveling is automatically handled by the UBI (Unsorted Block Images) subsystem(1).

Here’s the software stack on your NAND-based device(1):

  1. Storage device: SLC NAND(2)(1)
  2. Hardware Driver: MTD (Memory Technology Device)(1)
  3. Wear leveling and Bad block management: UBI subsystem(1)
  4. Filesystem: UBIFS(1)

The UBI layer ensures that all flash cells are worn similarly and prevents always writing to the same cells(1). This wear-leveling algorithm is built into the UBI subsystem and operates automatically without requiring manual configuration(1).

Additional Flash Protection Features

Beyond wear-leveling, your VF61 setup also includes(1):

  • Error Correction Codes (ECC): Detects and corrects corrupted data(1)
  • Bad block management: Identifies and stops using worn-out blocks(1)
  • Power-cut tolerance: UBIFS provides power-fail protection(1)

Best Practices

To maximize flash lifetime on your VF61(1):

  • Reduce write access to the flash device
  • Monitor write behavior in your application
  • Avoid using the full storage capacity (partial usage improves wear-leveling efficiency)
  • Run stress tests to validate your expected product lifetime

The wear-leveling is working automatically in BSP 2.8.7 for your VF61 module, so no additional configuration is needed.

Best regards, Toradex AI Assistant.



Did you like my answer? :+1: :-1:

If I answered your question, please tick the “Solution” checkbox.

For follow-up questions to me, please use @ToradexAI in your post.

What if there would be 0 available PEBs because rootfs uses all available LEBs?

In that case, flash wear-leveling can not work, right?

UBIFS works with LEBs, while UBI manages the underlying PEBs. Even if the rootfs volume is configured to use most available LEBs, UBI should still keep enough reserved PEBs for wear leveling, bad-block handling, and internal operations. If there are truly no free/reserved PEBs left, UBI may not be able to replace newly failing blocks or perform proper wear leveling, which can lead to write failures or a read-only filesystem. Also, having only a very small number of available blocks reduces UBI’s ability to distribute writes evenly, which can lead to excessive wear on the remaining blocks.

If there are no PEBs free, how to free some PEBs?

To free PEBs back to UBI, you must shrink or delete a UBI volume. Deleting files inside UBIFS only frees space inside that filesystem; it does not reduce the UBI volume size or return PEBs to the UBI free pool.

For a non-root volume, the safe procedure is to back up the data, unmount the volume, then either remove and recreate it at a smaller size, or resize the UBI volume:

ubirsvol /dev/ubi0 -n <vol_id> -S <new_LEB_count>
ubirsvol /dev/ubi0 -n <vol_id> -s <new_size>

or remove it completely:

ubirmvol /dev/ubi0 -n <vol_id>

However, UBIFS cannot generally be shrunk in place safely. If the volume contains UBIFS data, back up the data first, unmount the volume, recreate the UBIFS filesystem with the desired smaller size, and restore the data.

If the oversized volume is the mounted rootfs, do not try to shrink it live. Boot from recovery/initramfs/another rootfs and recreate or reflash the UBI layout with a smaller rootfs volume.

Thank you for your reply.

How to do it in Yocto using the BSP 2.8.7 for vf61?

The ubirsvol command is used to resize an existing UBI volume on a flash storage device. The two commands I provided in my previous post are simply different ways to specify the new size for the volume.

Here is what each command does:

  • ubirsvol /dev/ubi0 -n <vol_id> -S <new_LEB_count> : This sets the new volume size by specifying the number of Logical Erase Blocks (LEBs) it should contain. The tool then automatically calculates the total size in bytes by multiplying this number by the LEB size of the underlying flash device.
  • ubirsvol /dev/ubi0 -n <vol_id> -s <new_size> : This sets the new volume size directly in bytes . You can also use common size suffixes like KiB , MiB , or GiB for convenience.

Both commands ultimately achieve the exact same result: they resize the specified volume to a new size. You must choose one method or the other.

It is crucial to understand that ubirsvol only resizes the UBI volume (the container). If that volume contains a filesystem like UBIFS, the filesystem itself will not be automatically resized. After resizing the volume, you will typically need to run the appropriate filesystem resize command (e.g., ubifsresize ) for the change to be fully usable.

You must be absolutely certain the new size is large enough to hold all existing data.

Thank you for your reply. I meant how to modify the script that creates the volume when installing a new image in order to leave some ELBs for flash wear-leveling. How to do this in the Yocto project of BSP 2.8.7? What is the default behaviour without doing any change?

VF are upgraded using U-Boot commands. run update doesn’t recreate rootfs volume if it already exists. You may try ubi part ubi; ubi remove rootfs, then recreate rootfs with ubi create rootfs. But if ubi part ubi reports PEBs reserved for bad PEB handling: 0, then, ghm, U-Boot has no commands to ubiformat MTD partition. You should boot from usb/SD/etc and call ubiformat /dev/mtd3, which will at least preserve existing UBI erase counters. If you don’t mind erase counters, then perhaps you could nand erase.part ubi, and then expect ubi part ubi reformattin blank MTD partition with non zero reserved PEBs.

Since BSP2,8,7, UBI received many improvements and bug fixes. Even without those fixes, at least you need running ubihealthd, which, I think, is missing in BSP2,8,7. It is supposed to find blocks with too many correctable ECC errors and move data to less weared blocks.

BTW, VF support for 32bit ECC (in some older than 2.8.6 BSP it was upgraded from weaker ECC) doesn’t take into account one nasty and not documented VF bug. 32bit ECC correction on erased flash pages claims that bit 5 at page offset 0x5FD is always 0, which is noticed by Linux drivers, and something like nanddump /dev/mtd3 > dev/null reports too many ECC bitflips, at least one for every erased flash page.