Partition with multiple erasesize blocks

Angelos Manousarides amanous at inaccessnetworks.com
Mon Jun 26 07:15:53 EDT 2006


I have a PXA-based board with intel P30 flash, top type (4 small sectors at the
end, sized 0x10000, all the other flash large sectors sized 0x40000). I define
from command line the partition sizes, using command line ATAG. The entire
flash has size 0x4000000 (64MB), with two erase regions:

erase region 0: offset=0x0,size=0x40000,blocks=255
erase region 1: offset=0x3fc0000,size=0x10000,blocks=4

If I try this configuration:

3 cmdlinepart partitions found on MTD device mrg110-6
Creating 3 MTD partitions on "mrg110-6":
0x00000000-0x00040000 : "u-boot"
0x00040000-0x00280000 : "kernel"
0x00280000-0x04000000 : "filesystem"

The linux filesystem (last partition) does not behave correctly at the limit,
and I suspect that the problem arises when the last small sectors are used for
the first time. If I do this:

dd if=/dev/zero of=/foobar

The command hangs, and once I saw a driver crash in zlib() calls.

If I try this setup:

Creating 3 MTD partitions on "mrg110-6":
0x00000000-0x00040000 : "u-boot"
0x00040000-0x00280000 : "kernel"
0x00280000-0x03fc0000 : "filesystem"

Thus, using an address space with a single erase size, the above tests
completes successfully. The command finishes with a "out of space" error.

I added some printk()'s in the kernel and saw that in the first case a single
erase size is defined with is not right. This is not a surprise of course (code
from add_mtd_partitions(), drivers/mtd/mtdpart.c):

if (master->numeraseregions>1) {
    /* Deal with variable erase size stuff */
    int i;
    struct mtd_erase_region_info *regions = master->eraseregions;

    /* Find the first erase regions which is part of this partition. */
    for (i=0; i < master->numeraseregions && slave->offset >= regions[i].offset; i++)
        ;

    for (i--; i < master->numeraseregions && slave->offset + slave->mtd.size > regions[i].offset; i++) {
        if (slave->mtd.erasesize < regions[i].erasesize) {
            slave->mtd.erasesize = regions[i].erasesize;
        }
    }
} else {
    /* Single erase size */
    slave->mtd.erasesize = master->erasesize;
}


Shouldn't this code allocate and set the mtd->eraseregions accordingly, with
the proper size and offsets of the new partition?

My kernel is 2.6.13 with some stuff backported from 2.6.16 in order to support
the P30 chip, but I saw that even the latest mtd code has the exact same code
for add_mtd_partitions.

Even worse, for this board I want to support 4 chips in 2 flash banks with
mdtconcat, which means that I need not only the partition code to support
partitions with multiple erase regions, but the concat code to support multiple
erase regions as well. Is there any luck?

--
Angelos Manousaridis





More information about the linux-mtd mailing list