The Memory Technology Devices (MTD) layer in the kernel is used to provide an abstraction layer for memory devices (most often, flash devices). This allows higher levels (such as filesystems like jffs or yaffs) to not care about the physical backing. It could be on a parallel NOR flash chip hooked up to the asynchronous memory bus, or a serial flash chip on the SPI bus, or a NAND flash chip hooked up a variety of ways.
The MTD homepage can be found at http://www.linux-mtd.infradead.org/.
There are a couple of layers in the MTD stack that you should be familiar with:
As you get lower down closer to the hardware, some pieces may be integrated or split out further. Unless you're writing a driver for a new chip, most things will be done “for you” already.
Many flash devices are already supported by the Linux kernel. To use any of them, you'll need these common options in your kernel configuration.
Device Drivers --->
Memory Technology Devices (MTD) --->
<*> Memory Technology Device (MTD) support
[*] Direct char device access to MTD devices
[*] Caching block device access to MTD devices
All options here are found under the MTD menu. The parent nodes have been omitted for brevity. Keep in mind that there is no restriction on using different flash types simultaneously (parallel and SPI and NAND and …).
Also keep in mind that these options only turn on drivers. They do not include the other half of the equation: board resources. Your board will have to declare appropriate resources in your Board Resources file. Consult other boards (such as the BF537-STAMP or BF548-EZKIT) for good examples.
Has a full address/data (memory) interface that allows random access to any location. It is block-erasable (many words will be erased at once), but is typically programmable as words or bytes at a time. Typically connected via the asynchronous memory bus.
To use this type of flash under Linux, you probably want these options:
RAM/ROM/Flash chip drivers --->
<*> Detect flash chips by Common Flash Interface (CFI) probe
<*> Support for Intel/Sharp flash chips
<*> Support for AMD/Fujitsu flash chips
<*> Support for RAM chips in bus mapping
<*> Support for ROM chips in bus mapping
Mapping drivers for chip access --->
<*> CFI Flash device in physical memory map
(the address/length options are ignored)
< > Generic uClinux RAM/ROM filesystem support
When the latter option is enabled, you'd get an extra ROMFS partition as mtdblock0. This may force an ext2 over INITRAMFS image upon make.
For the BF533-STAMP, you will also need:
Mapping drivers for chip access ---> [*] Support non-linear mappings of flash chips <*> Blackfin BF533-STAMP Flash Chip Support (0x7BB0) EBIU_AMBCTL For Flash (Bank 0) (0x7BB0) EBIU_AMBCTL For Flash (Bank 1) (0x7BB0) EBIU_AMBCTL For Flash (Bank 2) (0x7BB0) EBIU_AMBCTL For Flash (Bank 3)
For flash parts that also need some GPIOs to assist in addressing, you will want this driver:
Mapping drivers for chip access ---> [*] Support non-linear mappings of flash chips <*> GPIO-assisted Flash Chip Support
You will need some platform resources declared for this driver. See arch/blackfin/mach-bf537/boards/cm_bf537.c for an example.
A SPI-compatible interface as used for serial EEPROMs which provides a sequential read access. Densities tend to be higher, but access times are slower.
To use this type of flash under Linux, you probably want these options:
Mapping drivers for chip access ---> [*] Support non-linear mappings of flash chips < > Generic uClinux RAM/ROM filesystem support (disable this option) Self-contained MTD device drivers ---> <*> Support most SPI Flash chips (AT26DF, M25P, W25X, ...)
The ideal solution for applications requiring a large amount of data storage memory. The common densities are much larger such as sizes from 128Mbit (16Mbytes) to 8Gbit (1Gbyte), but requires bad block handling. May be connected via the asynchronous memory bus or a dedicated controller.
To use this type of flash under Linux, you probably want one of these options:
NAND Device Support ---> <*> NAND Flash device for BF537 STAMP board <*> Blackfin on-chip NAND Flash Controller driver [*] BF5XX NAND Hardware ECC <*> Support for generic platform NAND driver
Since each flash chip vendor designs their own communications protocol (for telling the chip to read/write/erase/protect regions of the flash), all of this logic is hidden away at the chip driver level. This presents to the next MTD layer a simple abstract interface of common operations. Higher levels can then write to this common interface and so work with a variety of flash chips without needing to change anything.
Nowadays, flash technologies in the same field tend to support the same instruction set (for example, CFI on parallel NOR flashes). This allows the same software chip driver to support a wide variety of arbitrary flash chips. You should, however, verify that the flash chip you're planning on using is actively supported before designing it into your board.
This also means that, unless you ignore the aforementioned advice, you probably will not need to write your own chip driver for an exotic flash part.
A mapping driver is used as the “glue” driver. It is used to manage how the flash device is actually hooked up to the processor. In other words, it facilitates communication between the Blackfin and the flash chip, but it does not know anything about the actual communication (since that is the job of the chip driver). This feature tends to be specific to parallel flash chips however. You could consider the SPI bus the “mapping driver” for serial NOR flashes, but you need not worry about that layer as there is a common SPI framework. NAND devices tend to be very board specific already, so each driver provides its own method/degree of board customization.
The mapping driver is also how the partition layout is tied to a specific device, but more on that in the next section.
One of the common (and simplest) mapping drivers is the physical mapping driver (physmap). This driver is used for any CFI compliant flash which is completely directly addressable on the memory bus. For example, if an asynchronous memory bank is dedicated to a flash chip and you can access it without any other assistance, this common mapping driver would be used.
Some examples of when a custom mapping driver will be needed:
The mapping driver allows you to hook every flash operation before calling down into the specific chip driver.
All mapping drivers are stored in the same location in linux-2.6.x/drivers/mtd/maps/. This may seem like an odd place for such a (usually) board-specific option, but it is how things are done. It also allows for mapping drivers which do very similar operations to be unified for multiple boards/architectures.
Often times, people do not want to use a flash device as just one big chunk of contiguous storage. Perhaps you want to store the bootloader, a kernel, a root filesystem, and reserve a small chunk for your own product-specific purpose. By defining a partition layout, you need not manage the storage yourself. The kernel will break up and enforce the specified boundaries for you. If you wanted, you could even mark some partitions with custom attributes (such as making a recovery partition as read-only).
Since this topic tends to be much easier to just copy and paste existing examples, please see the Board Examples section below.
While the MTD framework does sufficiently abstract the lower layers to allow you to format and use any file system type on flash media, you should only be using “flash friendly” file systems on them. Since flash media presents unique restrictions when compared to standard media (flash must be erased before writing, you have to erase/write in chunks rather than just bytes, limited number of erase/write cycles before flash goes bad, etc…), you should use a file system that is designed to work with these things in mind. Otherwise you risk arbitrary file system corruption or worse, premature flash failure.
Certainly any read-only file system (such as romfs or cramfs) would be OK as you only write it once, but if you want persistent backing (in other words, a writable file system), then you currently have two choices: jffs and yaffs. See the respective pages for more information on each type.
Not all boards will be shown, just a representative sampling. Keep in mind that the structures documented here are not the entire picture. The resources are often declared in a couple of related structures. Consult the relevant board resources file for the full picture.
For most devices, you can declare a partition table in a couple of ways:
Command line partition table parsingmtd_part_parser (not discussed here)The command line partition support is controlled via a kernel configuration option:
Device Drivers --->
Memory Technology Devices (MTD) --->
<*> Memory Technology Device (MTD) support
[*] MTD partitioning support
[*] Command line partition table parsing
Assuming you've enabled the kernel configuration option, you can override the default layout that is in the board resources by using the kernel command line. For example:
bootargs=mtdparts=FLASH-DRIVER:256k(uboot)ro,1792k(kernel),-(rootfs)
Replace the FLASH-DRIVER with whatever driver you are using. For the BF533-STAMP parallel flash, this will be bfin-async-flash. For the default physical mapping driver, this will be physmap-flash.0 (increment the number for each flash). For SPI flashes, replace with the driver name (such as m25p80 -- this is the driver name, not the type).
For the full command line syntax, consult the linux-2.6.x/drivers/mtd/cmdlinepart.c file. It will be documented at the top.
There are optional flags which can be set for each partition. The variable mask_flags can be set to (from linux-2.6.x/include/mtd/mtd-abi.h):
Assuming everything works out, you should see messages from the kernel about creating MTD partitions. The exact output is dependent on your partition table, but you should be able to gloss the details.
Here we see three partitions being setup for the parallel NOR flash (declared via the command line), two partitions for the SPI flash (declared via the board resources), and two partitions for the NAND flash (declared via the board resources).
3 cmdlinepart partitions found on MTD device physmap-flash.0 Creating 3 MTD partitions on "physmap-flash.0": 0x00000000-0x00040000 : "uboot" 0x00040000-0x00200000 : "kernel" 0x00200000-0x02000000 : "rootfs" m25p80 spi0.1: m25p16 (2048 Kbytes) Creating 2 MTD partitions on "m25p80": 0x00000000-0x00040000 : "bootloader" 0x00040000-0x00100000 : "linux kernel" Creating 2 MTD partitions on "NAND 256MiB 3,3V 8-bit": 0x00000000-0x00400000 : "Linux Kernel" 0x00400000-0x10000000 : "File System"
Pretty much all ADI boards use the Physical Mapping driver (physmap) to connect CFI compliant parallel NOR flashes. The only exceptions are the BF533-EZKit and BF533-STAMP.
This board has a non-CFI compliant flash which is unlikely to be used by customers in production. Please refer to other boards for examples applicable to your setup.
This board uses the bfin-async-flash mapping driver to allow simultaneous access of the flash and ethernet on the same asynchronous memory bank.
file: arch/blackfin/mach-bf533/boards/stamp.c
static struct mtd_partition stamp_partitions[] = { { .name = "bootloader(nor)", .size = 0x40000, .offset = 0, }, { .name = "linux kernel(nor)", .size = 0x180000, .offset = MTDPART_OFS_APPEND, }, { .name = "file system(nor)", .size = MTDPART_SIZ_FULL, .offset = MTDPART_OFS_APPEND, } };
file: arch/blackfin/mach-bf537/boards/stamp.c
static struct mtd_partition stamp_partitions[] = { { .name = "bootloader(nor)", .size = 0x40000, .offset = 0, }, { .name = "linux kernel(nor)", .size = 0x180000, .offset = MTDPART_OFS_APPEND, }, { .name = "file system(nor)", .size = 0x400000 - 0x40000 - 0x180000 - 0x10000, .offset = MTDPART_OFS_APPEND, }, { .name = "MAC Address(nor)", .size = MTDPART_SIZ_FULL, .offset = 0x3F0000, .mask_flags = MTD_WRITEABLE, } };
file: arch/blackfin/mach-bf548/boards/ezkit.c
static struct mtd_partition ezkit_partitions[] = { { .name = "bootloader(nor)", .size = 0x80000, .offset = 0, }, { .name = "linux kernel(nor)", .size = 0x400000, .offset = MTDPART_OFS_APPEND, }, { .name = "file system(nor)", .size = 0x1000000 - 0x80000 - 0x400000 - 0x8000 * 4, .offset = MTDPART_OFS_APPEND, }, { .name = "config(nor)", .size = 0x8000 * 3, .offset = MTDPART_OFS_APPEND, }, { .name = "u-boot env(nor)", .size = 0x8000, .offset = MTDPART_OFS_APPEND, } };
file: arch/blackfin/mach-bf561/boards/ezkit.c
static struct mtd_partition ezkit_partitions[] = { { .name = "bootloader(nor)", .size = 0x40000, .offset = 0, }, { .name = "linux kernel(nor)", .size = 0x1C0000, .offset = MTDPART_OFS_APPEND, }, { .name = "file system(nor)", .size = 0x800000 - 0x40000 - 0x1C0000 - 0x2000 * 8, .offset = MTDPART_OFS_APPEND, }, { .name = "config(nor)", .size = 0x2000 * 7, .offset = MTDPART_OFS_APPEND, }, { .name = "u-boot env(nor)", .size = 0x2000, .offset = MTDPART_OFS_APPEND, } };
The SPI resources (such as SPI chip select, DMA, byte-size, etc…) are declared like a normal SPI device. You can find information on this in the SPI document.
file: arch/blackfin/mach-bf527/boards/ezkit.c
static struct mtd_partition bfin_spi_flash_partitions[] = { { .name = "bootloader(spi)", .size = 0x00040000, .offset = 0, .mask_flags = MTD_CAP_ROM }, { .name = "linux kernel(spi)", .size = MTDPART_SIZ_FULL, .offset = MTDPART_OFS_APPEND, } };
file: arch/blackfin/mach-bf533/boards/stamp.c
static struct mtd_partition bfin_spi_flash_partitions[] = { { .name = "bootloader(spi)", .size = 0x00040000, .offset = 0, .mask_flags = MTD_CAP_ROM }, { .name = "linux kernel(spi)", .size = 0x180000, .offset = MTDPART_OFS_APPEND, }, { .name = "file system(spi)", .size = MTDPART_SIZ_FULL, .offset = MTDPART_OFS_APPEND, } };
file: arch/blackfin/mach-bf537/boards/stamp.c
static struct mtd_partition bfin_spi_flash_partitions[] = { { .name = "bootloader(spi)", .size = 0x00040000, .offset = 0, .mask_flags = MTD_CAP_ROM }, { .name = "linux kernel(spi)", .size = 0x180000, .offset = MTDPART_OFS_APPEND, }, { .name = "file system(spi)", .size = MTDPART_SIZ_FULL, .offset = MTDPART_OFS_APPEND, } };
file: arch/blackfin/mach-bf548/boards/ezkit.c
static struct mtd_partition bfin_spi_flash_partitions[] = { { .name = "bootloader(spi)", .size = 0x00080000, .offset = 0, .mask_flags = MTD_CAP_ROM }, { .name = "linux kernel(spi)", .size = MTDPART_SIZ_FULL, .offset = MTDPART_OFS_APPEND, } };
You could hook up a NAND flash via the asynchronous memory bank. We've created and documented such an example cf-ide-nand board. For Blackfins that include an on-chip NAND flash controller, you can just use that.
file: arch/blackfin/mach-bf537/boards/stamp.c
static struct mtd_partition bfin_plat_nand_partitions[] = { { .name = "linux kernel(nand)", .size = 0x400000, .offset = 0, }, { .name = "file system(nand)", .size = MTDPART_SIZ_FULL, .offset = MTDPART_OFS_APPEND, }, };
file: arch/blackfin/mach-bf548/boards/ezkit.c
static struct mtd_partition partition_info[] = { { .name = "bootloader(nand)", .offset = 0, .size = 0x80000, }, { .name = "linux kernel(nand)", .offset = MTDPART_OFS_APPEND, .size = 4 * 1024 * 1024, }, { .name = "file system(nand)", .offset = MTDPART_OFS_APPEND, .size = MTDPART_SIZ_FULL, }, };
A package called mtd-utils exists for managing all flash devices (such as erasing/dumping/testing). Please see the mtd-utils page for more information.
Additionally, each file system type (jffs and yaffs) includes its own set of utilities. Please consult each page for file system specific information.
Here we test performance of MTD devices using bonnie, with different I/O scheduler policies.
| Board Version | CCLK | SCLK | Kernel Version | Toolchain Version |
|---|---|---|---|---|
| BF548-EZKIT-1.3 - Rev 0.1 | 525MHz | 131MHz | 2.6.28-rc2-ADI-2009R1-pre-svn6005 | gcc 4.1.2 (svn) |
physmap platform flash device: 02000000 at 20000000 physmap-flash.0: Found 1 x16 devices at 0x0 in 16-bit bank physmap-flash.0: Found an alias at 0x1000000 for the chip at 0x0 Intel/Sharp Extended Query Table at 0x010A Intel/Sharp Extended Query Table at 0x010A Intel/Sharp Extended Query Table at 0x010A Intel/Sharp Extended Query Table at 0x010A Intel/Sharp Extended Query Table at 0x010A Using buffer write method Using auto-unlock on power-up/resume cfi_cmdset_0001: Erase suspend on write enabled erase region 0: offset=0x0,size=0x20000,blocks=127 erase region 1: offset=0xfe0000,size=0x8000,blocks=4 RedBoot partition parsing not available Using physmap partition information Creating 3 MTD partitions on "physmap-flash.0": 0x00000000-0x00040000 : "bootloader(nor)" 0x00040000-0x00440000 : "linux kernel(nor)" 0x00440000-0x01000000 : "file system(nor)" BF5xx on-chip NAND FLash Controller Driver, Version 1.2 (c) 2007 Analog Devices, Inc. bf5xx-nand bf5xx-nand.0: page_size=256, data_width=8, wr_dly=3, rd_dly=3 NAND device: Manufacturer ID: 0x20, Chip ID: 0xda (ST Micro NAND 256MiB 3,3V 8-bit) Creating 2 MTD partitions on "NAND 256MiB 3,3V 8-bit": 0x00000000-0x00400000 : "linux kernel(nand)" 0x00400000-0x10000000 : "file system(nand)" m25p80 spi0.1: m25p16 (2048 Kbytes) Creating 2 MTD partitions on "m25p80": 0x00000000-0x00040000 : "bootloader(spi)" 0x00040000-0x00200000 : "linux kernel(spi)" bfin-spi bfin-spi.0: Blackfin on-chip SPI Controller Driver, Version 1.0, regs_base@ffc00500, dma channel@4 bfin-spi bfin-spi.1: Blackfin on-chip SPI Controller Driver, Version 1.0, regs_base@ffc02300, dma channel@5 root:/> cat /proc/mtd dev: size erasesize name mtd0: 00040000 00020000 "bootloader(nor)" mtd1: 00400000 00020000 "linux kernel(nor)" mtd2: 00bc0000 00020000 "file system(nor)" mtd3: 00400000 00020000 "linux kernel(nand)" mtd4: 0fc00000 00020000 "file system(nand)" mtd5: 00040000 00010000 "bootloader(spi)" mtd6: 001c0000 00010000 "linux kernel(spi)"
root:/> echo "noop" > /sys/block/mtdblock4/queue/scheduler root:/> cat /sys/block/mtdblock4/queue/scheduler [noop] anticipatory cfq root:/> mount -t jffs2 /dev/mtdblock4 /mnt/ root:/> bonnie++ -u root -d /mnt/
Version 1.94 ------Sequential Output------ --Sequential Input- --Random-
Concurrency 1 -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
blackfin 300M 8 66 3114 91 3183 91 183 99 13805 75 943.3 84
Latency 2439ms 644ms 648ms 83999us 648ms 448ms
Version 1.94 ------Sequential Create------ --------Random Create--------
blackfin -Create-- --Read--- -Delete-- -Create-- --Read--- -Delete--
files /sec %CP /sec %CP /sec %CP /sec %CP /sec %CP /sec %CP
16 462 94 7599 100 493 93 542 98 8846 98 582 98
Latency 59999us 4000us 48000us 43999us 4000us 44000us
root:/> umount /mnt/ root:/> cat /sys/block/mtdblock4/queue/scheduler noop anticipatory [cfq] root:/> mount -t jffs2 /dev/mtdblock4 /mnt/ root:/> bonnie++ -u root -d /mnt/
Version 1.94 ------Sequential Output------ --Sequential Input- --Random-
Concurrency 1 -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
blackfin 300M 8 69 3113 91 3188 91 184 99 13714 74 939.0 83
Latency 2168ms 644ms 667ms 123ms 648ms 447ms
Version 1.94 ------Sequential Create------ --------Random Create--------
blackfin -Create-- --Read--- -Delete-- -Create-- --Read--- -Delete--
files /sec %CP /sec %CP /sec %CP /sec %CP /sec %CP /sec %CP
16 465 93 7627 99 522 98 547 98 9022 99 588 99
Latency 60000us 4000us 40000us 40000us 4000us 40000us
root:/> umount /mnt/ root:/> cat /sys/block/mtdblock4/queue/scheduler noop anticipatory [cfq] root:/> mount -t jffs2 /dev/mtdblock4 /mnt/ root:/> bonnie++ -u root -p 2 root:/> bonnie++ -u root -y s > out1 & root:/> bonnie++ -u root -y s > out2 &
root:/> cat out1
Version 1.94 ------Sequential Output------ --Sequential Input- --Random-
Concurrency 1 -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
blackfin 300M 4 32 1194 46 1213 47 91 49 7744 45 404.1 42
Latency 3988ms 687ms 503ms 147ms 448ms 471ms
Version 1.94 ------Sequential Create------ --------Random Create--------
blackfin -Create-- --Read--- -Delete-- -Create-- --Read--- -Delete--
files /sec %CP /sec %CP /sec %CP /sec %CP /sec %CP /sec %CP
16 260 48 2582 50 284 49 274 49 4546 50 297 49
Latency 68000us 24000us 324ms 47999us 27999us 52000us
root:/> cat out2
Version 1.94 ------Sequential Output------ --Sequential Input- --Random-
Concurrency 1 -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
blackfin 300M 4 32 1174 47 1207 48 90 50 7677 47 404.0 42
Latency 3780ms 700ms 456ms 140ms 448ms 467ms
Version 1.94 ------Sequential Create------ --------Random Create--------
blackfin -Create-- --Read--- -Delete-- -Create-- --Read--- -Delete--
files /sec %CP /sec %CP /sec %CP /sec %CP /sec %CP /sec %CP
16 255 46 1934 61 281 48 275 49 4481 49 292 50
Latency 64000us 27999us 332ms 47999us 27999us 52000us
root:/> umount /mnt/ root:/> cat /sys/block/mtdblock4/queue/scheduler [noop] anticipatory cfq root:/> mount -t jffs2 /dev/mtdblock4 /mnt/ root:/> bonnie++ -u root -p 2 root:/> bonnie++ -u root -y s > out1 & root:/> bonnie++ -u root -y s > out2 &
root:/> cat out1
Version 1.94 ------Sequential Output------ --Sequential Input- --Random-
Concurrency 1 -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
blackfin 300M 4 33 1170 48 1208 48 89 49 7937 45 403.0 43
Latency 4060ms 711ms 471ms 175ms 456ms 523ms
Version 1.94 ------Sequential Create------ --------Random Create--------
blackfin -Create-- --Read--- -Delete-- -Create-- --Read--- -Delete--
files /sec %CP /sec %CP /sec %CP /sec %CP /sec %CP /sec %CP
16 244 46 3810 50 282 50 261 48 4394 51 285 49
Latency 76000us 36000us 59999us 71999us 31999us 52000us
root:/> cat out2
Version 1.94 ------Sequential Output------ --Sequential Input- --Random-
Concurrency 1 -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
blackfin 300M 4 34 1190 48 1206 47 89 49 8074 46 403.3 42
Latency 4188ms 652ms 467ms 171ms 452ms 532ms
Version 1.94 ------Sequential Create------ --------Random Create--------
blackfin -Create-- --Read--- -Delete-- -Create-- --Read--- -Delete--
files /sec %CP /sec %CP /sec %CP /sec %CP /sec %CP /sec %CP
16 245 46 3817 50 286 49 261 48 4409 49 280 49
Latency 76000us 35999us 51999us 67999us 35999us 51999us
root:/> umount /mnt/ root:/> cat /sys/block/mtdblock4/queue/scheduler noop [anticipatory] cfq root:/> mount -t jffs2 /dev/mtdblock4 /mnt/ root:/> bonnie++ -u root -p 2 root:/> bonnie++ -u root -y s > out1 & root:/> bonnie++ -u root -y s > out2 &
root:/> cat out1
Version 1.94 ------Sequential Output------ --Sequential Input- --Random-
Concurrency 1 -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
blackfin 300M 4 33 1175 47 1205 47 89 49 7841 45 403.9 41
Latency 3739ms 672ms 495ms 148ms 644ms 484ms
Version 1.94 ------Sequential Create------ --------Random Create--------
blackfin -Create-- --Read--- -Delete-- -Create-- --Read--- -Delete--
files /sec %CP /sec %CP /sec %CP /sec %CP /sec %CP /sec %CP
16 248 46 3828 50 286 50 270 49 4535 50 284 48
Latency 80000us 35999us 56000us 43999us 28000us 56000us
root:/> cat out2
Version 1.94 ------Sequential Output------ --Sequential Input- --Random-
Concurrency 1 -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
blackfin 300M 4 33 1171 47 1207 47 89 49 8198 47 402.8 43
Latency 3819ms 679ms 504ms 128ms 456ms 551ms
Version 1.94 ------Sequential Create------ --------Random Create--------
blackfin -Create-- --Read--- -Delete-- -Create-- --Read--- -Delete--
files /sec %CP /sec %CP /sec %CP /sec %CP /sec %CP /sec %CP
16 248 46 3799 50 283 48 271 49 4481 49 289 49
Latency 64000us 35999us 60000us 51999us 35999us 48000us
root:/> echo "noop" > /sys/block/mtdblock4/queue/scheduler root:/> cat /sys/block/mtdblock4/queue/scheduler [noop] anticipatory cfq root:/> flash_eraseall /dev/mtd4 root:/> mount -t yaffs2 /dev/mtdblock4 /mnt/ root:/> bonnie++ -u root -d /mnt -s 200M
Version 1.94 ------Sequential Output------ --Sequential Input- --Random-
Concurrency 1 -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
blackfin 200M 49 99 3598 66 2005 60 181 98 5408 46 373.2 76
Latency 164ms 644ms 672ms 64000us 663ms 459ms
Version 1.94 ------Sequential Create------ --------Random Create--------
blackfin -Create-- --Read--- -Delete-- -Create-- --Read--- -Delete--
files /sec %CP /sec %CP /sec %CP /sec %CP /sec %CP /sec %CP
16 108 97 3957 77 475 60 107 97 6918 99 242 80
Latency 24000us 16000us 19999us 20000us 4000us 23999us
root:/> echo "noop" > /sys/block/mtdblock2/queue/scheduler root:/> cat /sys/block/mtdblock2/queue/scheduler [noop] anticipatory cfq root:/> mount -t jffs2 /dev/mtdblock2 /mnt/ root:/> bonnie++ -u root -d /mnt -n 0 -f
Version 1.94 ------Sequential Output------ --Sequential Input- --Random- Concurrency 1 -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 blackfin 300M 1857 97 604 99 13578 78 43.1 99 Latency 652ms 463ms 652ms 483ms
root:/> cat /sys/block/mtdblock2/queue/scheduler noop [anticipatory] cfq root:/> bonnie++ -u root -d /mnt -n 0 -f
Version 1.94 ------Sequential Output------ --Sequential Input- --Random- Concurrency 1 -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 blackfin 300M 1817 97 608 99 13928 78 43.3 99 Latency 652ms 463ms 648ms 580ms
root:/> echo "cfq" > /sys/block/mtdblock2/queue/scheduler root:/> cat /sys/block/mtdblock2/queue/scheduler noop anticipatory [cfq] root:/> umount /mnt/ root:/> mount -t jffs2 /dev/mtdblock2 /mnt/ root:/> bonnie++ -u root -d /mnt -n 0 -f
Version 1.94 ------Sequential Output------ --Sequential Input- --Random- Concurrency 1 -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 blackfin 300M 1847 97 610 99 13516 78 44.0 99 Latency 652ms 468ms 652ms 568ms
root:/> bonnie++ -u root -d /mnt -f -n 0 -s 40M
Version 1.94 ------Sequential Output------ --Sequential Input- --Random- Concurrency 1 -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 blackfin 40M 1607 69 1012 57 70620 100 548.9 57 Latency 11999us 1359ms 4000us 96000us
root:/> bonnie++ -u root -d /mnt -f -n 0 -s 40M
Version 1.94 ------Sequential Output------ --Sequential Input- --Random- Concurrency 1 -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 blackfin 40M 1608 70 976 55 62439 99 467.7 53 Latency 11999us 1292ms 4000us 79999us
root:/> bonnie++ -u root -d /mnt -f -n 0 -s 40M
Version 1.94 ------Sequential Output------ --Sequential Input- --Random- Concurrency 1 -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 blackfin 40M 1615 69 979 55 66064 94 374.2 45 Latency 8000us 1359ms 7999us 76000us
Note The Input speed may be invalid. Since there is only 2MB SPI flash on BF548-Ezkit, the file size cannot be very large. According to bonnie++, file size should double RAM size in order to get a good result.
Output: 1.5 MB/s, Input: 6.7 MB/s
root:/> mount -t jffs2 /dev/mtdblock6 /mnt/ root:/> time dd conv=fsync if=/dev/zero of=/mnt/10m.bin bs=1M count=10 10+0 records in 10+0 records out real 0m 6.46s user 0m 0.00s sys 0m 4.53s root:/> umount /mnt/ root:/> mount -t jffs2 /dev/mtdblock6 /mnt/ root:/> time cp /mnt/10m.bin /var/ real 0m 1.49s user 0m 0.02s sys 0m 0.91s
| Board Version | CCLK | SCLK | Kernel Version | Toolchain Version |
|---|---|---|---|---|
| BF527-EZKIT-2.0 - Rev 0.2 | 525MHz | 131MHz | 2.6.28-7-ADI-2009R1-pre-svn6167 | gcc 4.1.2 (svn) |
Comparing the sequential output/input result, we can see HW ECC has performance advantage over SW ECC.
root:/> bonnie++ -u root -d /mnt/
Version 1.94 ------Sequential Output------ --Sequential Input- --Random-
Concurrency 1 -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
blackfin 300M 5 24 1023 91 1032 90 207 99 7704 75 341.4 43
Latency 2364ms 84000us 131ms 51999us 652ms 527ms
Version 1.94 ------Sequential Create------ --------Random Create--------
blackfin -Create-- --Read--- -Delete-- -Create-- --Read--- -Delete--
files /sec %CP /sec %CP /sec %CP /sec %CP /sec %CP /sec %CP
16 260 91 6150 100 279 95 278 93 7728 99 278 96
Latency 71999us 8000us 47999us 52000us 4000us 43999us
root:/> bonnie++ -u root -d /mnt/
Version 1.94 ------Sequential Output------ --Sequential Input- --Random-
Concurrency 1 -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
blackfin 300M 7 66 994 97 1024 97 202 99 5787 91 483.8 99
Latency 2080ms 43999us 75999us 119ms 655ms 492ms
Version 1.94 ------Sequential Create------ --------Random Create--------
blackfin -Create-- --Read--- -Delete-- -Create-- --Read--- -Delete--
files /sec %CP /sec %CP /sec %CP /sec %CP /sec %CP /sec %CP
16 266 92 5979 100 297 99 274 97 7515 100 292 99
Latency 43999us 8000us 43999us 43999us 4000us 52000us