2009-06-15 06:44:58     Read/Write from mtd partition

Document created by Aaronwu Employee on Aug 15, 2013
Version 1Show Document
  • View in full screen mode

2009-06-15 06:44:58     Read/Write from mtd partition

Samuel Ayet (SPAIN)

Message: 75723   

 

Hi,

 

I'm using a BF537 - STAMP board with the 2008R1.5 dist. As I need to write some information (about 10kB stored in the paralel nor flash of 4Mb of the board), I'm trying to use a mtd partition to do it. I have noticed that last mtd partition (called "MAC Address") is 64kB and the MAC Adress uses only 6 Bytes. I have made a new partition of 64 kBytes - 6 Bytes in the /uClinux-dist-2008R1.5-RC3/linux-2.6.x/arch/blackfin/mach-bf537/boards/stamp.c. To do this, I have resized the "MAC Address" partition and added a new one and the partitions of the stamp.c now looks like this:

 

 

 

static struct mtd_partition stamp_partitions[] = {

    {

    //mtdblock0

        .name       = "Bootloader",

        .size       = 0x40000,

        .offset     = 0,

    }, {

    //mtdblock1

        .name       = "Kernel",

        .size       = 0xE0000,

        .offset     = MTDPART_OFS_APPEND,

    }, {

    //mtdblock2

        .name       = "RootFS",

        .size       = 0x400000 - 0x40000 - 0xE0000 - 0x10000,

        .offset     = MTDPART_OFS_APPEND,

    }, {

    //mtdblock3

        .name       = "MAC Address",

        .size       = 0x06,

        .offset     = 0x3F0000,

        .mask_flags = MTD_WRITEABLE,

    }, {

    //mtdblock4

        .name       = "Configuration Data",

        .size       = 0x10000-0x06,

        .offset     = 0x3F0006,

         .mask_flags = MTD_WRITEABLE,

    }

    

};

 

 

 

The problem I'm having is that I don't have permission (Permission Denied Error) to write to the last parttion so I can't write directly to the mtd or erase it and mount a file system thus I can't save my configuration file while running. I thought that the 'mask_flags = MTD_WRITEABLE' will be the flag that will make the mtd partition writeable, but I think I'm wrong. I'm not suere where the flash is protected (by hardware?, by u-boot?, by kernel?) and where I must unprotect it. Some advice?

 

 

 

Thank you!

QuoteReplyEditDelete

 

 

2009-06-15 06:51:47     Re: Read/Write from mtd partition

Mike Frysinger (UNITED STATES)

Message: 75724   

 

you have the logic inverted.  "mask_flags" means "flags to mask off".  i.e. flags that will always be ignored.  so there is no way for those partitions to be writable.

QuoteReplyEditDelete

 

 

2009-06-15 08:38:53     Re: Read/Write from mtd partition

Samuel Ayet (SPAIN)

Message: 75726   

 

Ok. I invert my logic. If I don't mask the flags with the MTD_WRITABLE mask, will I have permission to write? I mean this:

 

static struct mtd_partition stamp_partitions[] = {

    {

    //mtdblock0

        .name       = "Bootloader",

        .size       = 0x40000,

        .offset     = 0,

    }, {

    //mtdblock1

        .name       = "Kernel",

        .size       = 0xE0000,

        .offset     = MTDPART_OFS_APPEND,

    }, {

    //mtdblock2

        .name       = "RootFS",

        .size       = 0x400000 - 0x40000 - 0xE0000 - 0x10000,

        .offset     = MTDPART_OFS_APPEND,

    }, {

    //mtdblock3

        .name       = "MAC Address",

        .size       = 0x06,

        .offset     = 0x3F0000,

        //flags deleted

    }, {

    //mtdblock4

        .name       = "Configuration Data",

        .size       = 0x10000-0x06,

        .offset     = 0x3F0006,

        //flags deleted

    }

    

};

 

 

I have tryed this (with my logic inverted) but the same error -> "Permission Denied"

 

"so there is no way for those partitions to be writable."

 

No way? It's impossible? Couldn't I make a partition writeable? Do I need to use other memory to store my configuration file?

 

 

 

Thank you Mike!

QuoteReplyEditDelete

 

 

2009-06-15 08:54:03     Re: Read/Write from mtd partition

Mike Frysinger (UNITED STATES)

Message: 75727   

 

you really should use MTDPART_OFS_APPEND for .offset ...

 

at any rate, if you're sure you rebuilt and booted the kernel with .mask_flags removed, post the exact commands you're using to manage the partitions

QuoteReplyEditDelete

 

 

2009-06-15 09:47:29     Re: Read/Write from mtd partition

Jean-Christian de Rivaz (SWITZERLAND)

Message: 75728   

 

Maybe the size of the mtdblock3 partition are don't fit the boundary of a erase block of the NOR flash. MTD subsystem disable write on partition that don't fit into the erase block boundary. Check Linux kernel initialization log.

QuoteReplyEditDelete

 

 

2009-06-16 07:34:22     Re: Read/Write from mtd partition

Samuel Ayet (SPAIN)

Message: 75804   

 

Sorry for the delay...I'm bussy today. Yes, the problem is the size of the MTD partition as the init log says:

 

physmap platform flash device: 00400000 at 20000000

physmap-flash.0: Found 1 x16 devices at 0x0 in 16-bit bank

Amd/Fujitsu Extended Query Table at 0x0040

number of CFI chips: 1

cfi_cmdset_0002: Disabling erase-suspend-program due to code brokenness.

RedBoot partition parsing not available

Using physmap partition information

Creating 5 MTD partitions on "physmap-flash.0":

0x00000000-0x00040000 : "Bootloader"

0x00040000-0x00120000 : "Kernel"

0x00120000-0x003f0000 : "RootFS"

0x003f0000-0x003f0006 : "MAC Address"

mtd: partition "MAC Address" doesn't end on an erase block -- force read-only

0x003f0006-0x00400000 : "Configuration Data"

mtd: partition "Configuration Data" doesn't start on an erase block boundary -- force read-only

 

 

So what I have done is don't divide the MAC partition in two:

 

static struct mtd_partition stamp_partitions[] = {

    {

    //mtdblock0

        .name       = "Bootloader",

        .size       = 0x40000,

        .offset     = 0,

    }, {

    //mtdblock1

        .name       = "Kernel",

        .size       = 0xE0000,

        .offset     = MTDPART_OFS_APPEND,

    }, {

    //mtdblock2

        .name       = "RootFS",

        .size       = 0x400000 - 0x40000 - 0xE0000 - 0x10000,

        .offset     = MTDPART_OFS_APPEND,

    }, {

    //mtdblock3

        .name       = "MAC Address and Config Data",

        .size       = MTDPART_SIZ_FULL,

        .offset     = MTDPART_OFS_APPEND,

    }

};

 

 

 

And now to read/write I make a lseek of 6 bytes (length of MAC Address) before read/write from mtdblock3. Now I'don't have problems to write due to 'Permission Denied', but I can't read what I write. To test this I use 2  programs:

 

 

 

This one writes a 0x35 (5 in ASCII) in 1kbyte (1024 bytes) of flash starting from the sixth byte of the mtd3 partition.

 

int main(int argc, char* argv[], char** envp){

 

    int fd,i,written;

    char data[1];

    printf("\nOpening MTD...");

 

 

    fd = open("/dev/mtd3", O_RDWR);

  

    if (fd == -1){

        printf("Error: %s \n",strerror(errno));

    }

    else{

        printf("...Open MTD O.K.\n");

    }

 

    data[1] = 0x35;

    lseek(fd,6,SEEK_SET); //We seek the fd to the sixth position

 

    // Write 1024 positions.

    for(i = 0; i<1024; i++){

      written = write(fd,data,1);  

      printf("Writting in Flash a %c. \n",data[1]);

    }  

 

    close(fd);

  

}

 

 

 

And then this other one is for read 1kbyte of the mtd3 partition (without seeking the fd, don't mind for read the MAC Address):

 

 

 

int main(int argc, char* argv[], char** envp){

 

    int fd,read_bytes,i;

    unsigned char buff[1024];

   

    fd = open("/dev/mtd3", O_RDONLY);  

 

    if (fd == -1){

        printf("Error: %s \n",strerror(errno));

    }

    else{

        printf("...Open MTD O.K.\n");

    }

    read_bytes = read(fd,&buff,1024);

 

    if(read_bytes < 0){

        printf("Failed reading MTD : %s\n",strerror(errno));

    }

 

    else{

        for(i=0;i<read_bytes;i++){

            printf("Char number %d read: %0x\n",i,buff[i]);

        }

    }

    close(fd);

  

}

 

 

 

The main problem is that on those address of memory that I have written a 0x35, then I read a 0x00. What I don't know is if I'm reading/writting in the correct way. If i'm not, please let me know how I can do it.

 

 

 

Thanl you Mike and Jean!

QuoteReplyEditDelete

 

 

2009-06-16 07:38:46     Re: Read/Write from mtd partition

Mike Frysinger (UNITED STATES)

Message: 75805   

 

that isnt how you use mtd#.  those are low level interfaces to the device -- you must obey standard read/write/erase behavior.  if you want to have the mtd layers take care of erasing and such for you, then you must use one of the block or char devices.

 

QuoteReplyEditDelete

 

 

2009-06-16 11:49:45     Re: Read/Write from mtd partition

Samuel Ayet (SPAIN)

Message: 75838   

 

/* you must obey standard read/write/erase behavior */

 

I'm not sure of what do you mean, I thought MTD layer will be an abstact of the standard behavior of the flash device.

 

/* then you must use one of the block or char devices */

 

Mike, I have tried to use the mtdblock# device to read write directly, but I have the same error, I read 0x00 where I write 0x35. With mtdchar# I can tell you nothing because I dont have any device called like this. I have tested the MTD Ram Device and works fine, I can read what I write with the same program I have shown you before that don't work with mtd from flash. Of course the problem is that the MTD Ram Device is volatile...

 

│ │                      <*> Test driver using RAM                                                                   │ │

  │ │                      (4096) MTDRAM device size in KiB (NEW)                                                      │ │

  │ │                      (128) MTDRAM erase block size in KiB (NEW)                                                  │ │

  │ │                      (0)   SRAM Hexadecimal Absolute position or 0 (NEW

 

Due to I'm not having succes with read/write directly to the flash, i'm trying to mount a file system on a 128kbytes MTD partition. What I have done now is take 128kbytes of the "Root FS" so here I can erase this partition safety because I don't have stored the MAC like before. I want to format this simple 128kbytes partition in ext2/jffs2/fat32... and save a pair of config files that I will read/write. But I'm having the same problems of every time. I'm not sure if i'm doing this steps wrong of erasing, formating and mounting:

 

Board Resources:

 

static struct mtd_partition stamp_partitions[] = {

    {

    //mtdblock0

        .name       = "Bootloader",

        .size       = 0x40000,

        .offset     = 0,

    }, {

    //mtdblock1

        .name       = "Kernel",

        .size       = 0xE0000,

        .offset     = MTDPART_OFS_APPEND,

    }, {

    //mtdblock2

        .name       = "RootFS",

        .size       = 0x400000 - 0x40000 - 0xE0000 - 0x10000 - 0x20000,

        .offset     = MTDPART_OFS_APPEND,

    }, {

    //mtdblock3

        .name       = "Config Data",

        .size       = 0x20000,

        .offset     = MTDPART_OFS_APPEND,

    } , {

    //mtdblock4

        .name       = "MAC Address",

        .size       = MTDPART_SIZ_FULL,

        .offset     = 0x3F0000,

        .mask_flags = MTD_WRITEABLE,

    }

};

 

Trying to format the mtd3 partition.

 

root:/> eraseall /dev/mtd3

Erased 128 Kibyte @ 0 -- 100% complete.

 

 

root:/> mkfs.ext2 /dev/mtdblock3

mke2fs 1.39 (29-May-2006)

Filesystem label=

OS type: Linux

Block size=1024 (log=0)

Fragment size=1024 (log=0)

16 inodes, 128 blocks

6 blocks (4%) reserved for the super user

First data block=1

1 block group

8192 blocks per group, 8192 fragments per group

16 inodes per group

 

Writing inode tables: done

Writing superblocks and filesystem accounting information: done

 

This filesystem will be automatically checked every 23 mounts or

180.00 days, whichever comes first.  Use tune2fs -c or -i to override.

 

 

root:/> mount -t ext2 /dev/mtd3 /mnt/

mount: mounting /dev/mtd3 on /mnt/ failed

 

 

But if I dump the information of the mtd3 (for example with fdisk) I get all is '0x00'. I'm still in doubt on how to write directly to mtd devices... I thought that I could use them as a typical file (open, write, read...) but I'm not having any success on this way with flash MTD devices.

QuoteReplyEditDelete

 

 

2009-06-16 12:31:34     Re: Read/Write from mtd partition

Jean-Christian de Rivaz (SWITZERLAND)

Message: 75841   

 

Have you tryed to mount /dev/mtdblock3 instead of /dev/mtd3 ? I must admit that I have never used the /dev/mtd#. I alway use the /dev/mtdblock# to do anything.

 

If I remenber correctly, there is a MTD debug option. It can maybe help to see where the problem is.

 

Jean-Christian

QuoteReplyEditDelete

 

 

2009-06-16 12:35:09     Re: Read/Write from mtd partition

Mike Frysinger (UNITED STATES)

Message: 75842   

 

again, you cannot access mtd# directly like that on purpose.  if you want a block interface that takes care of erasing for you, you *must* use the mtdblock#.  using mtd# and not doing the erase stuff yourself will *not* work.

 

mtdchar# may not be enabled by default, but you can easily enable it in the kernel.

QuoteReplyEditDelete

 

 

2009-06-16 12:48:44     Re: Read/Write from mtd partition

Mike Frysinger (UNITED STATES)

Message: 75843   

 

the simple test code works for me when i use the proper mtdblock3

 

root:/> hexdump -C /dev/mtdblock3

00000000  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|

*

00400000

 

root:/> /a.out

ALL OK

 

root:/> hexdump -C /dev/mtdblock3

00000000  ff ff ff ff ff ff ca ca  ca ca ca ca ca ca ca ca  |................|

00000010  ca ca ca ca ca ca ca ca  ca ca ca ca ca ca ca ca  |................|

*

00000400  ca ca ca ca ca ca ff ff  ff ff ff ff ff ff ff ff  |................|

00000410  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|

*

00400000

 

it writes out 1024 bytes of 0x35, reads it back and verifies, then writes out 1024 bytes of 0xca, reads it back and verifies

 

#include <errno.h>

#include <fcntl.h>

#include <stdio.h>

#include <string.h>

#include <unistd.h>

 

#define C(f, r) do { if ((f) != r) { perror(#f); return -1; } } while (0)

 

char data[1024], data2[1024];

int main()

{

        int fd;

        C(fd = open("/dev/mtdblock3", O_RDWR), 3);

 

        memset(data, 0x35, sizeof(data));

        memcpy(data2, data, sizeof(data));

        C(lseek(fd, 6, SEEK_SET), 6);

        C(write(fd, data, sizeof(data)), sizeof(data));

        C(lseek(fd, 6, SEEK_SET), 6);

        C(read(fd, data, sizeof(data)), sizeof(data));

        C(memcmp(data, data2, sizeof(data)), 0);

 

        memset(data, ~0x35, sizeof(data));

        memcpy(data2, data, sizeof(data));

        C(lseek(fd, 6, SEEK_SET), 6);

        C(write(fd, data, sizeof(data)), sizeof(data));

        C(lseek(fd, 6, SEEK_SET), 6);

        C(read(fd, data, sizeof(data)), sizeof(data));

        C(memcmp(data, data2, sizeof(data)), 0);

 

        C(close(fd), 0);

        puts("ALL OK");

 

        return 0;

}

QuoteReplyEditDelete

 

 

2009-06-17 05:49:02     Re: Read/Write from mtd partition

Samuel Ayet (SPAIN)

Message: 75881   

 

OK. Thank you Jean and Mike. I tried yesterday to mount the partition with /dev/mtdblock3 instead of /dev/mtd3 but with the same error.

 

I have "copy & paste" the test program of Mike and works great, I don't know why my program always wrote 0x00 but this program writes what you want to flash and this is what I want to do. Now I have other other question: What is the best way to upgrade the flash memory of the BF537 from 4Mbytes to 16Mbytes? but I will open a new topic explaining the ways I think it could be done.

 

 

 

Thank you another time.

 

Samuel

Attachments

    Outcomes