使用mtd-utils工具实现对flash的升级分区的烧写yaffs2

yaffs2的格式是根据所使用的nandflash来制作的,不同的nandflash,得到的yaffs2是不一样的,具体可以参考自己所用的nandflash,以及生成yaffs2文件系统的工具mkyaffs2image。
yaffs2包含了oob数据,所以写flash的时候要分开,本文所使用的是256M oob是64bit,page是2048byte-2kByte,block=64page制作的yaffs2的大小是(2048+64)的倍数!
每次写入是按页(page)的大小写入,而擦除是按照块来的,坏块也是按照块来的,如果当前块是坏的就必须跳过该块!
下载mtd-utils源码!

yaffs2的写入函数


int mtd_write_yaffs2_skip_bad(libmtd_t desc,const struct mtd_dev_info *mtd, int fd, int eb, int offs,
const char *img_name)函数用来烧写flash,如下:
{
int tmp, ret, in_fd, len, written = ;
int write_eb_num,i;
int data_length,left_to_write,writesize;
off_t seek;
struct stat st;
char *buf,*temp,*dataAddr,*oobAddr; if (offs < || offs >= mtd->eb_size) {
errmsg("bad offset %d, mtd%d eraseblock size is %d",
offs, mtd->mtd_num, mtd->eb_size);
errno = EINVAL;
return -;
}
if (offs % mtd->subpage_size) {
//start address must align to page (2048)0x800
errmsg("write offset %d is not aligned to mtd%d min. I/O size %d",
offs, mtd->mtd_num, mtd->subpage_size);
errno = EINVAL;
return -;
}
in_fd = open(img_name, O_RDONLY | O_CLOEXEC);
if (in_fd == -)
return sys_errmsg("cannot open \"%s\"", img_name); if (fstat(in_fd, &st)){
sys_errmsg("cannot stat %s", img_name);
goto out_close;
} len = st.st_size;
if (len % (mtd->subpage_size + mtd->oob_size)){
errmsg("size of \"%s\" is %d byte, which is not aligned to "
"mtd%d min. I/O size %d, it is not a yaffs2 file ", img_name, len, mtd->mtd_num,
mtd->subpage_size + mtd->oob_size);
errno = EINVAL;
goto out_close;
}
data_length = len / (mtd->subpage_size + mtd->oob_size) * mtd->subpage_size; tmp = (offs + data_length + mtd->eb_size - ) / mtd->eb_size;
if (eb + tmp > mtd->eb_cnt) {
errmsg("\"%s\" image size(except oob size) is %d bytes, mtd%d size is %d "
"eraseblocks, the image does not fit if we write it "
"starting from eraseblock %d, offset %d",
img_name, data_length, mtd->mtd_num, mtd->eb_cnt, eb, offs);
errno = EINVAL;
goto out_close;
} /* Seek to the beginning of the eraseblock */
seek = (off_t)eb * mtd->eb_size + offs;
if (lseek(fd, seek, SEEK_SET) != seek) {
sys_errmsg("cannot seek mtd%d to offset %llu",
mtd->mtd_num, (unsigned long long)seek);
goto out_close;
}
writesize = (mtd->eb_size / mtd->subpage_size) *( mtd->subpage_size + mtd->oob_size);
printf("write size with oob size is: %d \n",writesize);
buf = xmalloc(writesize); left_to_write = len;
write_eb_num = eb;
///writeoffs = eb*mtd->eb_size + offs; while (left_to_write > ) {
int rd = ; ret = mtd_is_bad(mtd,fd,write_eb_num);//判断当前块是否是坏块!
if(ret >){ //是坏块!
write_eb_num = write_eb_num + ;
if(write_eb_num >= mtd->eb_cnt)
{
if(left_to_write < ){
goto out_free;
}
}
else {
printf("skip bad blocks at offset: %d \n",write_eb_num);
continue;
}
}else if(ret <){
printf("get bad blocks error: %d\n",errno);
} if(left_to_write < (mtd->eb_size +mtd->oob_size)){
writesize = left_to_write;
}
else{
writesize = (mtd->eb_size / mtd->subpage_size) *( mtd->subpage_size + mtd->oob_size);
} ret = read(in_fd, buf, writesize);
if(ret == -) {
sys_errmsg("cannot read \"%s\"", img_name);
goto out_free;
} temp = buf; dataAddr = temp;
oobAddr = temp + mtd->subpage_size; for(i=;i< mtd->eb_size/mtd->subpage_size;i++){ //完成一个块的写入!
ret = mtd_write(desc,mtd,fd,write_eb_num,i*mtd->subpage_size,dataAddr,mtd->subpage_size,oobAddr,mtd->oob_size,MTD_OPS_RAW);
if(ret < ){
printf("write data witd oob error : %d \n",errno);
}
temp = oobAddr + mtd->oob_size;
dataAddr = temp;
oobAddr = temp + mtd->subpage_size;
}
write_eb_num = write_eb_num +;
left_to_write -= writesize;
printf("left_to_write :%d write_eb_num: %d,writesize:%d\n",left_to_write,write_eb_num,writesize); } free(buf);
close(in_fd);
return ; out_free:
free(buf);
out_close:
close(in_fd);
return -; } ​

yaffs2的读取函数


int mtd_read_yaffs2_skip_bad(libmtd_t desc,const struct mtd_dev_info *mtd, int fd, int eb, int offs,
const char *img_name)
{
int tmp, ret, out_fd, len, written = ;
int read_eb_num,i,sekOffs;
int data_length,left_to_read,readsize;
off_t seek;
struct stat st;
char *buf,*dataAddr,*oobAddr; if (offs < || offs >= mtd->eb_size) {
errmsg("bad offset %d, mtd%d eraseblock size is %d",
offs, mtd->mtd_num, mtd->eb_size);
errno = EINVAL;
return -;
}
if (offs % mtd->subpage_size) {
//start address must align to page (2048)0x800
errmsg("write offset %d is not aligned to mtd%d min. I/O size %d",
offs, mtd->mtd_num, mtd->subpage_size);
errno = EINVAL;
return -;
}
len = 0x193b3c0;//for test's length, you can read nand flash frome straddr to endaddr!!!
//also can read all mtdx device!
if (len % (mtd->subpage_size + mtd->oob_size)){
errmsg("size of \"%s\" is %d byte, which is not aligned to "
"mtd%d min. I/O size %d, it is not a yaffs2 file ", img_name, len, mtd->mtd_num,
mtd->subpage_size + mtd->oob_size);
errno = EINVAL;
goto out_close;
}
data_length = len / (mtd->subpage_size + mtd->oob_size) * mtd->subpage_size; tmp = (offs + data_length + mtd->eb_size - ) / mtd->eb_size;
if (eb + tmp > mtd->eb_cnt) {
errmsg("\"%s\" image size(except oob size) is %d bytes, mtd%d size is %d "
"eraseblocks, the image does not fit if we write it "
"starting from eraseblock %d, offset %d",
img_name, data_length, mtd->mtd_num, mtd->eb_cnt, eb, offs);
errno = EINVAL;
goto out_close;
}
/* Seek to the beginning of the eraseblock */
seek = (off_t)eb * mtd->eb_size + offs;
if (lseek(fd, seek, SEEK_SET) != seek) {
sys_errmsg("cannot seek mtd%d to offset %llu",
mtd->mtd_num, (unsigned long long)seek);
goto out_close;
} readsize = mtd->subpage_size + mtd->oob_size;
printf("read size with oob size is: %d \n",readsize); buf = xmalloc(readsize); dataAddr = buf;
oobAddr = buf + mtd->subpage_size; left_to_read = len;
read_eb_num = eb; out_fd = open(img_name,O_WRONLY|O_CREAT|O_TRUNC|O_APPEND, S_IRUSR | S_IWUSR);
if(out_fd < ){
printf("open write file error: %d \n",errno);
return -;
} while (left_to_read > ) {
int rd = ; ret = mtd_is_bad(mtd,fd,read_eb_num);
if(ret >){
read_eb_num = read_eb_num + ;
if(read_eb_num >= mtd->eb_cnt)
{
if(left_to_read < ){
goto out_free;
}
}
else {
printf("skip bad blocks at offset: %d \n",read_eb_num);
continue;
}
}else if(ret <){
printf("get bad blocks error: %d\n",errno);
} if(left_to_read < (mtd->eb_size +mtd->oob_size)){
readsize = left_to_read;
}
else{
readsize = (mtd->eb_size / mtd->subpage_size) *( mtd->subpage_size + mtd->oob_size);
} for(i=;i< mtd->eb_size/mtd->subpage_size;i++){ ret = mtd_read(mtd,fd,read_eb_num,i*mtd->subpage_size,dataAddr,mtd->subpage_size);
if(ret < ){
printf("read data error: %d \n",errno);
goto out_free;
} sekOffs = read_eb_num * mtd->eb_size + i*mtd->subpage_size;
seek = (off_t)sekOffs;
//printf("seek %#llx sek offs %#x \n",seek,sekOffs);
ret = mtd_read_oob(desc,mtd,fd,seek,mtd->oob_size,oobAddr);
if(ret < ){
printf("read oob error: %d \n",errno);
goto out_free;
} ret = write(out_fd, dataAddr, mtd->subpage_size);
if(ret == -) {
sys_errmsg("cannot write data \"%s\"", img_name);
goto out_free;
}
ret = write(out_fd, oobAddr, mtd->oob_size);
if(ret == -) {
sys_errmsg("cannot write oob \"%s\"", img_name);
goto out_free;
}
}
read_eb_num = read_eb_num +;
left_to_read -= readsize;
printf("left_to_read :%-7d write_eb_num: %-3d,readsize:%-6d\n",left_to_read,read_eb_num,readsize);
}
free(buf);
close(out_fd);
return ;
out_free:
free(buf);
out_close:
close(out_fd);
return -; } ​

测试烧写;


具体如下:
int mtdDevFd1 =,ret =,i;
libmtd_t mtd_desc;
char* image_file = FILE_NAME;
struct mtd_dev_info mtd;
//open mtd device, see it at /dev/mtdX
//get mtd message : cat /proc/mtd
if ((mtdDevFd1 = open(mtdDev1, O_RDWR)) < ){
_SEND_DBUG_MSG("open %s error \n",mtdDev2);
ret =-;
goto out_close;
}
mtd_desc = libmtd_open();
if(mtd_desc == NULL){
_SEND_DBUG_MSG("can not initlize mtd lib \n");
ret =-;
goto out_close;
} if (mtd_get_dev_info(mtd_desc,mtdDev1,&mtd) < ){
ret =-;
goto out_close;;
_SEND_DBUG_MSG("get dev info error!\n");
}
printf("size:%#x \n",mtd.size);
printf("eb_size:%#x \n",mtd.eb_size);
printf("name:%s \n",mtd.name);
printf("subpage size: %#x \n",mtd.subpage_size);
printf("oob size: %#x \n",mtd.oob_size);
printf("eb_cnt: %#x \n",mtd.eb_cnt); for(i = ; i< mtd.eb_cnt;i++){
if(mtd_is_bad(&mtd, mtdDevFd1, i))
{
printf("erase skip bad block num: %d \n",i);
continue;
}
if( != mtd_erase(mtd_desc,&mtd,mtdDevFd1,i)){//擦除!
_SEND_DBUG_MSG("ersae error \n");
ret =-;
goto out_close;
}
}
if( != mtd_write_yaffs2_skip_bad(mtd_desc,&mtd,mtdDevFd1,,,image_file)){
_SEND_DBUG_MSG("write yaffs2 error \n");
ret = -;
}
out_close:
libmtd_close(mtd_desc);
close(mtdDevFd1);
//write end!!! ​

linux 对MTD分区nand flash的烧写和读取的更多相关文章

  1. Davinci DM6446开发攻略-UBOOT-2009.03移植2 nand flash的烧写

      很长一段时间没有更新博客了,是因为要推出新开发方案和做好客户服务工作,忙得不易乐乎.有关DAVINCI U-BOOT的移植,以前写过一篇u-boot-1.3.4(2008年的),其实和这个u-bo ...

  2. 【DM642学习笔记三】flash的烧写

    ICETEK-DM642-PCI板上的29L008B芯片提供了8M位的Flash空间(访问地址空间是CE1,90000000h~90080000h).主要用于自启动功能和存储FPGA的配置数据. 一. ...

  3. linux内核 mtd分区

    首先 内核配置需要打开MTD选项 Memory Technology Devices (MTD) ---> 如果是NOR Flash,需要选择Common Flash Interface (CF ...

  4. UBIFS分区制作及UBIFS烧写和启动

    参考 http://blog.csdn.net/chongzi865458/article/details/6799258 ubiattach version 1.0 - a tool to atta ...

  5. DM6446开发攻略:UBOOT-2009.03移植及nand flash烧写

    有关DAVINCI U-BOOT的移植,以前写过一篇u-boot-1.3.4(2008年的),其实和这个u-boot-2009.03差别不大,只不过这个u-boot-2009.03是从TI的网站上下载 ...

  6. 使用JLink间接烧写S3C2410、S3C2440开发板Nor、Nand Flash的方法

    1. 简要说明 JLink的调试功能.烧写Flash的功能都很强大,但是对于S3C2410.S3C2440的Flash操作有些麻烦:烧写Nor Flash时需要设置SDRAM,否则速率很慢:烧写Nan ...

  7. 【嵌入式开发】向开发板中烧写Linux系统-型号S3C6410

    作者 : 万境绝尘 转载请著名出处 终于拿到板子了, 嵌入式开发正式开启. 板子型号 : 三星 S3C6410 基于ARM11, 指令集基于arm6指令集; 为毛不是 Cortext A9的板子; 烧 ...

  8. DM365视频处理流程/DM368 NAND Flash启动揭秘

    出自http://blog.csdn.net/maopig/article/details/7029930 DM365的视频处理涉及到三个相关处理器,分别是视频采集芯片.ARM处理器和视频图像协处理器 ...

  9. DM368 NAND Flash启动

    概要: 本文介绍了DM368 NAND Flash启动的原理,并且以DM368  IPNC参考设计软件为例,介绍软件是如何配合硬件实现启动的. 芯片上电后是如何启动实现应用功能的?这是许多工程师在看到 ...

随机推荐

  1. 【原创】大叔问题定位分享(9)oozie提交spark任务报 java.lang.NoClassDefFoundError: org/apache/kafka/clients/producer/KafkaProducer

    oozie中支持很多的action类型,比如spark.hive,对应的标签为: <spark xmlns="uri:oozie:spark-action:0.1"> ...

  2. js-检测字符串出现次数最多,并返回

    function validateStr(val){ let obj = {}; let maxNum = -1; let maxStr; for(let i=0;i<val.length;i+ ...

  3. html基础技巧:点击、placeholder、文本、字体、清楚浮动

    点击处理: 消除a标签点击后的边框,颜色(background:#fff) 1:a:focus{outline:none;} button去除边框 1:border:none 2:border:0px ...

  4. 【异常处理】Java异常如何做异常处理

    类似SpringMVC项目的异常处理可以这样做: 整个项目创建全局的: 1.一个自定义异常如OneException和错误码,统一封装所有异常. 2.一个返回实体类ResponseEntity,包含返 ...

  5. Online tools

    Explore online vulnerability for servers and IoT devices : https://www.shodan.com get dumped leaked ...

  6. Jmeter性能测试之进阶Java request的使用

    在IDE中引用Jmeter的安装目录lib/ext中两个文件ApacheJMeter_core.jar和ApacheJMeter_java.jar Java request的类需要继承Abstract ...

  7. python 列表 元组 字符串

    列表添加: list.append() list.extend() list.insert() 列表删除: list.remove()   #删除某一个元素 list.pop()  #删除某一个返回删 ...

  8. 必须了解的Object知识

    必须了解的Object知识 作为Java中所有类的根类,Object提供了很多基础的方法,我们经常会覆写它的方法,但很多时候因为不了解这些方法内在的含义以及与其他方法之间的关系而错误的覆写.下面介绍一 ...

  9. 我的 FPGA 学习历程(05)—— 使用 Modelsim 仿真工具

    在第 3 篇中讲到了如何使用图形进行仿真激励输入,图形输入法尽管简单易学,但如若要求复杂的仿真输入激励.较长的仿真时间或是要求打印输出信息乃至输出文件日志则显得不够用了. 本篇以上一篇的 3-8 译码 ...

  10. C#超简单自定义事件

    我知道你为啥点进来,所以不要犹豫了,立刻马上果断创建控制台项目,直接复制下面精干短小而又强大的代码运行: using System; using System.Collections.Generic; ...