​int mtd_read_yaffs2_skip_bad(libmtd_t desc,const struct mtd_dev_info *mtd, int fd, int eb, intoffs,const char *img_name)

{int tmp, ret, out_fd, len, written = 0;intread_eb_num,i,sekOffs;intdata_length,left_to_read,readsize;

off_t seek;structstat st;char *buf,*dataAddr,*oobAddr;if (offs < 0 || offs >= mtd->eb_size) {

errmsg("bad offset %d, mtd%d eraseblock size is %d",

offs, mtd->mtd_num, mtd->eb_size);

errno=EINVAL;return -1;

}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 -1;

}

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;gotoout_close;

}

data_length= len / (mtd->subpage_size + mtd->oob_size) * mtd->subpage_size;

tmp= (offs + data_length + mtd->eb_size - 1) / 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;gotoout_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);gotoout_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 < 0){

printf("open write file error: %d \n",errno);return -1;

}while (left_to_read > 0) {int rd = 0;

ret=mtd_is_bad(mtd,fd,read_eb_num);if(ret >0){

read_eb_num= read_eb_num + 1;if(read_eb_num >= mtd->eb_cnt)

{if(left_to_read < 1){gotoout_free;

}

}else{

printf("skip bad blocks at offset: %d \n",read_eb_num);continue;

}

}else if(ret <0){

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=0;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 < 0){

printf("read data error: %d \n",errno);gotoout_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 < 0){

printf("read oob error: %d \n",errno);gotoout_free;

}

ret= write(out_fd, dataAddr, mtd->subpage_size);if(ret == -1) {

sys_errmsg("cannot write data \"%s\"", img_name);gotoout_free;

}

ret= write(out_fd, oobAddr, mtd->oob_size);if(ret == -1) {

sys_errmsg("cannot write oob \"%s\"", img_name);gotoout_free;

}

}

read_eb_num= read_eb_num +1;

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 0;

out_free:free(buf);

out_close:

close(out_fd);return -1;

}

​

Logo

北京人形旗下天工造物具身智能开源社区,聚焦具身天工与慧思开物两大平台

更多推荐