u-boot在S3C2440上的移植问题及解决方法集锦(一)

来源:互联网 发布:网络协议工作原理 编辑:程序博客网 时间:2024/06/09 15:58

一、移植环境

  • 主   机:VMWare6.5--Fedora 9
  • 开发板:自制开发板

              CPU:S3C2440;    SDRAM:HY57V561620FTP-H;    NOR flash:SST_39VF1601(2M);

              NAND flash:K9F1G08U0B(128M);    网卡芯片:DM9000EP

  • 编译器:arm-linux-gcc-4.3.2
  • u-boot:u-boot-2009.08
  • linux kernel:linux-2.6.30
  • busybox:busybox-1.13.3

二、博客地址

      http://blog.csdn.net/liuqiqi677

      如有错误,欢迎指正。

三、参考资料

      主要参考了黄刚的博客http://blogold.chinaunix.net/u3/101649/ ,他的博客写得相当不错,将嵌入式开发各个阶段的知识以边做边学的方式,辅以图片、解释,清晰地呈现给读者,能够让读者把握主线,对嵌入式开发有整体的了解。强烈推荐!!!

四、问题及解决方法

      1、NAND flash(K9F1G08U0B)的寻址方案

      开始照着黄刚的博客进行u-boot移植,u-boot从NOR flash启动比较顺利,但是从NAND flash启动时,就遇到问题了,u-boot不能完全启动!通过在程序中插入点led灯的方法,将问题定位在了NAND flash的读取函数nand_read_ll中对NAND flash单元进行寻址的几条指令上。这时,问题大概有眉目了,黄刚所用的开发板是友善之臂的mini2440,上面的NAND flash的型号是K9F1208,容量为64M,与我所用的芯片不一样。下面比较一下这两款芯片的寻址方案:

图1 K9F1208寻址方案

图2 K9F1G08寻址方案

      黄刚博客中K9F1208的寻址代码是:

       NFADDR = i & 0xFF;
       NFADDR = (i >> 9) & 0xFF;
       NFADDR = (i >> 17) & 0xFF;
       NFADDR = (i >> 25) & 0xFF;

      而我的K9F1G08的寻址代码则是:

       NFADDR = 0;
       NFADDR = 0;
       NFADDR = (i >> 11) & 0xFF;
       NFADDR = (i >> 19) & 0xFF;
       NFADDR = (i >> 27) & 0xFF;

      但是,这里又出现三个问题了:(1) K9F1G08的寻址方案只有4个周期,而我的代码却有5个周期;(2) 为什么前两个周期我给的值都是0;(3) 按照芯片手册,第3-5个周期起,移位操作应该分别为(i >> 12)、(i >> 20)、(i >> 28),那为什么却是上面那样的呢?一开始,我也是挺纳闷的,但是通过查找资料与不断试验,终于弄懂了这些原因。

      (1) 5个周期主要是为了兼容NAND flash容量大于128M的芯片。下面贴上K9F2G08的寻址方案,可以看出,它有5个寻址周期。而我们的K9F1G08在执行寻址代码的时候,会忽略掉周期大于4的部分,也就是说,只有前面4个周期才是有效的,才是它用来寻址的,第5个周期的数据就算写给它了,它也不会拿去用。

图3 K9F2G08寻址方案

      (2) NAND flash进行读操作是以页为单位,前2个周期的值表示页内偏移量,因此,前两个周期传给NAND flash的值为0,表示读操作是从每页的起始单元(及页内偏移量为0)开始的。

      (3) 这个问题纠结了半天,按照芯片手册,K9F1G08一页的大小是2KB,A0 --A10 就刚好能够完全寻址了。那么,这个A11 又是干什么的呢?网上有一种说法,NAND flash的每一页除了2KB的数据区,还有64 Bytes的OOB数据,这样每一页就有2112 Bytes的单元,A0 --A10 就不够了,而A0 --A11 能够寻址的单元数是4096,能够包含这64 Bytes的OOB数据。但是,我试过将偏移量改成(i >> 12)、(i >> 20)、(i >> 28),但是这样无法读出NAND flash中的数据,那么,这种说法是站不住脚的。网上还有一种说法,OOB数据是用另外的指令去读的,而芯片手册上可能是三星公司的笔误,虽然这种说法看似可能性较小,但是我觉得这个是目前为止解释最合理的一种,大公司也难免会有失误嘛。

      2、将u-boot拷到其它目录,不能正常编译

      我将u-boot拷到另一台主机上,并且换了一个目录,原来是在/opt/ARM/下,到新主机中,放到了/root/目录下,我在新主机中输入make指令,重新编译,在编译的过程中,出现错误 No rule to make target '*', needed by '/opt/ARM/*'。分析原因,是因为这个u-boot保留了原来的一些编译信息,它还是从就主机的那个目录下去寻找文件。于是,我执行make clean,make两条指令,还是报之前的错误。看来make clean将编译信息清除得还不够彻底。看来,只有用杀手锏了--make distclean,make my2440_config,make三条指令,编译成功了!

      下面,比较一下make clean,make distclean两条指令有什么不同。

      make clean清除上次make命令所产生的object文件(后缀为“.o”的文件)及可执行文件;make distclean要清除所有生成的文件。

      3、NAND 128MiB 3,3v 8-bit: MTD Erase failure: -22

      我在超级终端中,用saveenv命令将环境变量保存到NAND flash中时,提示了上面的错误信息。分析一下,意思是对NAND flash进行擦除操作时出现了错误。NAND flash在写操作之前会进行一次擦除操作,并且以块为单位进行擦除。我所使用的K9F1G08块的大小为128KB,而黄刚使用的K9F1208块的大小为64KB。因此,将 include/configs/my2440.h 中将环境变量区域的偏移位置及大小改成以下的值:

    #define CONFIG_ENV_IS_IN_NAND 1
    #define CONFIG_ENV_OFFSET 0x40000 //将环境变量保存到nand中的0x40000位置,必须在块的起始位置
      

    #define CONFIG_ENV_SIZE 0x20000 //环境变量区的大小,必须为块大小的整数倍则会提示下面的信息,将擦除整个块

            Warning: Erase size 0x00010000 smaller than one erase block 0x00020000
            Erasing 0x00020000 instead

      在后面对NAND flash进行分区的时候也要考虑这个问题,否则依然会出现这个错误。

      今天就写到这里,呵呵,问题还有很多,明天继续总结。^_^

原创粉丝点击