上一节修改代码后,提供了nor flash支持,但从nand flash启动,发现仍然会出现错误,故目前还不支持nand flash
继续分析arch/arm/lib/board.c,可知当系统从nand flash启动,nor flash不可见,flash_size<=0时,程序进入死循环hang();
修改代码:
取消死循环
// puts(failed);
// hang();
puts(“0 KB”);
往下可以看到,nand flash的初始化调用
nand_init();
在nand_init中
for (i = 0; i < CONFIG_SYS_MAX_NAND_DEVICE; i++)
nand_init_chip(i);
在nand_init_chip中
if (board_nand_init(nand))
return;
修改board_nand_init(位于drivers/mtd/nand/s3c2410_nand.c)
修改寄存器参数
// cfg = S3C2410_NFCONF_EN;
// cfg |= S3C2410_NFCONF_TACLS(tacls - 1);
// cfg |= S3C2410_NFCONF_TWRPH0(twrph0 - 1);
// cfg |= S3C2410_NFCONF_TWRPH1(twrph1 - 1);
cfg = ((tacls+1)<<12) | ((twrph0+1)<<8) | ((twrph1+1)<<4);
/*2410没有nfcont,2440有*/
writel((1<<4)|(1<<1)|(1<<0), &nand_reg->nfcont);
使用自己实现的片选函数
// nand->select_chip = NULL;
nand->select_chip = s3c2410_nand_select_chip;
添加片选函数
static void s3c2410_nand_select_chip(struct mtd_info *mtd, int chipnr)
{
struct s3c2440_nand *nand = s3c2410_get_base_nand();
switch(chipnr)
{
case -1:
nand->nfcont |= (1<<1);
break;
case 0:
nand->nfcont &= ~ (1<<1);
break;
}
}
board_nand_init中设置了控制函数nand->cmd_ctrl,用于控制写数据还是写地址
nand->cmd_ctrl = s3c2410_hwcontrol;
修改这个函数:
static void s3c2410_hwcontrol(struct mtd_info *mtd, int cmd, unsigned int ctrl)
{
struct s3c2440_nand *nand = s3c2410_get_base_nand();
if(ctrl & NAND_CLE)
{
writeb(cmd, &nand ->nfcmd);
}
else if (ctrl & NAND_ALE)
{
writeb(cmd, &nand ->nfaddr);
}
}
重新编译烧写即支持了nand flash