FL2440的U-boot-2009.08移植(五)uboot架构中NAND Flash驱动修改

移植NAND花了我一下午的时间才把他弄明白,解决错误的途中,我也学到了更多的东西,希望大家自己要尝试亲手移植,不要老是用别人的补丁文件,自己你懂手做了才真正是你的东西。

     

分析了一下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初始化。通过用Source Insight来做代码分析来一步步地查看函数执行过程,得出下面的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/fl2440.h中相应位置增加必要的宏定义:

#define CONFIG_CMD_NAND
/* 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
+= s3c2410_nand.o
COBJS-$(CONFIG_NAND_S3C2440) += s3c2410_nand.o 

下面的工作主要是修改drivers/mtd/nand/s3c2410_nand.c文件,首先修改27行如下

#if  0
#define NFCONF          __REGi(NF_BASE + 0x0)
#define NFCMD           __REGb(NF_BASE + 0x4)
#define NFADDR          __REGb(NF_BASE + 0x8)
#define NFDATA          __REGb(NF_BASE + 0xc)
#define NFSTAT          __REGb(NF_BASE + 0x10)
#define NFECC0          __REGb(NF_BASE + 0x14)
#define NFECC1          __REGb(NF_BASE + 0x15)
#define NFECC2          __REGb(NF_BASE + 0x16)
#endif 
#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 S3C2410_NFCONF_EN          (1<<15)
#define S3C2410_NFCONF_512BYTE     (1<<14)
#define S3C2410_NFCONF_4STEP       (1<<13)
#define S3C2410_NFCONF_INITECC     (1<<12)
#define S3C2410_NFCONF_nFCE        (1<<11)
#define S3C2410_NFCONF_TACLS(x)    ((x)<<8)
#define S3C2410_NFCONF_TWRPH0(x)   ((x)<<4)
#define S3C2410_NFCONF_TWRPH1(x)   ((x)<<0)
#define S3C2410_ADDR_NALE 4
#define S3C2410_ADDR_NCLE 8

uboot代码中的NAND Flash的读写驱动中存在一些错误,需要进行修改后才能完成,主要修改drivers/mtd/nand/s3c2410_nand.c文件,首先修改27行如下:

   修改s3c2410_hwcontrol函数  ,这个函数用来控制发送命令还是地址。board_nand_init函数。

首先声明一个全局变量 ulong IO_ADDR_W = NF_BASE; 

#ifdef CONFIG_S3C2410_NAND_HWECC  //这个宏没有定义,所以我们不用关心ECC之类的。

ulong
IO_ADDR_W = NF_BASE;
static void s3c2410_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) {
      ulong IO_ADDR_W = NF_BASE;          

 
         IO_ADDR_W = NF_BASE;
          if (!(ctrl & NAND_CLE))
                        IO_ADDR_W |= S3C2410_ADDR_NCLE;
                if (!(ctrl & NAND_ALE))
                        IO_ADDR_W |= S3C2410_ADDR_NALE;

                //chip->IO_ADDR_W = (void *)IO_ADDR_W;
              
               
           #if defined(CONFIG_S3C2440)  
        if (ctrl & NAND_NCE)  
            NFCONT&= ~S3C2410_NFCONT_nFCE;  //源码中是NFCONF,S3C2410_NFCONF_nFCE
                
        else  
           NFCONT|=
S3C2410_NFCONT_nFCE;  //源码中是NFCONF,S3C2410_NFCONF_nFCE
          #endif  
      }

     if (cmd != NAND_CMD_NONE)
         //     writeb(cmd, chip->IO_ADDR_W);
         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);

         /* initialize hardware */
        twrph0 = 0; twrph1 = 4; tacls = 2;
         cfg = 0;
        cfg |= S3C2410_NFCONF_TACLS(tacls - 1);
        cfg |= S3C2410_NFCONF_TWRPH0(twrph0 - 1);
        cfg |= S3C2410_NFCONF_TWRPH1(twrph1 - 1);
       NFCONF = cfg;
     cfg = (0<<13)|(0<<12)|(0<<10)|(0<<9)|(0<<8)|(0<<6)|(0<<5)|(1<<4)|(0<<1)|(1<<0);
     NFCONT = cfg;       

   * initialize nand_chip data structure */
        nand->IO_ADDR_R = nand->IO_ADDR_W = (void *)0x4e000010;  //NFSTAT 的地址是0x4e000010
     /* read_buf and write_buf are default */
        /* read_byte and write_byte are default */
        /* hwcontrol always must be implemented */
        nand->cmd_ctrl = s3c2410_hwcontrol;
      nand->dev_ready = s3c2410_dev_ready;

/*以下是校验码的设置,可以不用设置*/
#ifdef CONFIG_S3C2410_NAND_HWECC
        nand->ecc.hwctl = s3c2410_nand_enable_hwecc;
        nand->ecc.calculate = s3c2410_nand_calculate_ecc;
        nand->ecc.correct = s3c2410_nand_correct_data;
        nand->ecc.mode = NAND_ECC_HW3_512;
#else
        nand->ecc.mode = NAND_ECC_SOFT;
#endif
ifdef CONFIG_S3C2410_NAND_BBT
        nand->options = NAND_USE_FLASH_BBT;
#else
        nand->options = 0;
#endif
 DEBUGN("end of nand_init\n");
 return 0;
}

突然发现我自己都爱上了自己的执着精神,哈哈,回去吃完饭了。

参考地址:http://blog.csdn.net/yanghao23/article/details/7700699

时间: 2024-11-05 20:45:04

FL2440的U-boot-2009.08移植(五)uboot架构中NAND Flash驱动修改的相关文章

FL2440的U-boot-2009.08移植(三)支持Nor FLASH

如果没有Nor FLASH的同学可以跳过这一章节,直接进行下一张节.如果遇到什么问题,一般都是你没有定义那个宏之类的,这个问题可以很好的额解决. 修改norflash(nor fhash型号:JS28F320)的配置,把include/configs/fl2440.h中关于"Physical Memory Map"和"FLASH and environment organization"的配置都删掉,换成下面的配置: /*----------------------

FL2440的U-boot-2010.09移植(六)NAND Flash启动支持

 从NAND Flash启动的原理很简单,就是利用S3C2440内部4K大小的SRAM,存储在NAND Flash中的代码不能被执行,而S3C2440在从NAND Flash启动把NAND Flash的前4k代码复制到SRAM中运行,U-boot支持从NAND Flash启动的方法就是利用这前4K代码完成SDRAM的初始化(SDRAM有64M),然后还要完成从U-boot代码从NAND Flash中复制到SDRAM中,然后再跳转到SDRAM中去运行完整的U-boot.       为了便于系统启

Davinci DM6446开发攻略-UBOOT-2009.03移植2 nand flash的烧写

  很长一段时间没有更新博客了,是因为要推出新开发方案和做好客户服务工作,忙得不易乐乎.有关DAVINCI U-BOOT的移植,以前写过一篇u-boot-1.3.4(2008年的),其实和这个u-boot-2009.03差别不大,只不过这个u-boot-2009.03是从TI的网站上下载的,是DAVINCI系列最新的u-boot,也适合DM6467和DM365/368,移植的方法承接<Davinci DM6446开发攻略--u-boot-1.3.4移植(1)>,而本篇着重介绍nand flas

FL2440 Linux kernel + yaffs2根文件移植过程(一)

本文全过程为自己亲自试验,成功移植了一个最基本功能的Kernel.根文件系统,现在将这个一耗时.耗精力 的过程写下来,希望对遇到相同问题的朋友们有所帮助! 平台:飞凌FL2440             windows xp sp2             vmware 6.5.build-203739              ubuntu 9.10              交叉编译器: 4.3.2              内核:linux-2.6.28.7.tar.bz2        

全球程序员流入量最大的五座城市中印度占四席

一个顶级程序员能够对脸谱.苹果或谷歌有所贡献,但不可能从根本上改变这些大公司,而这位程序员如果加盟某个小企业,他要么失败,要么 就会成为百万富翁.在印度软件猎头公司骇客排名的联合创建人维维克拉夫森克看来,尽管美国硅谷正开出远超以往的高薪吸引印度顶级软件人才,但现如今印度才应是全球信息技术精英的向往之地.他在最近结束的一次网上程序员招募大赛后表示,目前全球程序员流入量最大的五座城市中,印度占四席,印度程序员不再 一心向往美国.印度软件人才市场近几年正在经历残酷的优胜劣汰.目前,印度有超过400所大

Spring Boot与Docker(二):使用Spring Boot和Docker构建微服务架构

本文讲的是Spring Boot与Docker(二):使用Spring Boot和Docker构建微服务架构,[编者的话]本篇是<使用Spring Boot和Docker构建微服务架构>系列的第二篇,本篇我们将会利用工具进行设置,深入探讨如何使用Docker工作,然后搭建我们的第一个容器.原文作者为3Pillar环球旗下美国Adbanced技术集团的总监Dan Greene,Dan有十八年的软件设计和开发经验,包括在电子商务.B2B集成.空间分析.SOA架构.大数据以及云计算等领域的软件产品架

android-libGDX移植游戏到iphone中

问题描述 libGDX移植游戏到iphone中 使用libGDX往iPhone中移植了一个游戏.在Android系统中游戏有后退键,在iPhone中有没有类似的键?还是需要做一个屏幕后退键来代替? 谢谢.

mw300r-openwrt uboot移植,uboot跑起来后读取文件出错

问题描述 openwrt uboot移植,uboot跑起来后读取文件出错 我用的是mw300r的板子,然后想把8Mflash换成4Mflash,但是怎么组都出错,求解答啊.急!!或者哪位大神知道firmware和art文件在falsh里面的存放位置不.下面出错的情况截图 解决方案 那不是上面提示你了,地址超出了,估计dts文件没配置好,我已经给你原来的问dts文件意思那发了一个文档的下载地址,好好看看,希望对你有用

嵌入式-自己移植了uboot现在想通过usb来烧写Linux内核,该怎么办?表示网络下载不了

问题描述 自己移植了uboot现在想通过usb来烧写Linux内核,该怎么办?表示网络下载不了 自己移植了uboot现在想通过usb来烧写Linux内核,该怎么办?表示网络下载不了 解决方案 不同的硬件用的软件不太一样,你的开发包应该有工具.再不行google下.什么叫网络下载不了. 参考下http://blog.sina.com.cn/s/blog_726c4bd20100unjn.htmlhttp://bbs.ednchina.com/BLOG_ARTICLE_3019734.HTM 解决方