uboot移植中的NOR FLASH配置

移植环境:

主芯片:SAMSUNG s3c2440A

开发板:GT2440

uboot版本:u-boot1.1.6

NOR Flash型号:EN29LV160AB。

硬件连接原理图如下图所示:

uboot移植中的NOR FLASH配置_第1张图片  uboot移植中的NOR FLASH配置_第2张图片

EN29LV160支持半字、单字节访问方式。如上图Pin47BYTE#为high时,采用Word Mode。Flash芯片的地址线A0-A19与s3c2440地址线的ADDR1-ADDR20连接。因为Flash是half word访问模式,s3c2440是按照单字节方式访问。故地址线错位连接。这点在s3c2440的datasheet中有描述。例如当s3c2440读取地址0处的数据时,发送的地址为0000 0000 0000 0000 0000b,地址线错位连接后,Flash芯片接收的地址为0。当s3c2440读取地址1处的数据时,发送的地址为0000 0000 0000 0000 0001,地址线错位连接后,Flash芯片接收的地址依然为0。这样为的是解决存储单元不匹配的问题。

EN29LV160AB的扇区分配,datasheet描述如下:

Flexible sector architecture(复杂的扇区结构)

One 16-KByte、two 8-KByte、one 32-KByte and third-one 64-KByte sectors(byte mode) 

One 8-KWord、two 4-KWord、One 16-KWord and third-one 32-KWord sectors(Word mode)


软件修改

在/include/configs/2440.h中,

//注释原程序采用的两块nor Flash的配置 

#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 CONFIG_SYS_MAX_FLASH_BANKS 1  /* max number of memory banks */

#ifdef CONFIG_AMD_LV800

#define PHYS_FLASH_SIZE            0x00100000  /* 1MB */

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

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

#endif

#ifdef CONFIG_AMD_LV400

#define PHYS_FLASH_SIZE            0x00080000  /* 512KB */

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

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

#endif

//第175行添加如下内容

#define CONFIG_EON_29LV160AB     1        //添加芯片

#define PHYS_FLASH_SIZE            0x200000 //Flash芯片的总容量

#define CONFIG_SYS_MAX_FLASH_SECT  (35)     //根据EN29LV160AB的芯片手册描述,共35个扇区

#define CFG_ENV_ADDR     (CONFIG_SYS_FLASH_BASE + 0x060000) //暂设置环境变量的首地址为0x060000(即:384Kb)         


在/include/flash.c中,添加Flash的ID和厂商代码,添加代码:

#define EON_ID_LV160AB   0x22492249

#define EON_MANUFACT 0x001c001c

在/board/2440/flash.c中修改nor FLASH的驱动,该文件中包括对FLASH的初始化、扇区的擦除和写入。主要是对flash_init、flash_erase、write_hword三个函数的修改。

#define MAIN_SECT_SIZE     0x8000  // 根据EON29LV160AB的datasheet描述,主扇区大小为32K,以word mode方式访问

#define MEM_FLASH_ADDR1  (*(volatile u16 *)(CONFIG_SYS_FLASH_BASE + (0x00000555 << 1)))

#define MEM_FLASH_ADDR2  (*(volatile u16 *)(CONFIG_SYS_FLASH_BASE + (0x000002AA << 1)))

由于我们是把norflash连接到了s3c2440的bank0上,因此norflash中的地址相对于s3c2440来说基址为0x00000000,即CONFIG_SYS_FLASH_BASE  = 0。

EN29LV160AB手册要求将解锁码写到指定的地址0x555和0x2AA上,所以s3c2440发送的地址应该向左移动一位,保证nor FLASH的正确接收地址信息。
由数据手册可知EN29LV160AB第0扇区大小为8K,第1、2为4K,第3为16K,后面31扇区为32K。所以需要按照描述修改程序中的前面4个扇区的大小

// 增加的代码

#elif defined(CONFIG_EON_29LV160AB) // 参考原FLASH描述进行修改,改与EN29LV160AB相关

(EON_MANUFACT & FLASH_VENDMASK) |

(EON_ID_LV160AB & FLASH_TYPEMASK);

#else

#error "Unknow flash configured"

#endif


for (j = 0; j < flash_info[i].sector_count; j++) 

{
    if (j <= 3) 
   {
        /* 1st one is 8 KB */
       if (j == 0) 
      {
             flash_info[i].start[j] = flashbase + 0;
      }
      /* 2nd and 3rd are both 4 KB */
      if ((j == 1) || (j == 2)) 
     {
           flash_info[i].start[j] = flashbase + 0x2000 + (j - 1) * 0x1000;
     }
     /* 4th 16 KB */
     if (j == 3) 
    {
           flash_info[i].start[j] = flashbase + 0x4000;
     }

else 
{
       flash_info[i].start[j] = flashbase + (j - 3) * MAIN_SECT_SIZE;
}
}
size += flash_info[i].size;


修改flash_print_info,添加EN29LV160AB相关信息如下:
switch (info->flash_id & FLASH_VENDMASK) {
case (AMD_MANUFACT & FLASH_VENDMASK):
  printf ("AMD: ");
  break;
case (EON_MANUFACT & FLASH_VENDMASK):
  printf ("EON: ");

  break;
default:
  printf ("Unknown Vendor ");
  break;
}
switch (info->flash_id & FLASH_TYPEMASK) {
case (AMD_ID_LV400B & FLASH_TYPEMASK):
  printf ("1x Amd29LV400BB (4Mbit)\n");
  break;
case (AMD_ID_LV800B & FLASH_TYPEMASK):
  printf ("1x Amd29LV800BB (8Mbit)\n");
  break;
case (EON_ID_LV160AB & FLASH_TYPEMASK):
  printf ("1x EN29LV160AB (16Mbit)\n");

  break;
default:
  printf ("Unknown Chip Type\n");
  goto Done;
  break;
}
修改int flash_erase (flash_info_t * info, int s_first, int s_last)
if ((info->flash_id & FLASH_VENDMASK) != //  由于我们使用的是EN29LV160AB的FLASH芯片,所以其他型号为未知型号
     (EON_MANUFACT & FLASH_VENDMASK)) {
  return ERR_UNKNOWN_FLASH_VENDOR;

4.      至此,uboot关于Norflash已经移植好.

http://blog.csdn.net/quannii/article/details/8861572



你可能感兴趣的:(linux,学习,嵌入式硬件)