开发板的Linux环境:
# uname -a
Linux 192.168.102.213 2.6.12-4.2-brcmstb #73 Tue Apr 14 16:06:50 CST 2009 7403a0 unknown
我的开发板的Nor flash分区情况是
# cat /proc/mtd
dev: size erasesize name
mtd0: 01800000 00020000 "rootfs"
mtd1: 00200000 00020000 "vmlinux"
mtd2: 00400000 00020000 "config"
mtd3: 00080000 00020000 "splash"
mtd4: 00080000 00020000 "cfe"
mtd5: 00000080 00020000 "mactype"
mtd6: 00040000 00020000 "nvram"
mtd7: 00040000 00020000 "feature"
# ls /dev/mtd* -al
crwxr-xr-x 1 nobody nobody 90, 0 Mar 2 2009 /dev/mtd0
crwxr-xr-x 1 nobody nobody 90, 2 Mar 2 2009 /dev/mtd1
crwxr-xr-x 1 nobody nobody 90, 4 Mar 2 2009 /dev/mtd2
crwxr-xr-x 1 nobody nobody 90, 6 Mar 2 2009 /dev/mtd3
crwxr-xr-x 1 nobody nobody 90, 8 Mar 2 2009 /dev/mtd4
crwxr-xr-x 1 nobody nobody 90, 10 Mar 2 2009 /dev/mtd5
crwxr-xr-x 1 nobody nobody 90, 12 Mar 2 2009 /dev/mtd6
-rw-r--r-- 1 root root 19 Apr 15 2009 /dev/mtd9
brwxr-xr-x 1 nobody nobody 31, 0 Mar 2 2009 /dev/mtdblock0
brwxr-xr-x 1 nobody nobody 31, 1 Mar 2 2009 /dev/mtdblock1
brwxr-xr-x 1 nobody nobody 31, 2 Mar 2 2009 /dev/mtdblock2
brwxr-xr-x 1 nobody nobody 31, 3 Mar 2 2009 /dev/mtdblock3
brwxr-xr-x 1 nobody nobody 31, 4 Mar 2 2009 /dev/mtdblock4
brwxr-xr-x 1 nobody nobody 31, 5 Mar 2 2009 /dev/mtdblock5
brwxr-xr-x 1 nobody nobody 31, 6 Mar 2 2009 /dev/mtdblock6
crwxr-xr-x 1 nobody nobody 90, 1 Mar 2 2009 /dev/mtdr0
crwxr-xr-x 1 nobody nobody 90, 3 Mar 2 2009 /dev/mtdr1
crwxr-xr-x 1 nobody nobody 90, 5 Mar 2 2009 /dev/mtdr2
crwxr-xr-x 1 nobody nobody 90, 7 Mar 2 2009 /dev/mtdr3
crwxr-xr-x 1 nobody nobody 90, 9 Mar 2 2009 /dev/mtdr4
crwxr-xr-x 1 nobody nobody 90, 11 Mar 2 2009 /dev/mtdr5
crwxr-xr-x 1 nobody nobody 90, 13 Mar 2 2009 /dev/mtdr6
通过NFS启动系统后,执行应用程序能读出 /dev/mtd6里面的数据,但是我要写入数据,该如何做?是不是在wriere()前要调用
ioctl()来擦除某个块,然后才能写? 请大家帮助,谢谢!
贴上我的一些关键代码:
FILE *fd = open("/dev/mtd6", O_RDWR)
read_len = read(fd, buff, sizeof(buff)-1);
int ret = ioctl(fd, MEMGETBADBLOCK, &offset); /* 擦某个块 */
write_len = write(buff, 1024/*sizeof(buff)-1*/, fd); /* 写入1K 数据 */
10 个解决方案
#1
我现在用读,或者读写打开/dev/mtd0 或者/dev/mtdblock0,可是调用这个函数出错:
错误码:errno=25.
#make menuconfig
查看内核配置如下:
Linux Kernel v2.6.11-1.1369_FC4 Configuration
<M> Memory Technology Device (MTD) support
[ ] Debugging
<M> MTD concatenating support
[*] MTD partitioning support
<M> RedBoot partition table parsing
(-1) Location of RedBoot partition table
[ ] Include unallocated flash regions
[ ] Force read-only for RedBoot system images
[*] Command line partition table parsing
--- User Modules And Translation Layers
<M> Direct char device access to MTD devices
<M> Caching block device access to MTD devices
<M> Readonly block device access to MTD devices
<M> FTL (Flash Translation Layer) support
<M> NFTL (NAND Flash Translation Layer) support
[*] Write support for NFTL
<M> INFTL (Inverse NAND Flash Translation Layer) support
int get_mtdinfo(int fd)
{
struct mtd_info_user mtdInfo;
struct erase_info_user mtdEraseInfo;
int num;
memset(&mtdInfo, 0, sizeof(struct mtd_info_user));
num = ioctl(fd, MEMGETINFO, &mtdInfo);
if(num < 0)
{
fprintf(stderr, "Error: could not get MTD device info from MTD device, [error=%d]\n", errno);
return -1;
}
printf("mtdInfo: type=%d, flags=%d, size=%d, erasesize=%d\n", \
mtdInfo.type, mtdInfo.flags, mtdInfo.size, mtdInfo.erasesize);
return 0;
}
错误码:errno=25.
#make menuconfig
查看内核配置如下:
Linux Kernel v2.6.11-1.1369_FC4 Configuration
<M> Memory Technology Device (MTD) support
[ ] Debugging
<M> MTD concatenating support
[*] MTD partitioning support
<M> RedBoot partition table parsing
(-1) Location of RedBoot partition table
[ ] Include unallocated flash regions
[ ] Force read-only for RedBoot system images
[*] Command line partition table parsing
--- User Modules And Translation Layers
<M> Direct char device access to MTD devices
<M> Caching block device access to MTD devices
<M> Readonly block device access to MTD devices
<M> FTL (Flash Translation Layer) support
<M> NFTL (NAND Flash Translation Layer) support
[*] Write support for NFTL
<M> INFTL (Inverse NAND Flash Translation Layer) support
#2
我已确定,mtd6: 00040000 00020000 "nvram" ,mtd6这个flash分区的开始地址和分区大小都是擦除块(128KB)的倍数关系。符合驱动要求的写条件。
#3
在内核的MTD驱动中的分区表:
#elif(CTV_DEFAULT_SIZE_MB == 32)
{ name: "vmlinux", offset: 0x01D00000, size: 2048 * 1024},//3456*1024 },
{ name: "config", offset: 0x01800000, size: 4096 * 1024},
{ name: "splash", offset: 0x01C80000, size: 512 * 1024},
{ name: "cfe", offset: 0x01C00000, size: 512*1024 },
// { name: "macadr", offset: 0x01FFF800, size: 144 },
{ name: "mactype", offset: 0x01FFF780, size: 128 },
{ name: "nvram", offset: 0x01F40000, size: 256 * 1024 },
{ name: "feature", offset: 0x01F00000, size: 256 * 1024 },
#endif
#4
请高手相助,多谢,可以另外开贴给分!Thanks.
#5
早上的帖子不是已经回你了嘛,给了一个简短的 dd 源码,稍微改一下就行了。你想要的那些东西貌似 dd 都能完成:
# dd if=/dev/mtd4 of=/dev/mtd5 bs=1024
#6
麻烦你再贴一下,那贴子,我不小心删除了。
#7
前面那部分就是处理 mtd_erase(), mtd_eraseall() 的,但是现在找不到了...
#8
请楼上,查一下网页的历史记录。谢了。
#9
已解决:
是编译选项里,指向了FC4的linux的头文件(是错误的),正确的做法指向broadcom的内核的头文件。
CC := mipsel-uclibc-gcc #gcc
DIR := /opt/stblinux-2.6.12/include #/usr/include, 不应当指向linux FC4的目录里的头文件。
CFLAGS := -o2 -I$(DIR)
参见
http://linux.chinaunix.net/bbs/viewthread.php?tid=1097651&pid=6983619&page=1&extra=page%3D1#pid6983619
是编译选项里,指向了FC4的linux的头文件(是错误的),正确的做法指向broadcom的内核的头文件。
CC := mipsel-uclibc-gcc #gcc
DIR := /opt/stblinux-2.6.12/include #/usr/include, 不应当指向linux FC4的目录里的头文件。
CFLAGS := -o2 -I$(DIR)
参见
http://linux.chinaunix.net/bbs/viewthread.php?tid=1097651&pid=6983619&page=1&extra=page%3D1#pid6983619
#10
/*
* flash_erase.c -- erase parts of a MTD device
*/
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <fcntl.h>
#include <time.h>
#include <sys/ioctl.h>
#include <sys/mount.h>
#include <mtd/mtd-user.h>
int region_erase(int Fd, int start, int count, int unlock, int regcount)
{
int i, j;
region_info_t * reginfo;
reginfo = calloc(regcount, sizeof(region_info_t));
for(i = 0; i < regcount; i++)
{
reginfo[i].regionindex = i;
if(ioctl(Fd,MEMGETREGIONINFO,&(reginfo[i])) != 0)
return 8;
else
printf("Region %d is at %d of %d sector and with sector "
"size %x\n", i, reginfo[i].offset, reginfo[i].numblocks,
reginfo[i].erasesize);
}
// We have all the information about the chip we need.
for(i = 0; i < regcount; i++)
{ //Loop through the regions
region_info_t * r = &(reginfo[i]);
if((start >= reginfo[i].offset) &&
(start < (r->offset + r->numblocks*r->erasesize)))
break;
}
if(i >= regcount)
{
printf("Starting offset %x not within chip.\n", start);
return 8;
}
//We are now positioned within region i of the chip, so start erasing
//count sectors from there.
for(j = 0; (j < count)&&(i < regcount); j++)
{
erase_info_t erase;
region_info_t * r = &(reginfo[i]);
erase.start = start;
erase.length = r->erasesize;
if(unlock != 0)
{ //Unlock the sector first.
if(ioctl(Fd, MEMUNLOCK, &erase) != 0)
{
perror("\nMTD Unlock failure");
close(Fd);
return 8;
}
}
printf("\rPerforming Flash Erase of length %u at offset 0x%x",
erase.length, erase.start);
fflush(stdout);
if(ioctl(Fd, MEMERASE, &erase) != 0)
{
perror("\nMTD Erase failure");
close(Fd);
return 8;
}
start += erase.length;
if(start >= (r->offset + r->numblocks*r->erasesize))
{ //We finished region i so move to region i+1
printf("\nMoving to region %d\n", i+1);
i++;
}
}
printf(" done\n");
return 0;
}
int non_region_erase(int Fd, int start, int count, int unlock)
{
mtd_info_t meminfo;
if (ioctl(Fd,MEMGETINFO,&meminfo) == 0)
{
erase_info_t erase;
erase.start = start;
erase.length = meminfo.erasesize;
for (; count > 0; count--) {
printf("\rPerforming Flash Erase of length %u at offset 0x%x",
erase.length, erase.start);
fflush(stdout);
if(unlock != 0)
{
//Unlock the sector first.
printf("\rPerforming Flash unlock at offset 0x%x",erase.start);
if(ioctl(Fd, MEMUNLOCK, &erase) != 0)
{
perror("\nMTD Unlock failure");
close(Fd);
return 8;
}
}
if (ioctl(Fd,MEMERASE,&erase) != 0)
{
perror("\nMTD Erase failure");
close(Fd);
return 8;
}
erase.start += meminfo.erasesize;
}
printf(" done\n");
}
return 0;
}
int main(int argc,char *argv[])
{
int regcount;
int Fd;
int start;
int count;
int unlock;
int res = 0;
if (1 >= argc)
{
fprintf(stderr,"You must specify a device\n");
return 16;
}
if (argc > 2)
start = strtol(argv[2], NULL, 0);
else
start = 0;
if (argc > 3)
count = strtol(argv[3], NULL, 0);
else
count = 1;
if(argc > 4)
unlock = strtol(argv[4], NULL, 0);
else
unlock = 0;
// Open and size the device
if ((Fd = open(argv[1],O_RDWR)) < 0)
{
fprintf(stderr,"File open error\n");
return 8;
}
printf("Erase Total %d Units\n", count);
if (ioctl(Fd,MEMGETREGIONCOUNT,®count) == 0)
{
if(regcount == 0)
{
res = non_region_erase(Fd, start, count, unlock);
}
else
{
res = region_erase(Fd, start, count, unlock, regcount);
}
}
return res;
}
* flash_erase.c -- erase parts of a MTD device
*/
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <fcntl.h>
#include <time.h>
#include <sys/ioctl.h>
#include <sys/mount.h>
#include <mtd/mtd-user.h>
int region_erase(int Fd, int start, int count, int unlock, int regcount)
{
int i, j;
region_info_t * reginfo;
reginfo = calloc(regcount, sizeof(region_info_t));
for(i = 0; i < regcount; i++)
{
reginfo[i].regionindex = i;
if(ioctl(Fd,MEMGETREGIONINFO,&(reginfo[i])) != 0)
return 8;
else
printf("Region %d is at %d of %d sector and with sector "
"size %x\n", i, reginfo[i].offset, reginfo[i].numblocks,
reginfo[i].erasesize);
}
// We have all the information about the chip we need.
for(i = 0; i < regcount; i++)
{ //Loop through the regions
region_info_t * r = &(reginfo[i]);
if((start >= reginfo[i].offset) &&
(start < (r->offset + r->numblocks*r->erasesize)))
break;
}
if(i >= regcount)
{
printf("Starting offset %x not within chip.\n", start);
return 8;
}
//We are now positioned within region i of the chip, so start erasing
//count sectors from there.
for(j = 0; (j < count)&&(i < regcount); j++)
{
erase_info_t erase;
region_info_t * r = &(reginfo[i]);
erase.start = start;
erase.length = r->erasesize;
if(unlock != 0)
{ //Unlock the sector first.
if(ioctl(Fd, MEMUNLOCK, &erase) != 0)
{
perror("\nMTD Unlock failure");
close(Fd);
return 8;
}
}
printf("\rPerforming Flash Erase of length %u at offset 0x%x",
erase.length, erase.start);
fflush(stdout);
if(ioctl(Fd, MEMERASE, &erase) != 0)
{
perror("\nMTD Erase failure");
close(Fd);
return 8;
}
start += erase.length;
if(start >= (r->offset + r->numblocks*r->erasesize))
{ //We finished region i so move to region i+1
printf("\nMoving to region %d\n", i+1);
i++;
}
}
printf(" done\n");
return 0;
}
int non_region_erase(int Fd, int start, int count, int unlock)
{
mtd_info_t meminfo;
if (ioctl(Fd,MEMGETINFO,&meminfo) == 0)
{
erase_info_t erase;
erase.start = start;
erase.length = meminfo.erasesize;
for (; count > 0; count--) {
printf("\rPerforming Flash Erase of length %u at offset 0x%x",
erase.length, erase.start);
fflush(stdout);
if(unlock != 0)
{
//Unlock the sector first.
printf("\rPerforming Flash unlock at offset 0x%x",erase.start);
if(ioctl(Fd, MEMUNLOCK, &erase) != 0)
{
perror("\nMTD Unlock failure");
close(Fd);
return 8;
}
}
if (ioctl(Fd,MEMERASE,&erase) != 0)
{
perror("\nMTD Erase failure");
close(Fd);
return 8;
}
erase.start += meminfo.erasesize;
}
printf(" done\n");
}
return 0;
}
int main(int argc,char *argv[])
{
int regcount;
int Fd;
int start;
int count;
int unlock;
int res = 0;
if (1 >= argc)
{
fprintf(stderr,"You must specify a device\n");
return 16;
}
if (argc > 2)
start = strtol(argv[2], NULL, 0);
else
start = 0;
if (argc > 3)
count = strtol(argv[3], NULL, 0);
else
count = 1;
if(argc > 4)
unlock = strtol(argv[4], NULL, 0);
else
unlock = 0;
// Open and size the device
if ((Fd = open(argv[1],O_RDWR)) < 0)
{
fprintf(stderr,"File open error\n");
return 8;
}
printf("Erase Total %d Units\n", count);
if (ioctl(Fd,MEMGETREGIONCOUNT,®count) == 0)
{
if(regcount == 0)
{
res = non_region_erase(Fd, start, count, unlock);
}
else
{
res = region_erase(Fd, start, count, unlock, regcount);
}
}
return res;
}
#1
我现在用读,或者读写打开/dev/mtd0 或者/dev/mtdblock0,可是调用这个函数出错:
错误码:errno=25.
#make menuconfig
查看内核配置如下:
Linux Kernel v2.6.11-1.1369_FC4 Configuration
<M> Memory Technology Device (MTD) support
[ ] Debugging
<M> MTD concatenating support
[*] MTD partitioning support
<M> RedBoot partition table parsing
(-1) Location of RedBoot partition table
[ ] Include unallocated flash regions
[ ] Force read-only for RedBoot system images
[*] Command line partition table parsing
--- User Modules And Translation Layers
<M> Direct char device access to MTD devices
<M> Caching block device access to MTD devices
<M> Readonly block device access to MTD devices
<M> FTL (Flash Translation Layer) support
<M> NFTL (NAND Flash Translation Layer) support
[*] Write support for NFTL
<M> INFTL (Inverse NAND Flash Translation Layer) support
int get_mtdinfo(int fd)
{
struct mtd_info_user mtdInfo;
struct erase_info_user mtdEraseInfo;
int num;
memset(&mtdInfo, 0, sizeof(struct mtd_info_user));
num = ioctl(fd, MEMGETINFO, &mtdInfo);
if(num < 0)
{
fprintf(stderr, "Error: could not get MTD device info from MTD device, [error=%d]\n", errno);
return -1;
}
printf("mtdInfo: type=%d, flags=%d, size=%d, erasesize=%d\n", \
mtdInfo.type, mtdInfo.flags, mtdInfo.size, mtdInfo.erasesize);
return 0;
}
错误码:errno=25.
#make menuconfig
查看内核配置如下:
Linux Kernel v2.6.11-1.1369_FC4 Configuration
<M> Memory Technology Device (MTD) support
[ ] Debugging
<M> MTD concatenating support
[*] MTD partitioning support
<M> RedBoot partition table parsing
(-1) Location of RedBoot partition table
[ ] Include unallocated flash regions
[ ] Force read-only for RedBoot system images
[*] Command line partition table parsing
--- User Modules And Translation Layers
<M> Direct char device access to MTD devices
<M> Caching block device access to MTD devices
<M> Readonly block device access to MTD devices
<M> FTL (Flash Translation Layer) support
<M> NFTL (NAND Flash Translation Layer) support
[*] Write support for NFTL
<M> INFTL (Inverse NAND Flash Translation Layer) support
#2
我已确定,mtd6: 00040000 00020000 "nvram" ,mtd6这个flash分区的开始地址和分区大小都是擦除块(128KB)的倍数关系。符合驱动要求的写条件。
#3
在内核的MTD驱动中的分区表:
#elif(CTV_DEFAULT_SIZE_MB == 32)
{ name: "vmlinux", offset: 0x01D00000, size: 2048 * 1024},//3456*1024 },
{ name: "config", offset: 0x01800000, size: 4096 * 1024},
{ name: "splash", offset: 0x01C80000, size: 512 * 1024},
{ name: "cfe", offset: 0x01C00000, size: 512*1024 },
// { name: "macadr", offset: 0x01FFF800, size: 144 },
{ name: "mactype", offset: 0x01FFF780, size: 128 },
{ name: "nvram", offset: 0x01F40000, size: 256 * 1024 },
{ name: "feature", offset: 0x01F00000, size: 256 * 1024 },
#endif
#4
请高手相助,多谢,可以另外开贴给分!Thanks.
#5
早上的帖子不是已经回你了嘛,给了一个简短的 dd 源码,稍微改一下就行了。你想要的那些东西貌似 dd 都能完成:
# dd if=/dev/mtd4 of=/dev/mtd5 bs=1024
#6
麻烦你再贴一下,那贴子,我不小心删除了。
#7
前面那部分就是处理 mtd_erase(), mtd_eraseall() 的,但是现在找不到了...
#8
请楼上,查一下网页的历史记录。谢了。
#9
已解决:
是编译选项里,指向了FC4的linux的头文件(是错误的),正确的做法指向broadcom的内核的头文件。
CC := mipsel-uclibc-gcc #gcc
DIR := /opt/stblinux-2.6.12/include #/usr/include, 不应当指向linux FC4的目录里的头文件。
CFLAGS := -o2 -I$(DIR)
参见
http://linux.chinaunix.net/bbs/viewthread.php?tid=1097651&pid=6983619&page=1&extra=page%3D1#pid6983619
是编译选项里,指向了FC4的linux的头文件(是错误的),正确的做法指向broadcom的内核的头文件。
CC := mipsel-uclibc-gcc #gcc
DIR := /opt/stblinux-2.6.12/include #/usr/include, 不应当指向linux FC4的目录里的头文件。
CFLAGS := -o2 -I$(DIR)
参见
http://linux.chinaunix.net/bbs/viewthread.php?tid=1097651&pid=6983619&page=1&extra=page%3D1#pid6983619
#10
/*
* flash_erase.c -- erase parts of a MTD device
*/
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <fcntl.h>
#include <time.h>
#include <sys/ioctl.h>
#include <sys/mount.h>
#include <mtd/mtd-user.h>
int region_erase(int Fd, int start, int count, int unlock, int regcount)
{
int i, j;
region_info_t * reginfo;
reginfo = calloc(regcount, sizeof(region_info_t));
for(i = 0; i < regcount; i++)
{
reginfo[i].regionindex = i;
if(ioctl(Fd,MEMGETREGIONINFO,&(reginfo[i])) != 0)
return 8;
else
printf("Region %d is at %d of %d sector and with sector "
"size %x\n", i, reginfo[i].offset, reginfo[i].numblocks,
reginfo[i].erasesize);
}
// We have all the information about the chip we need.
for(i = 0; i < regcount; i++)
{ //Loop through the regions
region_info_t * r = &(reginfo[i]);
if((start >= reginfo[i].offset) &&
(start < (r->offset + r->numblocks*r->erasesize)))
break;
}
if(i >= regcount)
{
printf("Starting offset %x not within chip.\n", start);
return 8;
}
//We are now positioned within region i of the chip, so start erasing
//count sectors from there.
for(j = 0; (j < count)&&(i < regcount); j++)
{
erase_info_t erase;
region_info_t * r = &(reginfo[i]);
erase.start = start;
erase.length = r->erasesize;
if(unlock != 0)
{ //Unlock the sector first.
if(ioctl(Fd, MEMUNLOCK, &erase) != 0)
{
perror("\nMTD Unlock failure");
close(Fd);
return 8;
}
}
printf("\rPerforming Flash Erase of length %u at offset 0x%x",
erase.length, erase.start);
fflush(stdout);
if(ioctl(Fd, MEMERASE, &erase) != 0)
{
perror("\nMTD Erase failure");
close(Fd);
return 8;
}
start += erase.length;
if(start >= (r->offset + r->numblocks*r->erasesize))
{ //We finished region i so move to region i+1
printf("\nMoving to region %d\n", i+1);
i++;
}
}
printf(" done\n");
return 0;
}
int non_region_erase(int Fd, int start, int count, int unlock)
{
mtd_info_t meminfo;
if (ioctl(Fd,MEMGETINFO,&meminfo) == 0)
{
erase_info_t erase;
erase.start = start;
erase.length = meminfo.erasesize;
for (; count > 0; count--) {
printf("\rPerforming Flash Erase of length %u at offset 0x%x",
erase.length, erase.start);
fflush(stdout);
if(unlock != 0)
{
//Unlock the sector first.
printf("\rPerforming Flash unlock at offset 0x%x",erase.start);
if(ioctl(Fd, MEMUNLOCK, &erase) != 0)
{
perror("\nMTD Unlock failure");
close(Fd);
return 8;
}
}
if (ioctl(Fd,MEMERASE,&erase) != 0)
{
perror("\nMTD Erase failure");
close(Fd);
return 8;
}
erase.start += meminfo.erasesize;
}
printf(" done\n");
}
return 0;
}
int main(int argc,char *argv[])
{
int regcount;
int Fd;
int start;
int count;
int unlock;
int res = 0;
if (1 >= argc)
{
fprintf(stderr,"You must specify a device\n");
return 16;
}
if (argc > 2)
start = strtol(argv[2], NULL, 0);
else
start = 0;
if (argc > 3)
count = strtol(argv[3], NULL, 0);
else
count = 1;
if(argc > 4)
unlock = strtol(argv[4], NULL, 0);
else
unlock = 0;
// Open and size the device
if ((Fd = open(argv[1],O_RDWR)) < 0)
{
fprintf(stderr,"File open error\n");
return 8;
}
printf("Erase Total %d Units\n", count);
if (ioctl(Fd,MEMGETREGIONCOUNT,®count) == 0)
{
if(regcount == 0)
{
res = non_region_erase(Fd, start, count, unlock);
}
else
{
res = region_erase(Fd, start, count, unlock, regcount);
}
}
return res;
}
* flash_erase.c -- erase parts of a MTD device
*/
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <fcntl.h>
#include <time.h>
#include <sys/ioctl.h>
#include <sys/mount.h>
#include <mtd/mtd-user.h>
int region_erase(int Fd, int start, int count, int unlock, int regcount)
{
int i, j;
region_info_t * reginfo;
reginfo = calloc(regcount, sizeof(region_info_t));
for(i = 0; i < regcount; i++)
{
reginfo[i].regionindex = i;
if(ioctl(Fd,MEMGETREGIONINFO,&(reginfo[i])) != 0)
return 8;
else
printf("Region %d is at %d of %d sector and with sector "
"size %x\n", i, reginfo[i].offset, reginfo[i].numblocks,
reginfo[i].erasesize);
}
// We have all the information about the chip we need.
for(i = 0; i < regcount; i++)
{ //Loop through the regions
region_info_t * r = &(reginfo[i]);
if((start >= reginfo[i].offset) &&
(start < (r->offset + r->numblocks*r->erasesize)))
break;
}
if(i >= regcount)
{
printf("Starting offset %x not within chip.\n", start);
return 8;
}
//We are now positioned within region i of the chip, so start erasing
//count sectors from there.
for(j = 0; (j < count)&&(i < regcount); j++)
{
erase_info_t erase;
region_info_t * r = &(reginfo[i]);
erase.start = start;
erase.length = r->erasesize;
if(unlock != 0)
{ //Unlock the sector first.
if(ioctl(Fd, MEMUNLOCK, &erase) != 0)
{
perror("\nMTD Unlock failure");
close(Fd);
return 8;
}
}
printf("\rPerforming Flash Erase of length %u at offset 0x%x",
erase.length, erase.start);
fflush(stdout);
if(ioctl(Fd, MEMERASE, &erase) != 0)
{
perror("\nMTD Erase failure");
close(Fd);
return 8;
}
start += erase.length;
if(start >= (r->offset + r->numblocks*r->erasesize))
{ //We finished region i so move to region i+1
printf("\nMoving to region %d\n", i+1);
i++;
}
}
printf(" done\n");
return 0;
}
int non_region_erase(int Fd, int start, int count, int unlock)
{
mtd_info_t meminfo;
if (ioctl(Fd,MEMGETINFO,&meminfo) == 0)
{
erase_info_t erase;
erase.start = start;
erase.length = meminfo.erasesize;
for (; count > 0; count--) {
printf("\rPerforming Flash Erase of length %u at offset 0x%x",
erase.length, erase.start);
fflush(stdout);
if(unlock != 0)
{
//Unlock the sector first.
printf("\rPerforming Flash unlock at offset 0x%x",erase.start);
if(ioctl(Fd, MEMUNLOCK, &erase) != 0)
{
perror("\nMTD Unlock failure");
close(Fd);
return 8;
}
}
if (ioctl(Fd,MEMERASE,&erase) != 0)
{
perror("\nMTD Erase failure");
close(Fd);
return 8;
}
erase.start += meminfo.erasesize;
}
printf(" done\n");
}
return 0;
}
int main(int argc,char *argv[])
{
int regcount;
int Fd;
int start;
int count;
int unlock;
int res = 0;
if (1 >= argc)
{
fprintf(stderr,"You must specify a device\n");
return 16;
}
if (argc > 2)
start = strtol(argv[2], NULL, 0);
else
start = 0;
if (argc > 3)
count = strtol(argv[3], NULL, 0);
else
count = 1;
if(argc > 4)
unlock = strtol(argv[4], NULL, 0);
else
unlock = 0;
// Open and size the device
if ((Fd = open(argv[1],O_RDWR)) < 0)
{
fprintf(stderr,"File open error\n");
return 8;
}
printf("Erase Total %d Units\n", count);
if (ioctl(Fd,MEMGETREGIONCOUNT,®count) == 0)
{
if(regcount == 0)
{
res = non_region_erase(Fd, start, count, unlock);
}
else
{
res = region_erase(Fd, start, count, unlock, regcount);
}
}
return res;
}