Search by Tags

eMMC (Linux)

 

Subscribe for this article updates

Introduction

Embedded MultiMediaCard, usually referred to as eMMC or e.MMC, is a solid-state storage standard derived from the MMC standard. Formerly maintained by the MMC Association (MMCA), it is now the responsibility of JEDEC. The standard may have extensions, such as the e.MMC Security Extension.

In a short summary, an eMMC device is a raw NAND chip with an integrated controller that abstracts concepts such as wear levelling and ECC. For more information about flash technologies, check our additional resources:

The eMMC is an evolving standard. As of January 2019, JEDEC published the document JESD84-B51A: Embedded MultiMediaCard (e.MMC), Electrical Standard (5.1A), a.k.a eMMC 5.1A.

This article goes through:

  • Storage and Partitioning: considerations on how the eMMC devices are currently used in the Toradex BSP by default, as well as considerations about disk size and free space, and means to clone or erase the eMMC.
  • Configuration and Monitoring: how to get and set eMMC parameters by either using open-source software (mainly mmc-utils) and vendor-specific software (e.g. emmcparm from Micron). The section is divided by topics of interest, as for instance flash health status, pSLC and reliable write.

Prerequisites

You need a module with eMMC. A summary table of eMMC-based modules is provided below:

Family Modules eMMC Capacity (GB) Technology
Apalis TK1 2GB 16 8-bit MLC
Apalis iMX6Q 2GB IT
iMX6Q 1GB
iMX6D 1GB IT
iMX6D 512MB
4 8-bit MLC
Apalis T30 1GB
T30 1GB IT
4 8-bit MLC
Apalis T30 2GB 8 8-bit MLC
Colibri iMX7D 1GB 4 8-bit MLC
Colibri iMX6S 256MB
iMX6S 256MB IT
iMX6DL 512MB
iMX6DL 512MB IT
4 8-bit MLC
Colibri T30 1GB
T30 1GB IT
4 8-bit MLC

Storage and Partitioning

The eMMC standard provides an interface in which the device is seen and treated as a block device by Linux. As an implication, any file system used in HDDs and SSDs can be employed on eMMC devices. On the other hand, eMMC is widely different from those and its peculiarities must be taken into consideration when choosing and configuring the file system.

As of the embedded Linux BSP 2.7b4, Toradex switched from using ext3 to ext4 by default, therefore ext4 is the current file system adopted in our BSP.

The eMMC device has a boot area, which is seen as a different block device than the regular user area. It is a vendor specific area that uses an underlying storage technology more reliable than the user area, for instance SLC or pSLC instead of MLC.

The default partitioning scheme of an eMMC-based Toradex module is as follows:

eMMC boot area:

  • Raw partition - U-Boot bootloader and environment, Toradex factory configuration block.
  • Raw partition - RPMB area.

eMMC user area:

  • FAT32 partition - Kernel and device tree.
  • EXT-4 partition - Root file system.

Consideration About Disk Size and Free Space

Note: Following information is from a Colibri iMX6S 256MB IT V1.1A with embedded Linux BSP 2.8b5.

You can use the command fdisk to see the partitioning scheme:

root@colibri-imx6:~# fdisk -l
Disk /dev/mmcblk0: 3850 MB, 3850371072 bytes
4 heads, 16 sectors/track, 117504 cylinders
Units = cylinders of 64 * 512 = 32768 bytes
Device Boot Start End Blocks Id System
/dev/mmcblk0p1 129 640 16384 c Win95 FAT32 (LBA)
/dev/mmcblk0p2 641 117504 3739648 83 Linux
Disk /dev/mmcblk0boot1: 16 MB, 16777216 bytes
4 heads, 16 sectors/track, 512 cylinders
Units = cylinders of 64 * 512 = 32768 bytes
Disk /dev/mmcblk0boot1 doesn't contain a valid partition table
Disk /dev/mmcblk0boot0: 16 MB, 16777216 bytes
4 heads, 16 sectors/track, 512 cylinders
Units = cylinders of 64 * 512 = 32768 bytes
Disk /dev/mmcblk0boot0 doesn't contain a valid partition table

From the above output, notice that boot area does not have a partition table. In addition, the user area size is 3850371072 bytes, being 16777216 bytes for the kernel and device tree partition and 3829399552 bytes for the root file system. Alternatively, one could get the block devices and partition sizes using the command lsblk:

root@colibri-imx6:~# lsblk -b /dev/mmcblk0
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
mmcblk0 179:0 0 3850371072 0 disk
├─mmcblk0p1 179:1 0 16777216 0 part /media/mmcblk0p1
└─mmcblk0p2 179:2 0 3829399552 0 part /
root@colibri-imx6:~# lsblk -b /dev/mmcblk0boot0
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
mmcblk0boot0 179:8 0 16777216 1 disk
root@colibri-imx6:~# lsblk -b /dev/mmcblk0boot1
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
mmcblk0boot1 179:16 0 16777216 1 disk

Using the command df, you'll notice that the size reported by the file systems is slightly smaller than the user area partitions:

root@colibri-imx6:~# df
Filesystem 1K-blocks Used Available Use% Mounted on
/dev/root 3615352 488560 2923428 14% /
devtmpfs 58644 4 58640 0% /dev
tmpfs 124692 0 124692 0% /dev/shm
tmpfs 124692 396 124296 0% /run
tmpfs 124692 0 124692 0% /sys/fs/cgroup
tmpfs 124692 4 124688 0% /tmp
tmpfs 124692 0 124692 0% /var/volatile
/dev/mmcblk0p1 16116 5179 10937 32% /media/mmcblk0p1
tmpfs 24936 0 24936 0% /run/user/0

From the command above the total size of the kernel and device tree partition is 16502784 bytes and the root file system is 3702120448 bytes. This reports the actual usable space for each partition and happens due to file system overhead - things such as the inode table and file system journal.

Erase

There is a specific article for this topic:

Clone Contents

Even though discouraged, it is possible to copy the eMMC contents for backup or replication purposes. There is a specific article for this topic:

Configuration and Monitoring

The Linux kernel provides a tool chest for configuring MMC devices from user space named mmc-utils. A downstream version from Chromium OS is integrated out-of-the-box in the Toradex BSPs.

If you want to use the upstream version, it can be easily built using OpenEmbedded. Both variants (upstream and downstream) can be built and installed concurrently in the same image, due to update-alternatives support.

Mmc-utils makes it possible to query information from the device as well as configure features. Some examples are health status, enhanced user area, write reliability, sanitize, cache and write protection. Use the command help to list all available features:

mmc --help

Flash manufacturers may provide their own eMMC tools. For instance Micron releases the emmcparm tool periodically. It can be obtained from the Micron website, though you must register and request access to it. Once you have it deployed to the module, set the execute flag of the binary and run it without parameters to display the help:

Note: For a better understanding of emmcparm, browse Micron's website for the technical note TN-FC-25 - Understanding Linux Driver Support for e.MMC

chmod +x emmcparm_arm
./emmcparm_arm

The following sections go through some of the available commands of mmc-utils and emmcparm.

Health Status

Health status can be generic - as defined in the eMMC standard - or vendor specific. It is related to the concepts of raw NAND flash technology, such as SLC vs. MLC, eraseblock count, spare eraseblocks and erase cycles.

In a short summary, from the health perspective, the eMMC can be seen as an array of physical blocks - so-called eraseblocks - that have an average lifetime. The lifetime is measured by the amount of erase operations to a single block - the eraseblock count - and for MLC NAND technology it varies from 3000 to 10000 cycles depending on the trace width in nanometers.

A raw lifetime estimation could be stated as size of block * number of blocks * number of erase operations before eraseblock wears out. For instance, theoretically an eMMC with 1024 blocks - each having 4MiB and 3000 erases per block - can store up to 4MiB * 1024 * 3000 = 12000GiB or 12TiB. Notice that this is an inaccurate estimation due to the various caching mechanisms of Linux as well as the practical aspects of NAND operation, which for instance contribute to write amplification.

Note: You may find more information about flash memory in the extra material pointed to in this article's introduction.

Health Status as Defined in the eMMC 5.0 Standard Onwards

Since e.MMC 5.0, device health status became part of the standard. It provides life time estimation for SLC and MLC areas as well as pre EOL status:

  • Device life time estimation type A: life time estimation for SLC eraseblocks, provided in steps of 10%, e.g.:
    • 0x02 means 10%-20% device life time used.
  • Device life time estimation type B: life time estimation for MLC eraseblocks, provided in steps of 10%, e.g.:
    • 0x02 means 10%-20% device life time used.
  • Pre EOL information: overall status for reserved blocks. Possible values are:
    • 0x00 - Not defined.
    • 0x01 - Normal: consumed less than 80% of the reserved blocks.
    • 0x02 - Warning: consumed 80% of the reserved blocks.
    • 0x03 - Urgent: consumed 90% of the reserved blocks.

Warning: Depending on the computer on module and its version, the eMMC standard may be prior to 5.0 and thus not have the generic life time estimation available.

First, check the eMMC standard version:

root@colibri-imx6:~# mmc extcsd read /dev/mmcblk0 | head -n 3
=============================================
  Extended CSD rev 1.7 (MMC 5.0)
=============================================

Then you can get the health status from the Extended CSD register (ECSD), which can be parsed by the command mmc extcsd read <device>, for instance:

root@colibri-imx6:~# mmc extcsd read /dev/mmcblk0
...
Device life time estimation type B [DEVICE_LIFE_TIME_EST_TYP_B: 0x01]
 i.e. 0% - 10% device life time used
Device life time estimation type A [DEVICE_LIFE_TIME_EST_TYP_A: 0x02]
 i.e. 10% - 20% device life time used
Pre EOL information [PRE_EOL_INFO: 0x01]
 i.e. Normal
...
 
root@colibri-imx6:~# mmc extcsd read /dev/mmcblk0 | grep -A 1 LIFE
Device life time estimation type B [DEVICE_LIFE_TIME_EST_TYP_B: 0x01]
 i.e. 0% - 10% device life time used
Device life time estimation type A [DEVICE_LIFE_TIME_EST_TYP_A: 0x02]
 i.e. 10% - 20% device life time used
 
root@colibri-imx6:~# mmc extcsd read /dev/mmcblk0 | grep -A 1 EOL
Pre EOL information [PRE_EOL_INFO: 0x01]
 i.e. Normal

Vendor Specific

Vendor-specific health status may be available in eMMC devices. The best way to understand what is available is to go through the vendor documentation, since they may provide instructions or utilities for retrieving the information from the device.

Note: Even eMMCs compliant to standards prior to eMMC 5.0 may have vendor specific health status information.

Micron

Micron is an eMMC manufacturer that provides specific information about the health status of some of its parts. Below is a list of Toradex modules equipped with Micron eMMCs that both comply to the eMMC 5.0 standard and have additional vendor-specific health information:

Computer on Module Version
Apalis iMX6Q 2GB IT V1.1C
Apalis iMX6Q 1GB V1.1B
Apalis iMX6D 1GB IT V1.1B
Apalis iMX6D 512MB V1.1B
Apalis T30 1GB V1.1B
Apalis T30 1GB IT V1.1B
Colibri iMX7D 1GB V1.1A
Colibri iMX6S 256MB V1.1A
Colibri iMX6S 256 MB IT V1.1A
Colibri iMX6D 512MB V1.1A
Colibri iMX6D 512MB IT V1.1A

Note: For a better understanding of this section, browse Micron's website for the technical note TN-FC-32 - e.MMC Device Health Report

There are two possibilities for retrieving the vendor-specific data:

  • Using emmcparm, a binary command-line tool provided by Micron.
  • Implementing it by yourself based in Micron's documentation.

Below we illustrate the output of some emmcparm commands related to flash health.

  • Get the number of spare blocks and its usage:
root@colibri-imx6:~/emmcparm_4.3.0/bin# ./emmcparm_arm --spare_block
Device file = /dev/mmcblk0
EXT_CSD revision [192] = 1.7 (for MMC v5.0x)     
 
Feature name: Spare Block                      
 
Total spare block count: 72
Used spare blocks[%]: 0.00
  • Get the number of initial (from factory) and later bad blocks:
root@colibri-imx6:~/emmcparm_4.3.0/bin# ./emmcparm_arm --bad_block
Device file = /dev/mmcblk0
EXT_CSD revision [192] = 1.7 (for MMC v5.0x)     
 
Feature name: Bad Block                        
 
Total initial bad block count: 0
Total later bad block count  : 0
  • Get block erase count statistics:
root@colibri-imx6:~/emmcparm_4.3.0/bin# ./emmcparm_arm --erase_count
Device file = /dev/mmcblk0
EXT_CSD revision [192] = 1.7 (for MMC v5.0x)     
 
Feature name: Erase Count     Min   |     Max |     Ave
Global erase count:            1   |    1689    |     619
Enhanced area (SLC):             1   |     687    |     567
Normal area (MLC):               1   |    1689    |    1441
  • Get block erase count detailed per-block information:
root@colibri-imx6:~/emmcparm_4.3.0/bin# ./emmcparm_arm --sect_count
Device file = /dev/mmcblk0
EXT_CSD revision [192] = 1.7 (for MMC v5.0x)     
 
Feature name: Block Erase Count                
Block#    Erase#  Type
74 1689    - 
96 1654    - 
49 1689    - 
95 1689    -
...

Enhanced User Area and Pseudo SLC

Enhanced User Area, also referred to as enhanced storage is a mode defined in the eMMC 4.4 (MMCA 4.4) standard onwards in which the user area of the eMMC can be configured, which is meant to make that area more reliable and present better performance. How manufacturers do implement the Enhanced User Area is not defined in the standard, though. If the device supports this configuration, then the boot and RPMB area partitions must be configured as enhanced storage by default.

Note: As of the beginning of 2019, almost all eMMCs in production support Enhanced User Area, thus they have boot and RPMB partitions with this configuration enabled by default.

Pseudo SLC, also known as pSLC, is a configuration of the MLC NAND flash memory that uses half of the cells capacity - that is, instead of 2 bits per cell, uses 1 bit per cell - to improve the reliability, performance and endurance of the eMMC. In practice, the pSLC mode is in-between SLC and MLC.

A few remarks about enhanced mode are presented below:

  • Enhanced storage is a concept, whereas pSLC is an implementation.
  • pSLC is a means to implement enhanced storage.
  • Sometimes the terms pSLC and enhanced storage are used interchangeably, but unless explicitly stated by the eMMC manufacturer, there is no way of knowing that they really use pSLC as the underlying implementation.
  • It isn't very straightforward to find information about which implementation is used for enhanced storage in the vendor datasheets.
  • One can select memory regions to configure as enhanced storage. There is no need to configure the whole eMMC user area as enhanced area.
  • Programming a memory region to enhanced storage is a one-time operation. That means it cannot be reverted.
  • Over-provisioning of MLC is not as good as pSLC. The former does not provide any advantage in performance nor reliability, while the latter gives an endurance factor greater than 2.

Configure eMMC Enhanced User Area

Attention: Some of the commands from this section are one-time only operations. That means they cannot be reverted. Think carefully before executing any of them.

U-Boot has mmc commands, including the capability of hardware partitioning. This is what we need to configure the eMMC (or part of it) as enhanced storage. This section goes through how to do it:

Note: Following information is from a Colibri iMX6S 256MB IT V1.0B with embedded Linux BSP 2.8b5.

First of all, get the information about the size of the user area partition:

Colibri iMX6 # mmc info
Device: FSL_SDHC
Manufacturer ID: 11
OEM: 100
Name: 004GE 
Tran Speed: 52000000
Rd Block Len: 512
MMC version 5.0
High Capacity: Yes
Capacity: 3.7 GiB
Bus Width: 8-bit
Erase Group Size: 512 KiB
HC WP Group Size: 4 MiB
User Capacity: 3.7 GiB WRREL
Boot Capacity: 2 MiB ENH
RPMB Capacity: 512 KiB ENH

In the example above it is round to 3.7GiB and has write reliability switched on. The mmc hwpartition command can be used to get partition information as well as set enhanced storage. We can see the current configuration:

Colibri iMX6 # mmc hwpartition
Partition configuration:
    No enhanced user data area
    No GP1 partition
    No GP2 partition
    No GP3 partition
    No GP4 partition

Let's try to switch the whole partition to Enhanced User Area mode. We'll pass an option check that does not execute the operation right away, it only tests it and outputs the outcome as if we had actually done it. The size needs to be specified in 512 byte blocks and the area must be HC WP group size aligned:

Colibri iMX6 # mmc hwpartition user enh 0 7086080 check
Partition configuration:
        User Enhanced Start: 0 Bytes
        User Enhanced Size: 3.4 GiB
        No GP1 partition
        No GP2 partition
        No GP3 partition
        No GP4 partition
Total enhanced size exceeds maximum (865 > 472)
Failed!

It fails, informing the maximum size allowed in "HC WP group size", that is 472 * 4MiB = 1888MiB. Thus we need this value in 512 KiB blocks, which is 1888 * 1024 * 1024 / 512 = 3866624. Once you are sure about the value to use as well as the offset, use the complete option. We'll do it for the whole user are in the example below:

Note: The following command also configures write reliability as on, which is usually desired. Read the Reliable Write section before proceeding.

Colibri iMX6 # mmc hwpartition user enh 0 3866624 wrrel on complete
Partition configuration:
        User Enhanced Start: 0 Bytes
        User Enhanced Size: 1.8 GiB
        No GP1 partition
        No GP2 partition
        No GP3 partition
        No GP4 partition

Once you power-cycle, the changes take effect:

Colibri iMX6 # mmc info
Device: FSL_SDHC
Manufacturer ID: 11
OEM: 100
Name: 004GE 
Tran Speed: 52000000
Rd Block Len: 512
MMC version 5.0
High Capacity: Yes
Capacity: 1.8 GiB
Bus Width: 8-bit
Erase Group Size: 4 MiB
HC WP Group Size: 4 MiB
User Capacity: 1.8 GiB ENH WRREL
User Enhanced Start: 0 Bytes
User Enhanced Size: 1.8 GiB
Boot Capacity: 2 MiB ENH
RPMB Capacity: 512 KiB ENH

Performance of Enhanced User Area

Note: Following information is from a Colibri T30 IT V1.1A.

The Enhanced User Area is expected to be faster, if we assume that it is implemented as a pSLC area.

Check eMMC capacity before configuration:

Disk /dev/mmcblk0: 3.6 GiB, 3825205248 bytes, 7471104 sectors

Then configure the eMMC as enhanced storage:

mmc hwpartition user enh 0 3735552 wrrel on complete

Check eMMC capacity after configuration:

Disk /dev/mmcblk0: 1912 MB, 1912602624 bytes

It is exactly 50%, an indicator that it is in pSLC mode. Now we can compare the results of bonnie++ and dd to check write performance:

Before:

# bonnie++ -u 0 -d test/ -r 64 -s 256
...
Version 1.03e       ------Sequential Output------ --Sequential Input- --Random-
                    -Per Chr- --Block-- -Rewrite- -Per Chr- --Block-- --Seeks--
Machine        Size K/sec %CP K/sec %CP K/sec %CP K/sec %CP K/sec %CP  /sec %CP
colibri-t30    256M  7337  85 12856  36  9825  12 10721  96 395316  99 +++++ +++
                    ------Sequential Create------ --------Random Create--------
                    -Create-- --Read--- -Delete-- -Create-- --Read--- -Delete--
              files  /sec %CP  /sec %CP  /sec %CP  /sec %CP  /sec %CP  /sec %CP
                 16 15767  74 +++++ +++  5384  51 12167  72 +++++ +++  3310  43
 
 
# dd if=/dev/zero of=test.img bs=4k count=64k conv=fdatasync
65536+0 records in
65536+0 records out
268435456 bytes (268 MB) copied, 28.9241 s, 9.3 MB/s

After:

# bonnie++ -u 0 -d test/ -r 64 -s 256
...
Version 1.03e       ------Sequential Output------ --Sequential Input- --Random-
                    -Per Chr- --Block-- -Rewrite- -Per Chr- --Block-- --Seeks--
Machine        Size K/sec %CP K/sec %CP K/sec %CP K/sec %CP K/sec %CP  /sec %CP
colibri-t30    256M  8543  92 25778  50 19970  20 11414  97 +++++ +++ +++++ +++
                    ------Sequential Create------ --------Random Create--------
                    -Create-- --Read--- -Delete-- -Create-- --Read--- -Delete--
              files  /sec %CP  /sec %CP  /sec %CP  /sec %CP  /sec %CP  /sec %CP
                 16 18322  87 +++++ +++  7468  55 17804  84 +++++ +++  5994  44
 
 
# dd if=/dev/zero of=test.img bs=4k count=64k conv=fdatasync
65536+0 records in
65536+0 records out
268435456 bytes (268 MB) copied, 13.6078 s, 19.7 MB/s

Write Reliability

Write reliability is a configuration that affects what happens to data during an unexpected power-cut. When it is enabled, write operations are atomic at the eMMC level and after an unexpected power-cut data is either old or new, but never undefined. To check if it's on by default you can use the U-Boot mmc info command:

Colibri iMX6 # mmc info
Device: FSL_SDHC
Manufacturer ID: 11
OEM: 100
Name: 004GE 
Tran Speed: 52000000
Rd Block Len: 512
MMC version 5.0
High Capacity: Yes
Capacity: 3.7 GiB
Bus Width: 8-bit
Erase Group Size: 512 KiB
HC WP Group Size: 4 MiB
User Capacity: 3.7 GiB WRREL
Boot Capacity: 2 MiB ENH
RPMB Capacity: 512 KiB ENH

From the command above, notice on the line User Capacity: 3.7 GiB WRREL that the WRREL means write reliability is on. If you want to change such configuration, refer to the section Configure eMMC Enhanced User Area.

Note: For a better understanding of reliable write on Micron eMMC devices, browse Micron's website for the technical note TN-FC-27 - e.MMC Power Loss Data Integrity

Notice that Micron eMMCs have reliable write and partition protection features, which they claim to have the same level of protection.

Performance of Write Reliability

Note: Following information is from a Colibri iMX6S 256MB IT V1.1A with embedded Linux BSP 2.8b5.

For Micron eMMCs, TN-FC-27 has a plot of sequential write performance against chunk size, comparing the results for enabled and disabled partition protection. As expected, when protection is enabled the performance is worse. The chunk size range in which it is worst is between 32KB and 256KB. In addition, the same document states in its conclusion that "a sequential write with partition protection enabled has much better performance than a sequential reliable write".

Write reliability enabled (default):

root@colibri-imx6:~# mmc extcsd read /dev/mmcblk0 | grep WR_REL_SET
Write reliability setting register [WR_REL_SET]: 0x1f
 
root@colibri-imx6:~# mmc extcsd read /dev/mmcblk0 | grep WR_REL_PARAM
Write reliability parameter register [WR_REL_PARAM]: 0x05
root@colibri-imx6:~# hdparm -t /dev/mmcblk0
 
/dev/mmcblk0:
 Timing buffered disk reads: 240 MB in  3.02 seconds =  79.52 MB/sec
 
---------------------------
 
root@colibri-imx6:~# time dd if=/dev/zero of=test.img bs=4k count=64k
65536+0 records in
65536+0 records out
 
real    0m24.712s
user    0m0.170s
sys 0m3.310s
 
---------------------------
 
root@colibri-imx6:~# bonnie++ -u 0 -d test/ -r 64 -s 256
...
Version 1.03e       ------Sequential Output------ --Sequential Input- --Random-
                    -Per Chr- --Block-- -Rewrite- -Per Chr- --Block-- --Seeks--
Machine        Size K/sec %CP K/sec %CP K/sec %CP K/sec %CP K/sec %CP  /sec %CP
colibri-imx6   256M 10410  39 10722  11  8770  10 21446  78 80853  21  3947  28
                    ------Sequential Create------ --------Random Create--------
                    -Create-- --Read--- -Delete-- -Create-- --Read--- -Delete--
              files  /sec %CP  /sec %CP  /sec %CP  /sec %CP  /sec %CP  /sec %CP
                 16 11174  97 +++++ +++ 16064  95  8516  74 +++++ +++ 15768  96

Write reliability disabled:

root@colibri-imx6:~# mmc extcsd read /dev/mmcblk0 | grep WR_REL_SET
Write reliability setting register [WR_REL_SET]: 0x1e
 
root@colibri-imx6:~# mmc extcsd read /dev/mmcblk0 | grep WR_REL_PARAM
Write reliability parameter register [WR_REL_PARAM]: 0x05
root@colibri-imx6:~# hdparm -t /dev/mmcblk0
 
/dev/mmcblk0:
 Timing buffered disk reads: 238 MB in  3.02 seconds =  78.69 MB/sec
 
---------------------------
 
root@colibri-imx6:~# time dd if=/dev/zero of=test.img bs=4k count=64k
65536+0 records in
65536+0 records out
 
real    0m25.122s
user    0m0.060s
sys 0m4.050s
 
---------------------------
 
root@colibri-imx6:~# bonnie++ -u 0 -d test/ -r 64 -s 256
...
Version 1.03e       ------Sequential Output------ --Sequential Input- --Random-
                    -Per Chr- --Block-- -Rewrite- -Per Chr- --Block-- --Seeks--
Machine        Size K/sec %CP K/sec %CP K/sec %CP K/sec %CP K/sec %CP  /sec %CP
colibri-imx6   256M 10314  44 10348  12  8541  10 20840  76 80592  20  4066  28
                    ------Sequential Create------ --------Random Create--------
                    -Create-- --Read--- -Delete-- -Create-- --Read--- -Delete--
              files  /sec %CP  /sec %CP  /sec %CP  /sec %CP  /sec %CP  /sec %CP
                 16  6110  78 +++++ +++  3265  39  6172  77 +++++ +++  2449  31