- 论坛徽章:
- 0
|
回复 #1 Roemer 的帖子
我没有非常详细的跟踪内核flash驱动的那部分代码,但是可以告诉你的是此处给出的警告无关紧要,不会对你的flash的正常运行构成任何影响。正如你所说,在很多使用flash的嵌入式系统中,一般在启动信息中都会有这个打印信息,事实上,更准确的说,在使用AMD/Fujitsu Nor Flash类型的所有嵌入式系统中,只要内核对于Flash配置正确,都会打印此信息。
该信息来自drivers/mtd/chips/cfi_cmdset_0002.c文件cfi_amdstd_setup函数末尾处。
具体调用流程如下(符合CFI接口标准的FLASH初始化流程):
drivers/mtd/maps/yourdriver.c:yourdriver_init (Flash驱动一般的入口方式,也有使用
platform device方式的,此处不论。)
|
v
drivers/mtd/chips/chipreg.c:do_map_probe
|
v
drivers/mtd/chips/cfi_probe.c:cfi_probe
|
v
drivers/mtd/chips/gen_probe.c:mtd_do_chip_probe
|
v
drivers/mtd/chips/gen_probe.c:check_cmd_set
|
v
drivers/mtd/chips/cfi_cmdset_0002.c:cfi_cmdset_0002
|
v
drivers/mtd/chips/cfi_cmdset_0002.c:cfi_amdstd_setup
cfi_amdstd_setup函数实现如下(2.6.22内核):
static struct mtd_info *cfi_amdstd_setup(struct mtd_info *mtd)
{
struct map_info *map = mtd->priv;
struct cfi_private *cfi = map->fldrv_priv;
unsigned long devsize = (1<<cfi->cfiq->DevSize) * cfi->interleave;
unsigned long offset = 0;
int i,j;
printk(KERN_NOTICE "number of %s chips: %d\n",
(cfi->cfi_mode == CFI_MODE_CFI)?"CFI":"JEDEC",cfi->numchips);
/* Select the correct geometry setup */
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
/* 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"
__module_get(THIS_MODULE);
return mtd;
setup_err:
if(mtd) {
kfree(mtd->eraseregions);
kfree(mtd);
}
kfree(cfi->cmdset_priv);
kfree(cfi->cfiq);
return NULL;
}
注意函数末尾处的printk调用打印的就是你询问的问题,你可以看到这个打印并不依赖于任何其他宏定义,它只是一个警告。如果需要解释一下,那么就是:
内核flash代码没有对flash erase-suspend方式进行支持。
如果你阅读过某一flash手册(其实所有CFI接口规范的flash手册都大同小异),你会看到
flash有一个suspend命令,可以对当前执行的命令进行挂起,还有一个resume命令,可以启动之前挂起的flash操作。
flash的擦除是按block(1 block 一般等于64kB)方式擦除的。那么以上的意思就是在flash擦除过程中内核代码不支持挂起再启动的操作,即如果发出命令擦除10个block,那么内核要么被中断擦除操作(ctrl+c),要么全部擦除完成;不支持我先擦除7个block,挂起一会,再擦除剩下的3个block。
实际上,这种方式不会对flash的正常工作造成任何影响,一般我们自己在写flash驱动时,大多也不支持erase-suspend操作,更进一步,大多数时候suspend, resume命令根本就不使用!
综上所述,以上打印的警告信息完全可以忽略不计,而非内核不提供flash驱动。为避免用户“紧张”,你完全可以将这个打印信息注释掉! |
|