uboot nor flash驱动移植(基于am29lv160bt)之环境变量没法保存的办法

转载 2012年03月30日 08:29:07
前言:
    声明一下:如果想按照本方法移植的话,需参照国嵌的手册: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:
 
可以自己查看两个芯片的时序图 
 
看到了吧,这两款芯片的操作时序并不一样,所以你要好好改了,具体内容我就不扯了,下面我贴出我移植的关键的2个文件中的代码,你只要把这2个文件的代码复制到你的相应文件中,编译一下就成了:
 
你可以把这2个文件的内容和国嵌4.2.6中移植中的对比一下,有些地方我同样修改了,但是因为这个文件中支持这个nor flash,所以说,有好些步骤,不需要动:
1.board/mini2440/flash.c (可以直接复制到你的同样目录下的flash.c中(PS把原先的flash.c内容清空,复制一下代码就行了) 
代码贴出如下:

 

#include <common.h>

#include <asm/processor.h>

 

#define CFG_FLASH_WORD_SIZE     unsigned short 

#define CFG_FLASH_ADDR0         0x555 

#define CFG_FLASH_ADDR1         0x2AA 

#define CFG_FLASH_READ0         0x0000 

#define CFG_FLASH_READ1         0x0001 

#define CFG_FLASH_READ2         0x0002 

 

flash_info_t    flash_info[CFG_MAX_FLASH_BANKS];

 

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;

 

      

       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)) {

             

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

                     info->start[i] = base;

                     base += 8 << 10;

              }

              while (i < info->sector_count) {  

                     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)) {

             

              base += info->size;

              i = info->sector_count;

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

                     base -= 8 << 10;

                     --i;

                     info->start[i] = base;

              }

              while (i > 0) {              

                     base -= 64 << 10;

                     --i;

                     info->start[i] = base;

              }

       } else {

           if (info->flash_id & FLASH_BTYPE) {

             

              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 {

             

              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; i<info->sector_count; ++i) {

#ifdef CFG_FLASH_EMPTY_INFO

             

              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;       

              for (k=0; k<size; k++)

                {

                  if (*flash++ != 0xffffffff)

                    {

                     erased = 0;

                     break;

                    }

                }

 

              if ((i % 5) == 0)

                     printf ("\n   ");

             

              printf (" lX%s%s",

                     info->start[i],

                     erased ? " E" : "  ",

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

#else

              if ((i % 5) == 0)

                     printf ("\n   ");

              printf (" lX%s",

                     info->start[i],

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

#endif

 

       }

       printf ("\n");

       return;

}

 

 

 

 

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__);

 

      

       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);                   

       }

 

       value = addr2[CFG_FLASH_READ1];        

 

       switch (value) {

       case (CFG_FLASH_WORD_SIZE)AMD_ID_LV400T:

              info->flash_id += FLASH_AM400T;

              info->sector_count = 11;

              info->size = 0x00080000;

              break;                         

 

       case (CFG_FLASH_WORD_SIZE)AMD_ID_LV400B:

              info->flash_id += FLASH_AM400B;

              info->sector_count = 11;

              info->size = 0x00080000;

              break;                         

 

       case (CFG_FLASH_WORD_SIZE)AMD_ID_LV800T:

              info->flash_id += FLASH_AM800T;

              info->sector_count = 19;

              info->size = 0x00100000;

              break;                         

 

       case (CFG_FLASH_WORD_SIZE)AMD_ID_LV800B:

              info->flash_id += FLASH_AM800B;

              info->sector_count = 19;

              info->size = 0x00100000;

              break;                         

 

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

              info->flash_id += FLASH_AM160T;

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

              info->size = 0x00200000;

              break;                         

 

       case (CFG_FLASH_WORD_SIZE)AMD_ID_LV160B:

              info->flash_id += FLASH_AM160B;

              info->sector_count = 35;

              info->size = 0x00200000;

              break;                         

 

       case (CFG_FLASH_WORD_SIZE)STM_ID_29W320DT:

              info->flash_id += FLASH_STMW320DT;

              info->sector_count = 67;

              info->size = 0x00400000;  break;      

 

       case (CFG_FLASH_WORD_SIZE)AMD_ID_LV320T:

              info->flash_id += FLASH_AM320T;

              info->sector_count = 71;

              info->size = 0x00400000;  break;      

 

       case (CFG_FLASH_WORD_SIZE)AMD_ID_LV320B:

              info->flash_id += FLASH_AM320B;

              info->sector_count = 71;

              info->size = 0x00400000;  break;      

 

       case (CFG_FLASH_WORD_SIZE)AMD_ID_DL322T:

              info->flash_id += FLASH_AMDL322T;

              info->sector_count = 71;

              info->size = 0x00400000;  break;      

 

       case (CFG_FLASH_WORD_SIZE)AMD_ID_DL322B:

              info->flash_id += FLASH_AMDL322B;

              info->sector_count = 71;

              info->size = 0x00400000;  break;      

 

       case (CFG_FLASH_WORD_SIZE)AMD_ID_DL323T:

              info->flash_id += FLASH_AMDL323T;

              info->sector_count = 71;

              info->size = 0x00400000;  break;      

 

       case (CFG_FLASH_WORD_SIZE)AMD_ID_DL323B:

              info->flash_id += FLASH_AMDL323B;

              info->sector_count = 71;

              info->size = 0x00400000;  break;      

 

       case (CFG_FLASH_WORD_SIZE)AMD_ID_LV640U:

              info->flash_id += FLASH_AM640U;

              info->sector_count = 128;

              info->size = 0x00800000;  break;      

 

       case (CFG_FLASH_WORD_SIZE)SST_ID_xF800A:

              info->flash_id += FLASH_SST800A;

              info->sector_count = 16;

              info->size = 0x00100000;

              break;                         

 

       case (CFG_FLASH_WORD_SIZE)SST_ID_xF160A:

              info->flash_id += FLASH_SST160A;

              info->sector_count = 32;

              info->size = 0x00200000;

              break;                         

 

       default:

              info->flash_id = FLASH_UNKNOWN;

              return (0);                   

 

       }

 

      

       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)) {

             

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

                     info->start[i] = base;

                     base += 8 << 10;

              }

              while (i < info->sector_count) {  

                     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)) {

             

              base += info->size;

              i = info->sector_count;

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

                     base -= 8 << 10;

                     --i;

                     info->start[i] = base;

              }

              while (i > 0) {              

                     base -= 64 << 10;

                     --i;

                     info->start[i] = base;

              }

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

             

              base += info->size;

              i = info->sector_count;

             

              base -= 16 << 10;

              --i;

              info->start[i] = base;

             

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

                     base -= 8 << 10;

                     --i;

                     info->start[i] = base;

              }

             

              base -= 32 << 10;

              --i;

              info->start[i] = base;

 

              while (i > 0) {              

                     base -= 64 << 10;

                     --i;

                     info->start[i] = base;

              }

       } else {

           if (info->flash_id & FLASH_BTYPE) {

             

              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 {

             

              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;

              }

           }

       }

 

      

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

             

             

              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;

       }

 

      

       if (info->flash_id != FLASH_UNKNOWN) {

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

              *addr2 = (CFG_FLASH_WORD_SIZE)0x00F0; 

       }

 

       return (info->size);

}

 

 

unsigned long flash_init (void)

{

        unsigned long size_b0;

        int i;

 

       

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

                flash_info[i].flash_id = FLASH_UNKNOWN;

        }

 

       

 

        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 = 0xlx = %ld MB\n",

                        size_b0, size_b0<<20);

        }

 

       

        flash_get_offsets (0, &flash_info[0]);

 

       

        (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;

 

      

       flag = disable_interrupts();

 

      

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

              if (info->protect[sect] == 0) {     

                  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; 

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

                       udelay(1000); 

                  } else {

                     if (sect == s_first) {

                    

                     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; 

                  }

                  l_sect = sect;

              }

       }

 

      

       if (flag)

              enable_interrupts();

 

      

       udelay (1000);

 

      

       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;

              }

             

              if ((now - last) > 1000) {     

                     putc ('.');

                     last = now;

              }

       }

 

DONE:

      

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

       addr[0] = (CFG_FLASH_WORD_SIZE)0x00F0;

 

       printf (" done\n");

       return 0;

}

 

 

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

{

       ulong cp, wp, data;

       int i, l, rc;

 

       wp = (addr & ~3);

 

      

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

              data = 0;

              for (i=0, cp=wp; i<l; ++i, ++cp) {

#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;

       }

 

      

       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);

       }

 

      

       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));

}

 

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;

 

      

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

              return (2);

       }

      

       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];

 

          

           if (flag)

             enable_interrupts();

 

           

           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 

 

#ifndef __CONFIG_H

#define __CONFIG_H

 

#define CONFIG_ARM920T          

#define    CONFIG_S3C2440                

#define CONFIG_MINI2440          

#define CONFIG_SYS_CLK_FREQ     12000000

 

 

#define USE_920T_MMU            1

#undef CONFIG_USE_IRQ                

 

#define CFG_MALLOC_LEN              (CONFIG_ENV_SIZE + 128*1024)

#define CFG_GBL_DATA_SIZE    128 

 

#if 0

#define CONFIG_DRIVER_CS8900       

#define CS8900_BASE          0x19000300

#define CS8900_BUS16        1

#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

 

#define CONFIG_SERIAL1           

 

#define    CONFIG_RTC_S3C24X0     1

 

#define CONFIG_ENV_OVERWRITE

 

#define CONFIG_BAUDRATE             115200

 

 

#define CONFIG_BOOTP_BOOTFILESIZE

#define CONFIG_BOOTP_BOOTPATH

#define CONFIG_BOOTP_GATEWAY

#define CONFIG_BOOTP_HOSTNAME

 

 

#include <config_cmd_default.h>

 

#define CONFIG_CMD_CACHE

#define CONFIG_CMD_DATE

#define CONFIG_CMD_ELF

 

#define CONFIG_CMD_PING

 

#define CONFIG_BOOTDELAY   3

#define CONFIG_NETMASK          255.255.255.0

#define CONFIG_IPADDR           10.0.0.110

#define CONFIG_SERVERIP              10.0.0.1

 

#if defined(CONFIG_CMD_KGDB)

#define CONFIG_KGDB_BAUDRATE  115200          

#define CONFIG_KGDB_SER_INDEX                

#endif

 

#define    CFG_LONGHELP                      

#define    CFG_PROMPT             "Mini2440 # " 

#define    CFG_CBSIZE        256        

#define    CFG_PBSIZE (CFG_CBSIZE+sizeof(CFG_PROMPT)+16)

#define    CFG_MAXARGS          16          

#define CFG_BARGSIZE             CFG_CBSIZE

 

#define CFG_MEMTEST_START 0x30000000   

#define CFG_MEMTEST_END           0x33F00000  

 

#undef  CFG_CLKS_IN_HZ             

 

#define    CFG_LOAD_ADDR             0x33000000   

 

#define    CFG_HZ               1562500

 

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

 

#define CONFIG_STACKSIZE     (128*1024)    

#ifdef CONFIG_USE_IRQ

#define CONFIG_STACKSIZE_IRQ    (4*1024)

#define CONFIG_STACKSIZE_FIQ     (4*1024)

#endif

 

#define CONFIG_NR_DRAM_BANKS 1       

#define PHYS_SDRAM_1            0x30000000

#define PHYS_SDRAM_1_SIZE   0x04000000

 

#define PHYS_FLASH_1              0x00000000

 

#define CFG_FLASH_BASE         PHYS_FLASH_1

 

#if 0

#define CONFIG_AMD_LV400      

#define CONFIG_AMD_LV800      

#endif

 

#define CFG_MAX_FLASH_BANKS      

#ifdef CONFIG_AMD_LV800

#define PHYS_FLASH_SIZE        0x00100000

#define CFG_MAX_FLASH_SECT      (19)

#define CONFIG_ENV_ADDR            (CFG_FLASH_BASE + 0x0F0000)

#endif

#ifdef CONFIG_AMD_LV400

#define PHYS_FLASH_SIZE        0x00080000

#define CFG_MAX_FLASH_SECT      (11)

#define CONFIG_ENV_ADDR            (CFG_FLASH_BASE + 0x070000)

#endif

 

#define PHYS_FLASH_SIZE        0x00200000

#define CFG_MAX_FLASH_SECT      (32)

#define CONFIG_ENV_ADDR            (CFG_FLASH_BASE + 0x030000)

#define CFG_MONITOR_BASE TEXT_BASE

#define CFG_MONITOR_LEN            (256*1024)

#define CFG_FLASH_ERASE_TOUT   (5*CFG_HZ)

#define CFG_FLASH_WRITE_TOUT  (5*CFG_HZ)

 

#define    CONFIG_ENV_IS_IN_FLASH     1

#define CONFIG_ENV_SIZE              0x10000 

 

#endif    

 完成后,重新编译下就行了

移植uboot中的EN29LV160AB NOR FLASH芯片

EN29LV160AB 是TQ2440选的NOR FLASH芯片,定义的sector总数手册上的是35 。 通常,在嵌入式bootloader中,有两种方式来引导启动内核:从Nor Flash启...

S3C2440与NOR FLASH(AM29LV160DB)的接线分析

NOR FLASH的特点是芯片内执行(XIP, eXecute In Place),这样应用程序可以直接在flash 闪存内运行,不必再把代码读到系统RAM中。NOR的传输效率很高,在1~4MB的小容...

S3C2440 与 NOR FLASH(AM29LV160DB)的接线分析

NOR FLASH 的特点是芯片内执行(XIP, eXecute In Place),这样应用程序可以直接在 flash 闪存内运行, 不必再把代码读到系统 RAM 中。 NOR 的传输效率很高, 在...

AM29LV040B NOR FLASH芯片驱动C代码

  • 2015年01月06日 14:56
  • 6KB
  • 下载

飞思卡尔i.MX 6Quad Android 4.2.2的LVDS屏幕驱动移植 &uboot环境变量选择屏幕

1      概述 平台:freescale i.MX 6Quad 4核开发板MCIMX6Q-SDB(不带屏幕) 操作系统:Android 4.2.2_1 内核:3.0.35 显示屏:LG的L...

AM29LV160DB-90EC的datasheet

  • 2013年04月26日 20:53
  • 1.63MB
  • 下载

am29lv160db

  • 2014年09月02日 14:33
  • 809KB
  • 下载

uboot.2015.07移植之驱动NOR Flash(6)

移植u-boot-2015.07之修改程序支持检测nor flash

QQ2440-AM29LV160DB.jflash

  • 2011年10月19日 17:47
  • 5KB
  • 下载

Am29LV160DB手册

  • 2007年12月05日 23:21
  • 1.13MB
  • 下载
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:uboot nor flash驱动移植(基于am29lv160bt)之环境变量没法保存的办法
举报原因:
原因补充:

(最多只允许输入30个字)