u-boot-2009.08在飞凌OK2440/FL2440上的移植(四)——让u-boot支持nand flash识别与操作
来源:互联网 发布:ubuntu使用搜狗输入法 编辑:程序博客网 时间:2024/04/30 09:39
分析了一下Uboot中Nandflash的驱动,u-boot-2009.08使用的是和Linux内核一样的MTD(内存技术设备)架构。在Uboot下对Nand的支持体现在命令行下实现对nand flash的操作,为:nand info,nand device,nand read,nand write,nand erease,nand bad。用到的主要数据结构有:struct nand_flash_dev,struct nand_chip。前者包括主要的芯片型号,存储容量,设备ID,I/O总线宽度等信息;后者是具体对nand flash进行操作时用到的信息。
u-boot启动到第二个阶段后,在/cpu/arm920t/board.c这个文件中start_armboot函数里,有下面的代码:
#if defined(CONFIG_CMD_NAND)
puts ("NAND: ");
nand_init(); /* go init the NAND */
#endif
所以,我们只要定义了CONFIG_CMD_NAND这个宏,就会开始nand初始化。通过用KScope(Linux下的一个不错的IDE,可用来做代码分析)来一步步地查看函数执行过程,得出下面的nand执行流程:
1./cpu/arm920t/board.c文件中的start_armboot函数调用/drivers/mtd/nand/nand.c文件中的nand_init函数;
2.nand_init调用同文件下的nand_init_chip函数;
3.nand_init_chip函数调用/drivers/mtd/nand/s3c2410_nand.c文件下的board_nand_init函数,然后再调用/drivers/mtd/nand/nand_base.c函数中的nand_scan函数;
4.s3c2410_nand.c就是我们做移植需要实现的文件,是与具体的硬件密切相关的。
5.nand_scan函数会调用同文件下的nand_scan_ident等函数。
从这里我们得知,我们要把nand移植到2440上,就要修改s3c2410_nand.c这个文件!因为对nand flash的操作,实际上就是对nand控制器的操作,而2440的nand控制器和2410相比,有很大的不同!我们的修改工作量主要也是在这里。
首先在include/configs/ok2440v3.h中相应位置增加必要的宏定义:
**********************************************************************************************************************************************************
/*
* Command line configuration.
*/
..........................
#define CONFIG_CMD_NAND
#define CONFIG_CMDLINE_EDITING
#ifdef CONFIG_CMDLINE_EDITING
#undef CONFIG_AUTO_COMPLETE
#else
#define CONFIG_AUTO_COMPLETE
#endif
/* NAND flash settings */
#if defined(CONFIG_CMD_NAND)
#define CONFIG_SYS_NAND_BASE 0x4E000000
#define CONFIG_SYS_MAX_NAND_DEVICE 1
#define CONFIG_MTD_NAND_VERIFY_WRITE 1
#define NAND_SAMSUNG_LP_OPTIONS 1 /*注意,这个定义很重要,因为我们用的是大块nand!!我就是因为没定义这里卡了较长时间 */
#undef CONFIG_ENV_IS_IN_FLASH
#define CONFIG_ENV_IS_IN_NAND 1 /* 环境变量的保存位置 */
#endif
********************************************************************************************************************************************************
修改/drivers/mtd/nand/Makefile,在其中添加:
COBJS-y += s3c2440_nand.o
COBJS-$(CONFIG_NAND_S3C2440) += s3c2440_nand.o
把/drivers/mtd/nand/s3c2410_nand.c复制并重命名为s3c2440_nand.c,因为s3c2410和s3c2440在nand控制器方面有很多不同,所以要进行移植,我们最重要的是修改当前的s3c2440_nand.c,
修改s3c2440_nand.c:
#if 0
#define DEBUGN printf
#else
#define DEBUGN(x, args ...) {}
#endif
#include <nand.h>
#include <s3c2410.h>
#include <asm/io.h>
#define __REGb(x) (*(volatile unsigned char *)(x))
#define __REGi(x) (*(volatile unsigned int *)(x))
#define NF_BASE 0x4e000000
#define NFCONF __REGi(NF_BASE + 0x0)
#define NFCONT __REGi(NF_BASE + 0x4)
#define NFCMD __REGb(NF_BASE + 0x8)
#define NFADDR __REGb(NF_BASE + 0xc)
#define NFDATA __REGb(NF_BASE + 0x10)
#define NFMECCD0 __REGi(NF_BASE + 0x14)
#define NFMECCD1 __REGi(NF_BASE + 0x18)
#define NFSECCD __REGi(NF_BASE + 0x1C)
#define NFSTAT __REGb(NF_BASE + 0x20)
#define NFSTAT0 __REGi(NF_BASE + 0x24)
#define NFSTAT1 __REGi(NF_BASE + 0x28)
#define NFMECC0 __REGi(NF_BASE + 0x2C)
#define NFMECC1 __REGi(NF_BASE + 0x30)
#define NFSECC __REGi(NF_BASE + 0x34)
#define NFSBLK __REGi(NF_BASE + 0x38)
#define NFEBLK __REGi(NF_BASE + 0x3c)
#define S3C2440_NFCONT_nCE (1<<1)
#define S3C2440_ADDR_NALE 0x0c
#define S3C2440_ADDR_NCLE 0x08
ulong IO_ADDR_W = NF_BASE;//增加一个全局变量
static int s3c2440_dev_ready(struct mtd_info *mtd)
{
DEBUGN("dev_ready\n");
return (NFSTAT & 0x01);
}
static void s3c2440_hwcontrol(struct mtd_info *mtd, int cmd, unsigned int ctrl)
{
struct nand_chip *chip = mtd->priv;
DEBUGN("hwcontrol(): 0x%02x 0x%02x\n", cmd, ctrl);
if (ctrl & NAND_CTRL_CHANGE) {
IO_ADDR_W = NF_BASE;
if (!(ctrl & NAND_CLE)) //要写的是地址
{
IO_ADDR_W |= S3C2440_ADDR_NALE;}
if (!(ctrl & NAND_ALE)) //要写的是命令
{
IO_ADDR_W |= S3C2440_ADDR_NCLE;}
if (ctrl & NAND_NCE)
{NFCONT &= ~S3C2440_NFCONT_nCE; //使能nand flash
//DEBUGN("NFCONT is 0x%x ",NFCONT);
//DEBUGN("nand Enable ");
}
else
{NFCONT |= S3C2440_NFCONT_nCE; //禁止nand flash
//DEBUGN("nand disable ");
}
}
if (cmd != NAND_CMD_NONE)
writeb(cmd,(void *)IO_ADDR_W);
}
int board_nand_init(struct nand_chip *nand)
{
u_int32_t cfg;
u_int8_t tacls, twrph0, twrph1;
S3C24X0_CLOCK_POWER * const clk_power = S3C24X0_GetBase_CLOCK_POWER();
DEBUGN("board_nand_init()\n");
clk_power->CLKCON |= (1 << 4);
DEBUGN("CONFIG_S3C2440\n");
twrph0 = 4; twrph1 = 2; tacls = 0;
cfg = (tacls<<12)|(twrph0<<8)|(twrph1<<4);
NFCONF = cfg;
//DEBUGN("cfg is %x\n",cfg);
//DEBUGN("NFCONF is %lx\n",NFCONF);
cfg = (1<<6)|(1<<4)|(0<<1)|(1<<0);
NFCONT = cfg;
//DEBUGN("cfg is %lx\n",cfg);
//DEBUGN("NFCONT is %x\n",NFCONT);
/* initialize nand_chip data structure */
nand->IO_ADDR_R = nand->IO_ADDR_W = (void *)0x4e000010;
/* read_buf and write_buf are default */
/* read_byte and write_byte are default */
/* hwcontrol always must be implemented */
nand->cmd_ctrl = s3c2440_hwcontrol;
nand->dev_ready = s3c2440_dev_ready;
return 0;
}
s3c2440_hwcontrol函数主要控制是写命令还是写地址。
我遇到的问题,由于board_nand_init()函数我没有添加return 0,导致后面的判断没法进行,结果读出的NAND为0MiB,所以移植一定要仔细阅读源码,还有个问题就是uboot的打印信息中出现NAND_ECC_NONE selected by board driver. This is not recommended!!,据说这跟ECC的校验模式有关,但不影响,我后来把这个直接注释掉。
此时就能进行nand命令的基本操作,nand info、nand dump、nand read、nand write;如下图:
感谢网上的各位大牛,本博文主要参考:
- http://helloyesyes.iteye.com/blog/1071268
- http://www.360doc.com/content/12/1215/19/532901_254233098.shtml
- u-boot-2009.08在飞凌OK2440/FL2440上的移植(四)——让u-boot支持nand flash识别与操作
- u-boot-2009.08在飞凌OK2440/FL2440上的移植(五)——让u-boot从nand flash启动
- u-boot-2009.08在飞凌OK2440/FL2440上的移植(三)——让u-boot支持DM9000A
- u-boot-2009.08在飞凌OK2440/FL2440上的移植(二)——让u-boot支持从nor flash 启动
- u-boot-2009.08在飞凌OK2440/FL2440上的移植(一)——让u-boot在内存中运行进来
- u-boot-2009.08在飞凌OK2440/FL2440上的移植(六)——让u-boot引导内核启动
- u-boot-2011.03在mini2440/micro2440上的移植(五)——支持Nand Flash
- U-Boot 的移植入门(2)——nand flash识别与操作
- fl2440的U-boot-2010.09移植(六)NAND Flash启动支持
- u-boot-2011.03在mini2440/micro2440上的移植(七)——支持Nand Flash启动
- u-boot移植(四)使支持NAND FLASH
- fl2440的U-boot-2010.09移植(四) 添加NOR Flash启动支持
- u-boot-2009.08在mini2440上的移植(三)---增加nand flash功能——调试心得
- u-boot-2009.08在mini2440上的移植(三)---增加nand flash功能
- U-Boot移植——Nand Flash
- TQ2440 u-boot-2012.04.01移植四支持NAND Flash
- u-boot-2011.03在mini2440/micro2440上的移植(四)——支持内核启动
- fl2440——u-boot的移植
- http文件下载
- SQLPlus命令详细说明
- 【POJ】【P3237】【Tree】【题解】【树链剖分+线段树】
- jquery 键盘enter事件的小例子
- 如何养成读书的好习惯
- u-boot-2009.08在飞凌OK2440/FL2440上的移植(四)——让u-boot支持nand flash识别与操作
- 36 双端堆
- 【OpenCV入门教程之十二】OpenCV边缘检测:Canny算子,Sobel算子,Laplace算子,Scharr滤波器合辑
- 软考——公钥和私钥
- 基于hadoop2.2的map端表关联(map side join)mapreduce实现
- SQLLDR详解与例子
- 9.2
- 关于在集合中加入StringBuffer的问题
- android创建sqlite数据库及在SD卡上创建数据库