平台:
硬件:s3c2440 + 64MB(SDRAM) + 256MB(nand flash->K9F2G08U0C)
软件:u-boot-2011.12 + linux-3.1.6
要支持硬件ecc就必须保证u-boot和linux内核的ecc校验模式、算法一样。由于内核已经做好了2440硬件ecc的支持,所以以内核为标准修改u-boot。
1、linux内核部分
打开2440硬件ecc支持.
内核关键源文件:/drivers/mtd/nand/s3c2410.c,注意红色部分
关键函数:
static void s3c2410_nand_update_chip(struct s3c2410_nand_info *info,
struct s3c2410_nand_mtd *nmtd)
{
struct nand_chip *chip = &nmtd->chip;
dev_dbg(info->device, "chip %p => page shift %d\n",
chip, chip->page_shift);
if (chip->ecc.mode != NAND_ECC_HW)
return;
/* change the behaviour depending on wether we are using
* the large or small page nand device */
if (chip->page_shift > 10) {
chip->ecc.size = 256;
chip->ecc.bytes = 3;
} else {
chip->ecc.size = 512;
chip->ecc.bytes = 3;
chip->ecc.layout = &nand_hw_eccoob;
}
}
2、u-boot部分
据此修改u-boot源码
在u-boot全局配置头文件,我的是include/configs/dhole2440.h添加如下宏
#define CONFIG_S3C2440_NAND_HWECC /*打开nand flash硬件ecc支持*/
#ifdef CONFIG_S3C2440_NAND_HWECC
#define CONFIG_SYS_NAND_ECCSIZE 256 /*每次ecc数据块大小,对应内核的chip->ecc.size*/
#define CONFIG_SYS_NAND_ECCBYTES 3 /*校验结果为3个字节,对应内核的chip->ecc.bytes*/
#endif
修改drivers/mtd/nand/s3c2440_nand.c源文件的硬件ecc部分代码,因为u-boot默认没提供对s3c2440的支持。
void s3c2440_nand_enable_hwecc(struct mtd_info *mtd, int mode)
{
struct s3c2440_nand *nand = s3c2440_get_base_nand();
writel(readl(&nand->nfcont) | S3C2440_NFCONT_INITECC, &nand->nfcont);
}
static int s3c2440_nand_calculate_ecc(struct mtd_info *mtd, const u_char *dat,
u_char *ecc_code)
{
struct s3c2440_nand *nand = s3c2440_get_base_nand();
unsigned long ecc = readl(&nand->nfmecc0);
ecc_code[0] = ecc;
ecc_code[1] = ecc >> 8;
ecc_code[2] = ecc >> 16;
return 0;
}
static int s3c2440_nand_correct_data(struct mtd_info *mtd, u_char *dat,
u_char *read_ecc, u_char *calc_ecc)
{
if (read_ecc[0] == calc_ecc[0] &&
read_ecc[1] == calc_ecc[1] &&
read_ecc[2] == calc_ecc[2])
return 0;
return -1;
}
可以发现只提供了3字节ecc支持,这是为了兼容linux内核的ecc.
重新编译u-boot和linux内核就ok了。
阅读(960) | 评论(0) | 转发(0) |