Chinaunix首页 | 论坛 | 博客
  • 博客访问: 138092
  • 博文数量: 28
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 165
  • 用 户 组: 普通用户
  • 注册时间: 2013-07-14 10:02
文章分类

全部博文(28)

文章存档

2014年(12)

2013年(16)

我的朋友

分类: 嵌入式

2013-09-12 14:45:38

   前言:
    声明一下:如果想按照本方法移植的话,需参照国嵌的手册:4-2-6,上面讲解的步骤和解析。
    本人买了一块mini2440,同时买了一套国嵌的实验手册,可是做到4-2-6节的时候出了问题,因为照着实验手册做的话,下到nor flash会提示这个信息,如下
 
 
上面提示到nor flash芯片不是sst39vf1601,而是那个am29lv160b,呵呵,同时下面的扇区信息也不对,怎么是35个呢?2M存储量,一个是64K,怎么是35个,不是应该是国嵌上的那个32么?
 
同时还有一个疑问:这个移植的最终目的就是实现对nor flash的擦写,可是当你按照手册上的方法命名一个环境变量,保存,重启一下,在显示的时候发现没了。。。。
 
从以上信息可以得出一个结论:你的移植失败了。。。。
一.
为什么呢?因为国嵌的开发板本来是那个sst39vf1601,可是有很多人买并不是这个(你细心点看看你板子上的nor flash是不是),如果是的话,那移植不会出问题,如果不是(我的就不是),我的上面标的是:S29AL016.....,我查了一下,是spansion公司的(谁知道是啥公司,网上都找不到),这款芯片的id是:122c4(还有一个名字差不多,id是122c9,关于id,这个很重要,我的方法是用jlink来查看的),并且很奇怪,这款芯片和上面图片中的出现的那个AM29LV160T是一个id,也不知道为什么2个公司生产出来的芯片会是一个id,就是因为这是一个id,所以我们可以用AM29LV160T来配置。
 
解释了这么多,意思也该明白了,uboot识别出了你的芯片,可是你按手册上移植的时候并不是按照这个芯片移植的,所以出错了,解决办法(我不知道我的这个方法内部会不会有一些毛病,但是最终显示的界面证明我自己移植成功了):我是改造了2.6上的移植方法,换成了AM29LV160T:
 
二。
先贴出来:sst39vf1601和AM29LV160T的关键软件操作时序图:
sst39vf1601
 
 
再贴一幅关于am29lv160的
 
 
看到了吧,这两款芯片的操作时序并不一样,所以你要好好改了,具体内容我就不扯了,下面我贴出我移植的关键的2个文件中的代码,你只要把这2个文件的代码复制到你的相应文件中,编译一下就成了:
 
你可以把这2个文件的内容和国嵌4.2.6中移植中的对比一下,有些地方我同样修改了,但是因为这个文件中支持这个nor flash,所以说,有好些步骤,不需要动:
1.board/mini2440/flash.c : flash.rar  
代码贴出如下:

/*

 * (C) Copyright 2001

 * Stefan Roese, esd gmbh germany, stefan.roese@esd-electronics.com

 *

 * See file CREDITS for list of people who contributed to this

 * project.

 *

 * This program is free software; you can redistribute it and/or

 * modify it under the terms of the GNU General Public License as

 * published by the Free Software Foundation; either version 2 of

 * the License, or (at your option) any later version.

 *

 * This program is distributed in the hope that it will be useful,

 * but WITHOUT ANY WARRANTY; without even the implied warranty of

 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the

 * GNU General Public License for more details.

 *

 * You should have received a copy of the GNU General Public License

 * along with this program; if not, write to the Free Software

 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,

 * MA 02111-1307 USA

 */

 

#include

#include

 

#define CFG_FLASH_WORD_SIZE     unsigned short  /* flash word size (width)      */

#define CFG_FLASH_ADDR0         0x555  /* 参看am160的图示 */

#define CFG_FLASH_ADDR1         0x2AA  /* 参看am160的图示 */

/*

 * The following defines are added for buggy IOP480 byte interface.

 * All other boards should use the standard values (CPCI405 etc.)

 */

#define CFG_FLASH_READ0         0x0000  /* 0 is standard                        */

#define CFG_FLASH_READ1         0x0001  /* 1 is standard                        */

#define CFG_FLASH_READ2         0x0002  /* 2 is standard                        */

 

flash_info_t    flash_info[CFG_MAX_FLASH_BANKS]; /* info for FLASH chips    */

 

/*-----------------------------------------------------------------------

 * Functions

 */

static int write_word (flash_info_t *info, ulong dest, ulong data);

 

/*-----------------------------------------------------------------------

 */

 

 

static void flash_get_offsets (ulong base, flash_info_t *info)

{

       int i;

       short n;

 

       /* set up sector start address table */

       if (((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_SST) ||

           ((info->flash_id & FLASH_TYPEMASK) == FLASH_AM160T) ||   /*添加的,因为要以64K来划分*/

           ((info->flash_id & FLASH_TYPEMASK) == FLASH_AM640U)) {

           for (i = 0; i < info->sector_count; i++)

              info->start[i] = base + (i * 0x00010000);

       } else if (((info->flash_id & FLASH_TYPEMASK) == FLASH_AMDL322B) ||

                 ((info->flash_id & FLASH_TYPEMASK) == FLASH_AMDL323B) ||

                 ((info->flash_id & FLASH_TYPEMASK) == FLASH_AM320B) ||

                 ((info->flash_id & FLASH_TYPEMASK) == FLASH_AMDL324B)) {

              /* set sector offsets for bottom boot block type   */

              for (i=0; i<8; ++i) {              /*  8 x 8k boot sectors */

                     info->start[i] = base;

                     base += 8 << 10;

              }

              while (i < info->sector_count) {   /* 64k regular sectors    */

                     info->start[i] = base;

                     base += 64 << 10;

                     ++i;

              }

       } else if (((info->flash_id & FLASH_TYPEMASK) == FLASH_AMDL322T) ||

                 ((info->flash_id & FLASH_TYPEMASK) == FLASH_AMDL323T) ||

                 ((info->flash_id & FLASH_TYPEMASK) == FLASH_AM320T) ||

                 ((info->flash_id & FLASH_TYPEMASK) == FLASH_AMDL324T)) {

              /* set sector offsets for top boot block type        */

              base += info->size;

              i = info->sector_count;

              for (n=0; n<8; ++n) {           /*  8 x 8k boot sectors */

                     base -= 8 << 10;

                     --i;

                     info->start[i] = base;

              }

              while (i > 0) {               /* 64k regular sectors    */

                     base -= 64 << 10;

                     --i;

                     info->start[i] = base;

              }

       } else {

           if (info->flash_id & FLASH_BTYPE) {

              /* set sector offsets for bottom boot block type   */

              info->start[0] = base + 0x00000000;

              info->start[1] = base + 0x00004000;

              info->start[2] = base + 0x00006000;

              info->start[3] = base + 0x00008000;

              for (i = 4; i < info->sector_count; i++) {

                     info->start[i] = base + (i * 0x00010000) - 0x00030000;

              }

           } else {

              /* set sector offsets for top boot block type        */

              i = info->sector_count - 1;

              info->start[i--] = base + info->size - 0x00004000;

              info->start[i--] = base + info->size - 0x00006000;

              info->start[i--] = base + info->size - 0x00008000;

              for (; i >= 0; i--) {

                     info->start[i] = base + i * 0x00010000;

              }

           }

       }

}

 

/*-----------------------------------------------------------------------

 */

void flash_print_info  (flash_info_t *info)

{

       int i;

       int k;

       int size;

       int erased;

       volatile unsigned long *flash;

 

       if (info->flash_id == FLASH_UNKNOWN) {

              printf ("missing or unknown FLASH type\n");

              return;

       }

 

       switch (info->flash_id & FLASH_VENDMASK) {

       case FLASH_MAN_AMD:     printf ("AMD ");            break;

       case FLASH_MAN_FUJ:       printf ("FUJITSU ");             break;

       case FLASH_MAN_SST:      printf ("SST ");             break;

       case FLASH_MAN_STM:     printf ("ST  ");             break;

       default:           printf ("Unknown Vendor ");  break;

       }

 

       switch (info->flash_id & FLASH_TYPEMASK) {

       case FLASH_AM400B:  printf ("AM29LV400B (4 Mbit, bottom boot sect)\n");

                            break;

       case FLASH_AM400T:  printf ("AM29LV400T (4 Mbit, top boot sector)\n");

                            break;

       case FLASH_AM800B:  printf ("AM29LV800B (8 Mbit, bottom boot sect)\n");

                            break;

       case FLASH_AM800T:  printf ("AM29LV800T (8 Mbit, top boot sector)\n");

                            break;

       case FLASH_AM160B:  printf ("AM29LV160B (16 Mbit, bottom boot sect)\n");

                            break;

       case FLASH_AM160T:  printf ("AM29LV160T (16 Mbit, top boot sector)\n");

                            break; //调用的是这个函数,不用修改

       case FLASH_AM320T:  printf ("AM29LV320T (32 M, top sector)\n");

                            break;

       case FLASH_AM320B:  printf ("AM29LV320B (32 M, bottom sector)\n");

                            break;

       case FLASH_AMDL322T:     printf ("AM29DL322T (32 M, top sector)\n");

                            break;

       case FLASH_AMDL322B:     printf ("AM29DL322B (32 M, bottom sector)\n");

                            break;

       case FLASH_AMDL323T:     printf ("AM29DL323T (32 M, top sector)\n");

                            break;

       case FLASH_AMDL323B:     printf ("AM29DL323B (32 M, bottom sector)\n");

                            break;

       case FLASH_AM640U:  printf ("AM29LV640D (64 M, uniform sector)\n");

                            break;

       case FLASH_SST800A: printf ("SST39LF/VF800 (8 Mbit, uniform sector size)\n");

                            break;

       case FLASH_SST160A: printf ("SST39LF/VF160 (16 Mbit, uniform sector size)\n");

                            break;

       case FLASH_STMW320DT:  printf ("M29W320DT (32 M, top sector)\n");

                            break;

       default:           printf ("Unknown Chip Type\n");

                            break;

       }

 

       printf ("  Size: %ld MB in %d Sectors\n",

              info->size >> 20, info->sector_count);

 

       printf ("  Sector Start Addresses:");

       for (i=0; isector_count; ++i) {

#ifdef CFG_FLASH_EMPTY_INFO

              /*

               * Check if whole sector is erased

               */

              if (i != (info->sector_count-1))

                size = info->start[i+1] - info->start[i];

              else

                size = info->start[0] + info->size - info->start[i];

              erased = 1;

              flash = (volatile unsigned long *)info->start[i];

              size = size >> 2;        /* divide by 4 for longword access */

              for (k=0; k

                {

                  if (*flash++ != 0xffffffff)

                    {

                     erased = 0;

                     break;

                    }

                }

 

              if ((i % 5) == 0)

                     printf ("\n   ");

              /* print empty and read-only info */

              printf (" %08lX%s%s",

                     info->start[i],

                     erased ? " E" : "  ",

                     info->protect[i] ? "RO " : "   ");

#else

              if ((i % 5) == 0)

                     printf ("\n   ");

              printf (" %08lX%s",

                     info->start[i],

                     info->protect[i] ? " (RO)" : "     ");

#endif

 

       }

       printf ("\n");

       return;

}

 

/*-----------------------------------------------------------------------

 */

 

 

/*-----------------------------------------------------------------------

 */

 

/*

 * The following code cannot be run from FLASH!

 */

static ulong flash_get_size (vu_long *addr, flash_info_t *info)

{

       short i;

       short n;

       CFG_FLASH_WORD_SIZE value;

       ulong base = (ulong)addr;

       volatile CFG_FLASH_WORD_SIZE *addr2 = (CFG_FLASH_WORD_SIZE *)addr;

 

       debug("[%s, %d] Entering ...\n", __FUNCTION__, __LINE__);

 

       /* Write auto select command: read Manufacturer ID */

       addr2[CFG_FLASH_ADDR0] = (CFG_FLASH_WORD_SIZE)0x00AA;

       addr2[CFG_FLASH_ADDR1] = (CFG_FLASH_WORD_SIZE)0x0055;

       addr2[CFG_FLASH_ADDR0] = (CFG_FLASH_WORD_SIZE)0x0090;

 

       value = addr2[CFG_FLASH_READ0];

 

       switch (value) {

       case (CFG_FLASH_WORD_SIZE)AMD_MANUFACT:

              info->flash_id = FLASH_MAN_AMD;

              break;

       case (CFG_FLASH_WORD_SIZE)FUJ_MANUFACT:

              info->flash_id = FLASH_MAN_FUJ;

              break;

       case (CFG_FLASH_WORD_SIZE)SST_MANUFACT:

              info->flash_id = FLASH_MAN_SST;

              break;

       case (CFG_FLASH_WORD_SIZE)STM_MANUFACT:

              info->flash_id = FLASH_MAN_STM;

              break;

       default:

              info->flash_id = FLASH_UNKNOWN;

              info->sector_count = 0;

              info->size = 0;

              return (0);                    /* no or unknown flash  */

       }

 

       value = addr2[CFG_FLASH_READ1];         /* device ID           */

 

       switch (value) {

       case (CFG_FLASH_WORD_SIZE)AMD_ID_LV400T:

              info->flash_id += FLASH_AM400T;

              info->sector_count = 11;

              info->size = 0x00080000;

              break;                          /* => 0.5 MB         */

 

       case (CFG_FLASH_WORD_SIZE)AMD_ID_LV400B:

              info->flash_id += FLASH_AM400B;

              info->sector_count = 11;

              info->size = 0x00080000;

              break;                          /* => 0.5 MB         */

 

       case (CFG_FLASH_WORD_SIZE)AMD_ID_LV800T:

              info->flash_id += FLASH_AM800T;

              info->sector_count = 19;

              info->size = 0x00100000;

              break;                          /* => 1 MB            */

 

       case (CFG_FLASH_WORD_SIZE)AMD_ID_LV800B:

              info->flash_id += FLASH_AM800B;

              info->sector_count = 19;

              info->size = 0x00100000;

              break;                          /* => 1 MB            */

 

       case (CFG_FLASH_WORD_SIZE)AMD_ID_LV160T://调用的是这个

              info->flash_id += FLASH_AM160T;

              info->sector_count = 32;  //原来是35,改为32

              info->size = 0x00200000;

              break;                          /* => 2 MB            */

 

       case (CFG_FLASH_WORD_SIZE)AMD_ID_LV160B:

              info->flash_id += FLASH_AM160B;

              info->sector_count = 35;

              info->size = 0x00200000;

              break;                          /* => 2 MB            */

 

       case (CFG_FLASH_WORD_SIZE)STM_ID_29W320DT:

              info->flash_id += FLASH_STMW320DT;

              info->sector_count = 67;

              info->size = 0x00400000;  break;       /* => 4 MB     */

 

       case (CFG_FLASH_WORD_SIZE)AMD_ID_LV320T:

              info->flash_id += FLASH_AM320T;

              info->sector_count = 71;

              info->size = 0x00400000;  break;       /* => 4 MB     */

 

       case (CFG_FLASH_WORD_SIZE)AMD_ID_LV320B:

              info->flash_id += FLASH_AM320B;

              info->sector_count = 71;

              info->size = 0x00400000;  break;       /* => 4 MB     */

 

       case (CFG_FLASH_WORD_SIZE)AMD_ID_DL322T:

              info->flash_id += FLASH_AMDL322T;

              info->sector_count = 71;

              info->size = 0x00400000;  break;       /* => 4 MB     */

 

       case (CFG_FLASH_WORD_SIZE)AMD_ID_DL322B:

              info->flash_id += FLASH_AMDL322B;

              info->sector_count = 71;

              info->size = 0x00400000;  break;       /* => 4 MB     */

 

       case (CFG_FLASH_WORD_SIZE)AMD_ID_DL323T:

              info->flash_id += FLASH_AMDL323T;

              info->sector_count = 71;

              info->size = 0x00400000;  break;       /* => 4 MB     */

 

       case (CFG_FLASH_WORD_SIZE)AMD_ID_DL323B:

              info->flash_id += FLASH_AMDL323B;

              info->sector_count = 71;

              info->size = 0x00400000;  break;       /* => 4 MB     */

 

       case (CFG_FLASH_WORD_SIZE)AMD_ID_LV640U:

              info->flash_id += FLASH_AM640U;

              info->sector_count = 128;

              info->size = 0x00800000;  break;       /* => 8 MB     */

 

       case (CFG_FLASH_WORD_SIZE)SST_ID_xF800A:

              info->flash_id += FLASH_SST800A;

              info->sector_count = 16;

              info->size = 0x00100000;

              break;                          /* => 1 MB            */

 

       case (CFG_FLASH_WORD_SIZE)SST_ID_xF160A:

              info->flash_id += FLASH_SST160A;

              info->sector_count = 32;

              info->size = 0x00200000;

              break;                          /* => 2 MB            */

 

       default:

              info->flash_id = FLASH_UNKNOWN;

              return (0);                    /* => no or unknown flash */

 

       }

 

       /* set up sector start address table, add myself am160t */

       if (((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_SST) ||

           ((info->flash_id & FLASH_TYPEMASK) == FLASH_AM160T) || //添加的,原理同上

           ((info->flash_id & FLASH_TYPEMASK) == FLASH_AM640U)) {

           for (i = 0; i < info->sector_count; i++)

              info->start[i] = base + (i * 0x00010000);

       } else if (((info->flash_id & FLASH_TYPEMASK) == FLASH_AMDL322B) ||

                 ((info->flash_id & FLASH_TYPEMASK) == FLASH_AMDL323B) ||

                 ((info->flash_id & FLASH_TYPEMASK) == FLASH_AM320B) ||

                 ((info->flash_id & FLASH_TYPEMASK) == FLASH_AMDL324B)) {

              /* set sector offsets for bottom boot block type   */

              for (i=0; i<8; ++i) {              /*  8 x 8k boot sectors */

                     info->start[i] = base;

                     base += 8 << 10;

              }

              while (i < info->sector_count) {   /* 64k regular sectors    */

                     info->start[i] = base;

                     base += 64 << 10;

                     ++i;

              }

       } else if (((info->flash_id & FLASH_TYPEMASK) == FLASH_AMDL322T) ||

                 ((info->flash_id & FLASH_TYPEMASK) == FLASH_AMDL323T) ||

                 ((info->flash_id & FLASH_TYPEMASK) == FLASH_AM320T) ||

                 ((info->flash_id & FLASH_TYPEMASK) == FLASH_AMDL324T)) {

              /* set sector offsets for top boot block type        */

              base += info->size;

              i = info->sector_count;

              for (n=0; n<8; ++n) {           /*  8 x 8k boot sectors */

                     base -= 8 << 10;

                     --i;

                     info->start[i] = base;

              }

              while (i > 0) {               /* 64k regular sectors    */

                     base -= 64 << 10;

                     --i;

                     info->start[i] = base;

              }

       } else if ((info->flash_id & FLASH_TYPEMASK) == FLASH_STMW320DT) {

              /* set sector offsets for top boot block type        */

              base += info->size;

              i = info->sector_count;

              /*  1 x 16k boot sector */

              base -= 16 << 10;

              --i;

              info->start[i] = base;

              /*  2 x 8k  boot sectors */

              for (n=0; n<2; ++n) {

                     base -= 8 << 10;

                     --i;

                     info->start[i] = base;

              }

              /*  1 x 32k boot sector */

              base -= 32 << 10;

              --i;

              info->start[i] = base;

 

              while (i > 0) {               /* 64k regular sectors    */

                     base -= 64 << 10;

                     --i;

                     info->start[i] = base;

              }

       } else {

           if (info->flash_id & FLASH_BTYPE) {

              /* set sector offsets for bottom boot block type   */

              info->start[0] = base + 0x00000000;

              info->start[1] = base + 0x00004000;

              info->start[2] = base + 0x00006000;

              info->start[3] = base + 0x00008000;

              for (i = 4; i < info->sector_count; i++) {

                     info->start[i] = base + (i * 0x00010000) - 0x00030000;

              }

           } else {

              /* set sector offsets for top boot block type        */

              i = info->sector_count - 1;

              info->start[i--] = base + info->size - 0x00004000;

              info->start[i--] = base + info->size - 0x00006000;

              info->start[i--] = base + info->size - 0x00008000;

              for (; i >= 0; i--) {

                     info->start[i] = base + i * 0x00010000;

              }

           }

       }

 

       /* check for protected sectors */

       for (i = 0; i < info->sector_count; i++) {

              /* read sector protection at sector address, (A7 .. A0) = 0x02 */

              /* D0 = 1 if protected */

              addr2 = (volatile CFG_FLASH_WORD_SIZE *)(info->start[i]);

              if ((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_SST)

                info->protect[i] = 0;

              else

                info->protect[i] = addr2[CFG_FLASH_READ2] & 1;

       }

 

       /*

        * Prevent writes to uninitialized FLASH.

        */

       if (info->flash_id != FLASH_UNKNOWN) {

              addr2 = (CFG_FLASH_WORD_SIZE *)info->start[0];

              *addr2 = (CFG_FLASH_WORD_SIZE)0x00F0;  /* reset bank */

       }

 

       return (info->size);

}

 

 

unsigned long flash_init (void)

{

        unsigned long size_b0;

        int i;

 

        /* Init: no FLASHes known */

        for (i=0; i

                flash_info[i].flash_id = FLASH_UNKNOWN;

        }

 

        /* Static FLASH Bank configuration here - FIXME XXX */

 

        size_b0 = flash_get_size((vu_long *)CFG_FLASH_BASE, &flash_info[0]);

 

        if (flash_info[0].flash_id == FLASH_UNKNOWN) {

                printf ("## Unknown FLASH on Bank 0 - Size = 0x%08lx = %ld MB\n",

                        size_b0, size_b0<<20);

        }

 

        /* Setup offsets */

        flash_get_offsets (0, &flash_info[0]);

 

        /* Monitor protection ON by default */

        (void)flash_protect(FLAG_PROTECT_SET,

                            -CFG_MONITOR_LEN,

                            0xffffffff,

                            &flash_info[0]);

 

        flash_info[0].size = size_b0;

 

        return (size_b0);

}

 

/*-----------------------------------------------------------------------

 */

 

int    flash_erase (flash_info_t *info, int s_first, int s_last)

{

       volatile CFG_FLASH_WORD_SIZE *addr = (CFG_FLASH_WORD_SIZE *)(info->start[0]);

       volatile CFG_FLASH_WORD_SIZE *addr2;

       int flag, prot, sect, l_sect;

       ulong start, now, last;

       int i;

 

       if ((s_first < 0) || (s_first > s_last)) {

              if (info->flash_id == FLASH_UNKNOWN) {

                     printf ("- missing\n");

              } else {

                     printf ("- no sectors to erase\n");

              }

              return 1;

       }

 

       if (info->flash_id == FLASH_UNKNOWN) {

              printf ("Can't erase unknown flash type - aborted\n");

              return 1;

       }

 

       prot = 0;

       for (sect=s_first; sect<=s_last; ++sect) {

              if (info->protect[sect]) {

                     prot++;

              }

       }

 

       if (prot) {

              printf ("- Warning: %d protected sectors will not be erased!\n",

                     prot);

       } else {

              printf ("\n");

       }

 

       l_sect = -1;

 

       /* Disable interrupts which might cause a timeout here */

       flag = disable_interrupts();

 

       /* Start erase on unprotected sectors */

       for (sect = s_first; sect<=s_last; sect++) {

              if (info->protect[sect] == 0) {      /* not protected */

                  addr2 = (CFG_FLASH_WORD_SIZE *)(info->start[sect]);

                  if ((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_SST) {

                     addr[CFG_FLASH_ADDR0] = (CFG_FLASH_WORD_SIZE)0x00AA00AA;

                     addr[CFG_FLASH_ADDR1] = (CFG_FLASH_WORD_SIZE)0x00550055;

                     addr[CFG_FLASH_ADDR0] = (CFG_FLASH_WORD_SIZE)0x00800080;

                     addr[CFG_FLASH_ADDR0] = (CFG_FLASH_WORD_SIZE)0x00AA00AA;

                     addr[CFG_FLASH_ADDR1] = (CFG_FLASH_WORD_SIZE)0x00550055;

                     addr2[0] = (CFG_FLASH_WORD_SIZE)0x00500050;  /* block erase */

                     for (i=0; i<50; i++)

                       udelay(1000);  /* wait 1 ms */

                  } else {

                     if (sect == s_first) {

                     /*add myself 这个地方很重要,那个saveenv,就是调用的这里,在这我解释一下,通过图片,我们看到,这flash不支持块擦写,所以就用扇区擦写*/

                     printf("select sector erase \n");  //我添加的,实验证明,在我进行saveenv是,显示了这条信息,说明,进入了着个if

                         addr[CFG_FLASH_ADDR0] = (CFG_FLASH_WORD_SIZE)0x00AA;

                         addr[CFG_FLASH_ADDR1] = (CFG_FLASH_WORD_SIZE)0x0055;

                         addr[CFG_FLASH_ADDR0] = (CFG_FLASH_WORD_SIZE)0x0080;

                         addr[CFG_FLASH_ADDR0] = (CFG_FLASH_WORD_SIZE)0x00AA;

                         addr[CFG_FLASH_ADDR1] = (CFG_FLASH_WORD_SIZE)0x0055;

                     }

                     addr2[0] = (CFG_FLASH_WORD_SIZE)0x0030;  /* sector erase */

                  }

                  l_sect = sect;

              }

       }

 

       /* re-enable interrupts if necessary */

       if (flag)

              enable_interrupts();

 

       /* wait at least 80us - let's wait 1 ms */

       udelay (1000);

 

       /*

        * We wait for the last triggered sector

        */

       if (l_sect < 0)

              goto DONE;

 

       start = get_timer (0);

       last  = start;

       addr = (CFG_FLASH_WORD_SIZE *)(info->start[l_sect]);

       while ((addr[0] & (CFG_FLASH_WORD_SIZE)0x0080) != (CFG_FLASH_WORD_SIZE)0x0080) {

              if ((now = get_timer(start)) > CFG_FLASH_ERASE_TOUT) {

                     printf ("Timeout\n");

                     return 1;

              }

              /* show that we're waiting */

              if ((now - last) > 1000) {      /* every second */

                     putc ('.');

                     last = now;

              }

       }

 

DONE:

       /* reset to read mode */

       addr = (CFG_FLASH_WORD_SIZE *)info->start[0];

       addr[0] = (CFG_FLASH_WORD_SIZE)0x00F0; /* reset bank */

 

       printf (" done\n");

       return 0;

}

 

/*-----------------------------------------------------------------------

 * Copy memory to flash, returns:

 * 0 - OK

 * 1 - write timeout

 * 2 - Flash not erased

 */

 

int write_buff (flash_info_t *info, uchar *src, ulong addr, ulong cnt)

{

       ulong cp, wp, data;

       int i, l, rc;

 

       wp = (addr & ~3); /* get lower word aligned address */

 

       /*

        * handle unaligned start bytes

        */

       if ((l = addr - wp) != 0) {

              data = 0;

              for (i=0, cp=wp; i

#ifdef CONFIG_MINI2440

                     data = data | ((*(uchar *)cp)<<(8*i));

#else

                     data = (data << 8) | (*(uchar *)cp);

#endif

              }

              for (; i<4 && cnt>0; ++i) {

#ifdef CONFIG_MINI2440

                     data = data  | ((*src++)<<(8*i));

#else

                     data = (data << 8) | *src++;

#endif

                     --cnt;

                     ++cp;

              }

              for (; cnt==0 && i<4; ++i, ++cp) {

#ifdef CONFIG_MINI2440

                     data = data | ((*(uchar *)cp)<<(8*i));

#else

                     data = (data << 8) | (*(uchar *)cp);

#endif

              }

 

              if ((rc = write_word(info, wp, data)) != 0) {

                     return (rc);

              }

              wp += 4;

       }

 

       /*

        * handle word aligned part

        */

       while (cnt >= 4) {

              data = 0;

#ifdef CONFIG_MINI2440

              data = (*(ulong*)src);

              src += 4;

#else

              for (i=0; i<4; ++i) {

                     data = (data << 8) | *src++;

              }

#endif

              if ((rc = write_word(info, wp, data)) != 0) {

                     return (rc);

              }

              wp  += 4;

              cnt -= 4;

       }

 

       if (cnt == 0) {

              return (0);

       }

 

       /*

        * handle unaligned tail bytes

        */

       data = 0;

       for (i=0, cp=wp; i<4 && cnt>0; ++i, ++cp) {

#ifdef CONFIG_MINI2440

              data = data  | ((*src++)<<(8*i));

#else

              data = (data << 8) | *src++;

#endif

              --cnt;

       }

       for (; i<4; ++i, ++cp) {

#ifdef CONFIG_MINI2440

              data = data | ((*(uchar *)cp)<<(8*i));

#else

              data = (data << 8) | (*(uchar *)cp);

#endif

       }

 

       return (write_word(info, wp, data));

}

 

/*-----------------------------------------------------------------------

 * Write a word to Flash, returns:

 * 0 - OK

 * 1 - write timeout

 * 2 - Flash not erased

 */

static int write_word (flash_info_t *info, ulong dest, ulong data)

{

       volatile CFG_FLASH_WORD_SIZE *addr2 = (CFG_FLASH_WORD_SIZE *)(info->start[0]);

       volatile CFG_FLASH_WORD_SIZE *dest2 = (CFG_FLASH_WORD_SIZE *)dest;

       volatile CFG_FLASH_WORD_SIZE *data2 = (CFG_FLASH_WORD_SIZE *)&data;

       ulong start;

       int flag;

       int i;

 

       /* Check if Flash is (sufficiently) erased */

       if ((*((volatile ulong *)dest) & data) != data) {

              return (2);

       }

       /* Disable interrupts which might cause a timeout here */

       flag = disable_interrupts();

 

       for (i=0; i<4/sizeof(CFG_FLASH_WORD_SIZE); i++)

         {

           addr2[CFG_FLASH_ADDR0] = (CFG_FLASH_WORD_SIZE)0x00AA;

           addr2[CFG_FLASH_ADDR1] = (CFG_FLASH_WORD_SIZE)0x0055;

           addr2[CFG_FLASH_ADDR0] = (CFG_FLASH_WORD_SIZE)0x00A0;

 

           dest2[i] = data2[i];

 

           /* re-enable interrupts if necessary */

           if (flag)

             enable_interrupts();

 

           /* data polling for D7 */

           start = get_timer (0);

           while ((dest2[i] & (CFG_FLASH_WORD_SIZE)0x0080) !=

                 (data2[i] & (CFG_FLASH_WORD_SIZE)0x0080)) {

             if (get_timer(start) > CFG_FLASH_WRITE_TOUT) {

              return (1);

             }

           }

         }

 

       return (0);

}

 

/*-----------------------------------------------------------------------

 */

 
2.关于include/configs/mini2440.h,和国嵌上的修改完全一样,我还是传上来吧 mini2440.rar 
代码我也提出来吧:
 

/*

 * (C) Copyright 2002

 * Sysgo Real-Time Solutions, GmbH

 * Marius Groeger

 * Gary Jennejohn

 * David Mueller

 *

 * Configuation settings for the SAMSUNG SMDK2410 board.

 *

 * See file CREDITS for list of people who contributed to this

 * project.

 *

 * This program is free software; you can redistribute it and/or

 * modify it under the terms of the GNU General Public License as

 * published by the Free Software Foundation; either version 2 of

 * the License, or (at your option) any later version.

 *

 * This program is distributed in the hope that it will be useful,

 * but WITHOUT ANY WARRANTY; without even the implied warranty of

 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the

 * GNU General Public License for more details.

 *

 * You should have received a copy of the GNU General Public License

 * along with this program; if not, write to the Free Software

 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,

 * MA 02111-1307 USA

 */

 

#ifndef __CONFIG_H

#define __CONFIG_H

 

/*

 * High Level Configuration Options

 * (easy to change)

 */

#define CONFIG_ARM920T        1     /* This is an ARM920T Core */

#define    CONFIG_S3C2440              1     /* in a SAMSUNG S3C2410 SoC     */

#define CONFIG_MINI2440        1     /* on a SAMSUNG SMDK2410 Board  */

/* input clock of PLL */

#define CONFIG_SYS_CLK_FREQ     12000000/* the SMDK2410 has 12MHz input clock */

 

 

#define USE_920T_MMU            1

#undef CONFIG_USE_IRQ                 /* we don't need IRQ/FIQ stuff */

 

/*

 * Size of malloc() pool

 */

#define CFG_MALLOC_LEN              (CONFIG_ENV_SIZE + 128*1024)

#define CFG_GBL_DATA_SIZE    128  /* size in bytes reserved for initial data */

 

/*

 * Hardware drivers

 */

/*modified by david, for mini2440 ,dm9000 */

#if 0

#define CONFIG_DRIVER_CS8900     1     /* we have a CS8900 on-board */

#define CS8900_BASE          0x19000300

#define CS8900_BUS16        1 /* the Linux driver does accesses as shorts */

#endif

 

#define CONFIG_DRIVER_DM9000 1

#define CONFIG_DM9000_USE_16BIT 1

#define CONFIG_DM9000_BASE 0x20000300

#define DM9000_IO 0x20000300

#define DM9000_DATA 0x20000304

 

/*

 * select serial console configuration

 */

#define CONFIG_SERIAL1          1    /* we use SERIAL 1 on SMDK2410 */

 

/************************************************************

 * RTC

 ************************************************************/

#define    CONFIG_RTC_S3C24X0     1

 

/* allow to overwrite serial and ethaddr */

#define CONFIG_ENV_OVERWRITE

 

#define CONFIG_BAUDRATE             115200

 

 

/*

 * BOOTP options

 */

#define CONFIG_BOOTP_BOOTFILESIZE

#define CONFIG_BOOTP_BOOTPATH

#define CONFIG_BOOTP_GATEWAY

#define CONFIG_BOOTP_HOSTNAME

 

 

/*

 * Command line configuration.

 */

#include

 

#define CONFIG_CMD_CACHE

#define CONFIG_CMD_DATE

#define CONFIG_CMD_ELF

 

/*add by david,for 2440,ping cmd*/

#define CONFIG_CMD_PING

 

#define CONFIG_BOOTDELAY   3

/*#define CONFIG_BOOTARGS  "root=ramfs devfs=mount console=ttySA0,9600" */

/*#define CONFIG_ETHADDR    08:00:3e:26:0a:5b */

#define CONFIG_NETMASK          255.255.255.0

#define CONFIG_IPADDR           10.0.0.110

#define CONFIG_SERVERIP              10.0.0.1

/*#define CONFIG_BOOTFILE    "elinos-lart" */

/*#define CONFIG_BOOTCOMMAND       "tftp; bootm" */

 

#if defined(CONFIG_CMD_KGDB)

#define CONFIG_KGDB_BAUDRATE  115200           /* speed to run kgdb serial port */

/* what's this ? it's not used anywhere */

#define CONFIG_KGDB_SER_INDEX       1            /* which serial port to use */

#endif

 

/*

 * Miscellaneous configurable options

 */

#define    CFG_LONGHELP                       /* undef to save memory              */

#define    CFG_PROMPT             "Mini2440 # "  /* Monitor Command Prompt       */

#define    CFG_CBSIZE        256         /* Console I/O Buffer Size     */

#define    CFG_PBSIZE (CFG_CBSIZE+sizeof(CFG_PROMPT)+16) /* Print Buffer Size */

#define    CFG_MAXARGS          16           /* max number of command args  */

#define CFG_BARGSIZE             CFG_CBSIZE /* Boot Argument Buffer Size       */

 

#define CFG_MEMTEST_START 0x30000000    /* memtest works on     */

#define CFG_MEMTEST_END           0x33F00000   /* 63 MB in DRAM       */

 

#undef  CFG_CLKS_IN_HZ              /* everything, incl board info, in Hz */

 

#define    CFG_LOAD_ADDR             0x33000000    /* default load address   */

 

/* the PWM TImer 4 uses a counter of 15625 for 10 ms, so we need */

/* it to wrap 100 times (total 1562500) to get 1 sec. */

#define    CFG_HZ               1562500

 

/* valid baudrates */

#define CFG_BAUDRATE_TABLE       { 9600, 19200, 38400, 57600, 115200 }

 

/*-----------------------------------------------------------------------

 * Stack sizes

 *

 * The stack sizes are set up in start.S using the settings below

 */

#define CONFIG_STACKSIZE     (128*1024)     /* regular stack */

#ifdef CONFIG_USE_IRQ

#define CONFIG_STACKSIZE_IRQ    (4*1024) /* IRQ stack */

#define CONFIG_STACKSIZE_FIQ     (4*1024) /* FIQ stack */

#endif

 

/*-----------------------------------------------------------------------

 * Physical Memory Map

 */

#define CONFIG_NR_DRAM_BANKS 1        /* we have 1 bank of DRAM */

#define PHYS_SDRAM_1            0x30000000 /* SDRAM Bank #1 */

#define PHYS_SDRAM_1_SIZE   0x04000000 /* 64 MB */

 

#define PHYS_FLASH_1              0x00000000 /* Flash Bank #1 */

 

#define CFG_FLASH_BASE         PHYS_FLASH_1

 

/*-----------------------------------------------------------------------

 * FLASH and environment organization

 */

#if 0

#define CONFIG_AMD_LV400    1     /* uncomment this if you have a LV400 flash */

#define CONFIG_AMD_LV800    1     /* uncomment this if you have a LV800 flash */

#endif

 

#define CFG_MAX_FLASH_BANKS    1     /* max number of memory banks */

#ifdef CONFIG_AMD_LV800

#define PHYS_FLASH_SIZE        0x00100000 /* 1MB */

#define CFG_MAX_FLASH_SECT      (19) /* max number of sectors on one chip */

#define CONFIG_ENV_ADDR            (CFG_FLASH_BASE + 0x0F0000) /* addr of environment */

#endif

#ifdef CONFIG_AMD_LV400

#define PHYS_FLASH_SIZE        0x00080000 /* 512KB */

#define CFG_MAX_FLASH_SECT      (11) /* max number of sectors on one chip */

#define CONFIG_ENV_ADDR            (CFG_FLASH_BASE + 0x070000) /* addr of environment */

#endif

 

#define PHYS_FLASH_SIZE        0x00200000 /* 2M */

#define CFG_MAX_FLASH_SECT      (32) /* max number of sectors on one chip */

#define CONFIG_ENV_ADDR            (CFG_FLASH_BASE + 0x030000) /* addr of environment */

#define CFG_MONITOR_BASE TEXT_BASE

#define CFG_MONITOR_LEN            (256*1024)

/* timeout values are in ticks */

#define CFG_FLASH_ERASE_TOUT   (5*CFG_HZ) /* Timeout for Flash Erase */

#define CFG_FLASH_WRITE_TOUT  (5*CFG_HZ) /* Timeout for Flash Write */

 

#define    CONFIG_ENV_IS_IN_FLASH     1

#define CONFIG_ENV_SIZE              0x10000  /* Total Size of Environment Sector */

 

#endif     /* __CONFIG_H */

 

3.再贴出我下载到nor flash中启动后的界面,然后给我.bin文件,一切正常,并且使用flinfo也正常saveenv后重启也正常,如下,
 
 
 
然后重启一下,printenv一下,可以看到,mini2440仍然存在。。。
 
 
最后传一份我制作的.bin文件: u-boot20.rar   
 
最后:祝大家学习快乐。。。。。
 
 
阅读(2035) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~