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