续运行:
//puts(failed);
//hang();
分析:flash_init函数,可以打开下面函数中的调试开关:
if (!flash_detect_legacy(cfi_flash_bank_addr(i), i))
flash_get_size(cfi_flash_bank_addr(i), i);
#define DEBUG 1
#define debug 1
调试开关打开以后可以根据打印信息搜索:可知在数组jedec_table中缺少nor flash对应的数组,对应添加一项:
static const struct amd_flash_info jedec_table[] = {
// JZ2440v2使用的MT29LV160DB */
{
.mfr_id = (u16)MX_MANUFACT, // 厂家ID
.dev_id = 0X2249, // 设备ID
.name = "MXIC MT29LV160DB",
.uaddr = { // NOR flash看到解锁地址
[1] = MTD_UADDR_0x0555_0x02AA // x16
},
.DevSize = SIZE_2MiB, // 总大小
.CmdSet = P_ID_AMD_STD,
.NumEraseRegions= 4,
.regions = {
ERASEINFO(16*1024, 1),
ERASEINFO(8*1024, 2),
ERASEINFO(32*1024, 1),
ERASEINFO(64*1024, 31),
}
},
编译后测试,发现提示flash扇区太多,可以搜索后修改CONFIG_SYS_MAX_FLASH_SECT为:128
12、修改代码支持Nand Flash
u-boot已经可以Nand启动,但是并不表示u-boot启动以后可以对Nand Flash进行读写操作。
修改:
include/configs/smdk2440.h: #define CONFIG_CMD_NAND
把drivers/mtd/nand/s3c2410_nand.c复制为s3c2440_nand.c,
同时修改Makefile文件,增加:
COBJS-$(CONFIG_NAND_S3C2440) += s3c2440_nand.o
//#define CONFIG_S3C2410 // specifically a SAMSUNG S3C2410 SoC //
#define CONFIG_S3C2440 // specifically a SAMSUNG S3C2410 SoC //
#ifdef CONFIG_CMD_NAND
#ifdef CONFIG_S3C2410
#define CONFIG_NAND_S3C2410
#define CONFIG_SYS_S3C2410_NAND_HWECC
#else
#define CONFIG_NAND_S3C2440
#define CONFIG_SYS_S3C2440_NAND_HWECC
#endif
#define CONFIG_SYS_MAX_NAND_DEVICE 1
#define CONFIG_SYS_NAND_BASE 0x4E000000
#endif
分析源码:
bl board_init_r
nand_init(); // go init the NAND //
nand_init_chip(i);
if (board_nand_init(nand)) //调用nand_init初始化nand flash
修改:
a、删除:
#ifdef CONFIG_S3C2410_NAND_HWECC
#endif
之间关于ECC的代码。
b、board_nand_init:
struct s3c2440_nand *nand_reg = s3c2440_get_base_nand();
writel(readl(&clk_power->clkcon) | (1 < 4), &clk_power->clkcon);//使能nand flash控制器
...........
#if 0
cfg = S3C2410_NFCONF_EN;
cfg |= S3C2410_NFCONF_TACLS(tacls - 1);
cfg |= S3C2410_NFCONF_TWRPH0(twrph0 - 1);
cfg |= S3C2410_NFCONF_TWRPH1(twrph1 - 1);
#endif
// 初始化时序 //
cfg = ((tacls-1)<12)|((twrph0-1)<8)|((twrph1-1)<4);
writel(cfg, &nand_reg->nfconf);
// 使能NAND Flash控制器, 初始化ECC, 禁止片选 //
writel((1<4)|(1<1)|(1<0), &nand_reg->nfcont);
...........
nand->select_chip = s3c2440_nand_select;
// hwcontrol always must be implemented //
nand->cmd_ctrl = s3c2440_hwcontrol;
nand->dev_ready = s3c2440_dev_ready;
c、s3c2440_hwcontrol:
// ctrl : 表示做什么, 选中芯片/取消选中, 发命令还是发地址
//
// dat : 命令值或地址值
static void s3c2440_hwcontrol(struct mtd_info *mtd, int dat, unsigned int ctrl)
{
struct s3c2440_nand *nand = s3c2440_get_base_nand();
if (ctrl & NAND_CLE)
{
// 发命令 //
writeb(dat, &nand->nfcmd);
}
else if(ctrl & NAND_ALE)
{
// 发地址 //
writeb(dat, &nand->nfaddr);
}
}
d、增加函数s3c2440_nand_select:
static void s3c2440_nand_select(struct mtd_info *mtd, int chipnr)
{
struct s3c2440_nand *nand = s3c2440_get_base_nand();
switch (chipnr) {
case -1: // 取消选中 //
nand->nfcont |= (1<1);
break;
case 0: // 选中 //
nand->nfcont &= ~(1<1);
break;
default:
BUG();
}
}
e、s3c2440_dev_ready:
struct s3c2440_nand *nand = s3c2440_get_base_nand();
f、修改所有的s3c2410_nand为s3c2440_nand;
注意USB烧写方法:
1、因为没有裁剪的u-boot达到500K,但是我们自带的u-boot烧写分区没有