Sum of regions (1000000) != total size of set of interleaved chips (800000)
有关cfi->cfiq->EraseRegionInfo值的问题。原来用的am29lv033c 8bit 4M,cfi->cfiq->NumEraseRegions等于1,换成了sst39vf6401b 16bit 8M,cfi->cfiq->NumEraseRegions等于2,可以sector/block 擦除。我不太明白这个值是什么作用?
这个函数输出: Sum of regions (1000000) != total size of set of interleaved chips (800000)
很明显它把sst39vf6401b认成2*8=16M了。怎样修改?
Thank you!
static struct mtd_info *cfi_amdstd_setup(struct map_info *map)
{
struct cfi_private *cfi = map->fldrv_priv;
struct mtd_info *mtd;
unsigned long devsize = (1<<cfi->cfiq->DevSize) * cfi->interleave;
unsigned long offset = 0;
int i,j;
mtd = kmalloc(sizeof(*mtd), GFP_KERNEL);
printk(KERN_NOTICE "number of %s chips: %d\n",
(cfi->cfi_mode == CFI_MODE_CFI)?"CFI":"JEDEC",cfi->numchips);
if (!mtd) {
printk(KERN_WARNING "Failed to allocate memory for MTD device\n"
goto setup_err;
}
memset(mtd, 0, sizeof(*mtd));
mtd->priv = map;
mtd->type = MTD_NORFLASH;
/* Also select the correct geometry setup too */
mtd->size = devsize * cfi->numchips;
mtd->numeraseregions = cfi->cfiq->NumEraseRegions * cfi->numchips;
mtd->eraseregions = kmalloc(sizeof(struct mtd_erase_region_info)
* mtd->numeraseregions, GFP_KERNEL);
if (!mtd->eraseregions) {
printk(KERN_WARNING "Failed to allocate memory for MTD erase region info\n"
goto setup_err;
}
for (i=0; i<cfi->cfiq->NumEraseRegions; i++) {
unsigned long ernum, ersize;
ersize = ((cfi->cfiq->EraseRegionInfo >> & ~0xff) * cfi->interleave;
ernum = (cfi->cfiq->EraseRegionInfo & 0xffff) + 1;
if (mtd->erasesize < ersize) {
mtd->erasesize = ersize;
}
for (j=0; j<cfi->numchips; j++) {
mtd->eraseregions[(j*cfi->cfiq->NumEraseRegions)+i].offset = (j*devsize)+offset;
mtd->eraseregions[(j*cfi->cfiq->NumEraseRegions)+i].erasesize = ersize;
mtd->eraseregions[(j*cfi->cfiq->NumEraseRegions)+i].numblocks = ernum;
}
offset += (ersize * ernum);
}
if (offset != devsize) {
/* Argh */
printk(KERN_WARNING "Sum of regions (%lx) != total size of set of interleaved chips (%lx)\n", offset, devsize);
goto setup_err;
}#if 0
// debug
for (i=0; i<mtd->numeraseregions;i++){
printk("%d: offset=0x%x,size=0x%x,blocks=%d\n",
i,mtd->eraseregions.offset,
mtd->eraseregions.erasesize,
mtd->eraseregions.numblocks);
}
#endif
if (mtd->numeraseregions == 1
&& ((cfi->cfiq->EraseRegionInfo[0] & 0xffff) + 1) == 1) {
mtd->erase = cfi_amdstd_erase_chip;
} else {
mtd->erase = cfi_amdstd_erase_varsize;
mtd->lock = cfi_amdstd_lock_varsize;
mtd->unlock = cfi_amdstd_unlock_varsize;
}
if ( cfi->cfiq->BufWriteTimeoutTyp && !FORCE_WORD_WRITE) {
DEBUG(MTD_DEBUG_LEVEL1, "Using buffer write method\n" );
mtd->write = cfi_amdstd_write_buffers;
} else {
DEBUG(MTD_DEBUG_LEVEL1, "Using word write method\n" );
mtd->write = cfi_amdstd_write_words;
}
mtd->read = cfi_amdstd_read;
/* FIXME: erase-suspend-program is broken. See
http://lists.infradead.org/piper ... ecember/009001.html */
printk(KERN_NOTICE "cfi_cmdset_0002: Disabling erase-suspend-program due to code brokenness.\n"
/* does this chip have a secsi area? */
if(cfi->mfr==1){
switch(cfi->id){
case 0x50:
case 0x53:
case 0x55:
case 0x56:
case 0x5C:
case 0x5F:
/* Yes */
mtd->read_user_prot_reg = cfi_amdstd_secsi_read;
mtd->read_fact_prot_reg = cfi_amdstd_secsi_read;
default:
;
}
}
mtd->sync = cfi_amdstd_sync;
mtd->suspend = cfi_amdstd_suspend;
mtd->resume = cfi_amdstd_resume;
mtd->flags = MTD_CAP_NORFLASH;
map->fldrv = &cfi_amdstd_chipdrv;
mtd->name = map->name;
__module_get(THIS_MODULE);
return mtd;
setup_err:
if(mtd) {
if(mtd->eraseregions)
kfree(mtd->eraseregions);
kfree(mtd);
}
kfree(cfi->cmdset_priv);
kfree(cfi->cfiq);
return NULL;
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
EraseRegionInfo的意义如下,有的flash所有的块中有是一部分不可写,一部分可写,有的是全部是一样的可写的块比如16K,有的是一部分8K一部分16K,有的是全部16K的同时一部分还支持8K,这个就要不同的EraseRegionInfo来标志。
interleave还是按我前面那个帖子里说的是并列的意思,如果的你的是一个flash那就是1,而你这里估计是2,是因为在config文件里的配置是1而实际按2算的(实际是配置config是1,生成config还是2),可能是bug吧,在程序里强制变为1的方法我在前面的帖子里提到,至于这个问题详细是怎么产生的当时解决问题后就没有再看了。有兴趣可以研究下。
[ 本帖最后由 smalloc 于 2007-10-27 12:45 编辑 ]
sst39vf6401b就是支持4k和64k擦写的,所以有2种EraseRegionInfo。现在我就采用64k的方式,去掉4k方式。
mtd->eraseregions[0].offset = 0;
mtd->eraseregions[0].erasesize = 0x10000;
mtd->eraseregions[0].numblocks = 0x80;
程序能跑起来,我在文件系统建立文件,重启,文件依然保留。成功了。但是去掉了4k block的擦写,可能还有潜在问题。现在项目急,以后有时间要好好研究。
还有个问题想请教,在应用层写个程序能否直接修改arm的寄存器?
在应用层写个远程升级的程序,要把tftp下载的文件写到flash的指定地址,是不是需要写操作flash的driver,然后在应用层调用,这个driver不知应该怎么写?
谢谢俄i!
需要写字符驱动
RAMDISK文件系统是全部读到RAM中的,所以可以把数据写到falsh中,比如升级程序