TE2440II开发板使用的Norflash是INTEL的JS28F320J3D75,4M,32个block,每个128KB。本文添加对Norflash的支持,使Uboot可以烧录到Norflash,从Norflash启动,并执行Norflash下的命令。 
这样需要注释掉 /include/configs/TE2440II.h中的 
#define CONFIG_SKIP_LOWLEVEL_INIT     1    
//#define CONFIG_SKIP_RELOCATE_UBOOT    1   
把include/configs/TE2440II.h的Physical Memory Map和FLASH and environment organization修改为,这里添加了/board/cmi/flash.c中部份变量的宏定义。FLASH and environment organization这里的sector指的是手册中的bank,所以大小是128KB,为32块。#define CONFIG_ENV_ADDR         (CONFIG_SYS_FLASH_BASE + 0x40000),这个偏移是自己定的,是放环境变量的,只要不在uboot的代码区就可以。 
CONFIG_SYS_FLASH_ERASE_TOUT和CONFIG_SYS_FLASH_WRITE_TOUT是超时的时间,如果小了,自己改大些。cpu/arm920t/s3c24x0/timer.c中讲述了怎么获得时间的。 
/*----------------------------------------------------------------------- 
* 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 CONFIG_SYS_FLASH_BASE        PHYS_FLASH_1 
#define FLASH_BASE0_PRELIM  PHYS_FLASH_1 
#define CONFIG_SYS_MONITOR_BASE TEXT_BASE 
/*----------------------------------------------------------------------- 
* FLASH and environment organization 
*/ 
#define CONFIG_SYS_MAX_FLASH_BANKS    1    /* max number of memory banks */ 
#define CONFIG_INTEL_JS28F320 1 
#define PHYS_FLASH_SIZE 0x400000   /* 4M */ 
#define CONFIG_SYS_MAX_FLASH_SECT 32 
#define CONFIG_ENV_ADDR         (CONFIG_SYS_FLASH_BASE + 0x40000) 
/* timeout values are in ticks */ 
#define CONFIG_SYS_FLASH_ERASE_TOUT    (2*CONFIG_SYS_HZ) /* Timeout for Flash Erase */ 
#define CONFIG_SYS_FLASH_WRITE_TOUT    (2*CONFIG_SYS_HZ) /* Timeout for Flash Write */ 
#define    CONFIG_ENV_IS_IN_FLASH    1 
#define CONFIG_ENV_SIZE        0x20000    /* Total Size of Environment Sector */ 
#endif    /* __CONFIG_H */ 
用board/cmi/下的flash.c文件替换board/samsung/TE2440II/下的flash.c,因为cmi目录下的正好是JS28F320J3D75的驱动文件。删除这个write_short函数的申明和定 义、删除write_buff函数。替换成下面的两个函数: 
/****************************************************************************************************** 
* Copy memory to flash. 
*/ 
int write_buff (flash_info_t *info, uchar *src, ulong addr, ulong cnt) 
{ 
   ulong cp, wp; 
   ushort data; 
   int l; 
   int i, rc; 
wp = (addr & ~1); /* get lower word aligned address */
/* 
    * handle unaligned start bytes 
    */ 
   if ((l = addr - wp) != 0) 
   { 
      data = 0; 
      for (i=0, cp=wp; i<l; ++i, ++cp) { 
       data = (data >> 8) | (*(uchar *)cp << 8); 
      } 
      for (; i<2 && cnt>0; ++i) { 
     data = (data >> 8) | (*src++ << 8); 
     --cnt; 
     ++cp; 
      } 
      for (; cnt==0 && i<2; ++i, ++cp) { 
     data = (data >> 8) | (*(uchar *)cp << 8); 
      } 
if ((rc = write_word(info, wp, data)) != 0) { 
     return (rc); 
      } 
      wp += 2; 
   } 
/* 
    * handle word aligned part 
    */ 
   while (cnt >= 2) { 
      data = *((vu_short*)src); 
      if ((rc = write_word(info, wp, data)) != 0) { 
      return (rc); 
      } 
      src += 2; 
      wp  += 2; 
      cnt -= 2; 
   } 
if (cnt == 0) { 
      return ERR_OK; 
   } 
/* 
    * handle unaligned tail bytes 
    */ 
   data = 0; 
   for (i=0, cp=wp; i<2 && cnt>0; ++i, ++cp) { 
      data = (data >> 8) | (*src++ << 8); 
      --cnt; 
   } 
   for (; i<2; ++i, ++cp) { 
      data = (data >> 8) | (*(uchar *)cp << 8); 
   } 
return write_word(info, wp, data); 
} 
/****************************************************************************************************** 
* Copy memory to flash. 
*/ 
static int write_word (flash_info_t *info, ulong dest, ushort data) 
{ 
   vu_short *addr = (vu_short *)dest, val; 
   int rc = ERR_OK; 
   int flag; 
/* Check if Flash is (sufficiently) erased , fix by kavin*/ 
   if ((*addr & data) != data) 
      return ERR_NOT_ERASED; 
/* 
    * Disable interrupts which might cause a timeout 
    * here. Remember that our exception vectors are 
    * at address 0 in the flash, and we don't want a 
    * (ticker) exception to happen while the flash 
    * chip is in programming mode. 
    */ 
   flag = disable_interrupts(); 
/* clear status register command */ 
   *addr = 0x50; 
/* program set-up command */ 
   *addr = 0x40; 
/* latch address/data */ 
   *addr = data; 
/* arm simple, non interrupt dependent timer */ 
   reset_timer_masked(); 
/* wait while polling the status register */ 
   while(((val = *addr) & 0x80) != 0x80) 
   { 
      if (get_timer_masked() > CONFIG_SYS_FLASH_WRITE_TOUT) { 
      rc = ERR_TIMOUT; 
      /* suspend program command */ 
      *addr = 0xB0; 
      goto outahere; 
      } 
   } 
if(val & 0x1A) {        /* check for error */ 
      printf("\nFlash write error %02x at address %08lx\n", 
           (int)val, (unsigned long)dest); 
      if(val & (1<<3)) { 
     printf("Voltage range error.\n"); 
     rc = ERR_PROG_ERROR; 
     goto outahere; 
      } 
      if(val & (1<<1)) { 
     printf("Device protect error.\n"); 
     rc = ERR_PROTECTED; 
     goto outahere; 
      } 
      if(val & (1<<4)) { 
     printf("Programming error.\n"); 
     rc = ERR_PROG_ERROR; 
     goto outahere; 
      } 
      rc = ERR_PROG_ERROR; 
      goto outahere; 
   } 
outahere: 
   /* read array command */ 
   *addr = 0xFF; 
if (flag) 
      enable_interrupts(); 
return rc; 
} 
修改flash.c文件中的一个宏定义: 
把: 
#define FLASH_BLOCK_SIZE        0x00010000 
改为: 
#define FLASH_BLOCK_SIZE        0x00020000 
修改开发板目录下的lowlevel_init.S文件中SDARM刷新参数为: 
#define REFCNT    1258    /* period=7.8125us, HCLK=405/4 Mhz, (2048+1-7.8125*405/4) */ 
Lowlevel_init.S中对SDRAM进行了初始化,因为我们要把第二阶段的代码搬运到SDRAM中,REFCNT是刷新计数器,这个在移植的时候是一定要修改的。手册上有公式:Refresh period = (2^11-refresh_count+1)/HCLK,我使用的这款芯片在datasheet写着8192Refresh cycle/64ms,所以一个刷新周期为64ms/8192=7.8125us。目前公认的标准是,存储体中电容中数据有效保存期上限是64ms,也就是说每一行刷新的循环周期是64ms,这样刷新的速度就是:行数量/64ms。我的理解是CPU并不知道你用的SDRAM的刷新速度是多少,特殊功能寄存器也没有直接传递刷新速度的位,但是有一个刷新计数器,可以通过刷新计数器间接获得刷新速度,所以要设定刷新计数器。 
然后就可以烧录Norflash了。


