Chinaunix首页 | 论坛 | 博客
  • 博客访问: 173493
  • 博文数量: 23
  • 博客积分: 348
  • 博客等级: 一等列兵
  • 技术积分: 235
  • 用 户 组: 普通用户
  • 注册时间: 2012-10-02 16:34
个人简介

System Software Engineer

文章分类

全部博文(23)

文章存档

2013年(9)

2012年(14)

分类:

2012-12-14 12:50:20

原文地址:调试U-Boot笔记(五) 作者:hevake_lcj

    昨天,我们修改了u-boot中的部分代并成功地用AXD把我们的u-boot跑起来了。这是一个很大的成就!我们不能自满,今天将再接再厉,进一步探索。

    我们今天的目标是:使将u-boot烧录到NandFlash与NorFlash,并使之正常启动。

    接着昨天的试验,我们的程序能够通过AXD运行起来,那么我们把程序用JLink命令加载到Mini2440上也应该可以正常运行。我们来试一下……

    打开J-Link Commander程序。还是老步骤,先下载init.bin文件到0x40000000地址上并运行起来,等其完成了SDRAM的初始化之后,再将我们编译的u-boot.bin下载到0x33f80000地址上。依次键入如下命令:
    > r
    > loadbin e:\init.bin 0x40000000
    > setpc 0x40000000
    > g
    看一下开发板上的LED有没有正常闪烁,如有则继续:
    > h
    > loadbin e:\u-boot-gdb\u-boot.bin 0x33f80000
    > setpc 0x33f80000
    > g

    OK!此时我已听到一声蜂鸣器叫的声音,我们来看一下串口终端的显示:
   

    这已说明我们的u-boot启动起来了。

    然后,我们试一下将我们的u-boot写入到NandFlash去,我在笔记(一)中有写其中的过程。
    (1)用J-Link Commander将u-boot.bin导入到0x30000000的地址上去。
    (2)在串口终端中执行u-boot命令将0x30000000地址上的数据写到NandFlash中去。

    好,我们马上开始。我们在JLink命令行里输入以下命令:
    > h
    > loadbin e:\u-boot-gdb\u-boot.bin 0x30000000
    > g

    然后我们转向串口调试终端,执行U-boot命令:

    看来并没有想像中的那么顺利,在烧写NorFlash的时候还是遇到以前同样的问题。至于烧写到NandFlash,也失败了。

    烧写NorFlash时出现以下错误:
   

    错误是:General Flash Programming Error
    我把这个错误哪到源码里去搜索了一下,其在:
   

    打开该文件看看,查为flash_perror(int err)函数在执行。而该函数只负责打印错误信息。
    查到cp命令的执行函数,为 common/cmd_mem.c文件中的 do_mem_cp()。
   

    跟踪 do_mem_cp() 函数:

点击(此处)折叠或打开

  1. int do_mem_cp ( cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
  2. {
  3.     ulong    addr, dest, count;
  4.     int    size;

  5.     if (argc != 4) {
  6.         printf ("Usage:\n%s\n", cmdtp->usage);
  7.         return 1;
  8.     }

  9.     /* Check for size specification.
  10.     */
  11.     if ((size = cmd_get_data_size(argv[0], 4)) < 0)
  12.         return 1;

  13.     addr = simple_strtoul(argv[1], NULL, 16);
  14.     addr += base_address;

  15.     dest = simple_strtoul(argv[2], NULL, 16);
  16.     dest += base_address;

  17.     count = simple_strtoul(argv[3], NULL, 16);

  18.     if (count == 0) {
  19.         puts ("Zero length ???\n");
  20.         return 1;
  21.     }

  22. #ifndef CFG_NO_FLASH
  23.     /* check if we are copying to Flash */
  24.     if ( (addr2info(dest) != NULL)
  25. #ifdef CONFIG_HAS_DATAFLASH
  26.      && (!addr_dataflash(addr))
  27. #endif
  28.      ) {
  29.         int rc;

  30.         puts ("Copy to Flash... ");

  31.         rc = flash_write ((char *)addr, dest, count*size);
  32.         if (rc != 0) {
  33.             flash_perror (rc);
  34.             return (1);
  35.         }
  36.         puts ("done\n");
  37.         return 0;
  38.     }
  39. #endif

  40.     ……

  41.     while (count-- > 0) {
  42.         if (size == 4)
  43.             *((ulong *)dest) = *((ulong *)addr);
  44.         else if (size == 2)
  45.             *((ushort *)dest) = *((ushort *)addr);
  46.         else
  47.             *((u_char *)dest) = *((u_char *)addr);
  48.         addr += size;
  49.         dest += size;
  50.     }
  51.     return 0;
  52. }

    重点观察L36~46之间的代码,这段代码的意思就是将数据复制到NorFlash中去。要想知道为什么烧写不成功,还得进: flash_write ((char *)addr, dest, count*size); 去看看。
    common/flash.c 文件中定义:

点击(此处)折叠或打开

  1. /*-----------------------------------------------------------------------
  2.  * Copy memory to flash.
  3.  * Make sure all target addresses are within Flash bounds,
  4.  * and no protected sectors are hit.
  5.  * Returns:
  6.  * ERR_OK 0 - OK
  7.  * ERR_TIMOUT 1 - write timeout
  8.  * ERR_NOT_ERASED 2 - Flash not erased
  9.  * ERR_PROTECTED 4 - target range includes protected sectors
  10.  * ERR_INVAL 8 - target address not in Flash memory
  11.  * ERR_ALIGN 16 - target address not aligned on boundary
  12.  *            (only some targets require alignment)
  13.  */
  14. int
  15. flash_write (char *src, ulong addr, ulong cnt)
  16. {
  17. #ifdef CONFIG_SPD823TS
  18.     return (ERR_TIMOUT);    /* any other error codes are possible as well */
  19. #else
  20.     int i;
  21.     ulong end = addr + cnt - 1;
  22.     flash_info_t *info_first = addr2info (addr);
  23.     flash_info_t *info_last = addr2info (end );
  24.     flash_info_t *info;

  25.     if (cnt == 0) {
  26.         return (ERR_OK);
  27.     }

  28.     if (!info_first || !info_last) {
  29.         return (ERR_INVAL);
  30.     }

  31.     for (info = info_first; info <= info_last; ++info) {
  32.         ulong b_end = info->start[0] + info->size;    /* bank end addr */
  33.         short s_end = info->sector_count - 1;
  34.         for (i=0; i<info->sector_count; ++i) {
  35.             ulong e_addr = (i == s_end) ? b_end : info->start[i + 1];

  36.             if ((end >= info->start[i]) && (addr < e_addr) &&
  37.              (info->protect[i] != 0) ) {
  38.                 return (ERR_PROTECTED);
  39.             }
  40.         }
  41.     }

  42.     /* finally write data to flash */
  43.     for (info = info_first; info <= info_last && cnt>0; ++info) {
  44.         ulong len;

  45.         len = info->start[0] + info->size - addr;
  46.         if (len > cnt)
  47.             len = cnt;
  48.         if ((i = write_buff(info, (uchar *)src, addr, len)) != 0) {
  49.             return (i);
  50.         }
  51.         cnt -= len;
  52.         addr += len;
  53.         src += len;
  54.     }
  55.     return (ERR_OK);
  56. #endif /* CONFIG_SPD823TS */
  57. }

    最终是调用L54的 write_buff() 来实现Flash数据写入操作。我正想跟一下这个write_buff()函数,发现u-boot工程里有很多个write_buff()函数。感觉u-boot根据每一种类型的FLASH芯片都做了一套Flash驱动接口。这时,我在想:“我是不是没有选对Flash芯片哟?”

    好了,夜很深了,明天再继续探究。

阅读(1082) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~