文章详情

  • 游戏榜单
  • 软件榜单
关闭导航
热搜榜
热门下载
热门标签
php爱好者> php文档>U-boot实现NOR FLASH启动

U-boot实现NOR FLASH启动

时间:2009-08-09  来源:lixuan216

起始工作就不多说了,本篇主要介绍U-boot的nor flash启动。 修改如下: (include/configs/<yourneme>.h):
添加:
#define CONFIG_SST_39VF1601   1
#define CFG_MAX_FLASH_BANKS 1
#define PHYS_FLASH_SIZE       0x200000   /* 2MB */
#define CFG_MAX_FLASH_SIZE    (512)       /* max number of sectors on one chip */
#define CFG_ENV_ADDR (CFG_FLASH_BASE + 0x40000)   /* addr of environment */
并将关于AM29LV400和AM29LV800的信息全部注释掉。
NOR FLASH的操作函数在board/fs2410/flash.c中实现。它支持AM29LV400和AM29LV800.为了了解NORFLASH的操作,我们直接修改这个文件。首先我们的板子已经有了一个U-BOOT,但由于烧写的问题,我们这里启动一个调试方法,具体就是在配置文件include/configs/fs2410.h里定义:
#define CONFIG_SKIP_LOWLEVEL_INIT,这个宏用于cpu/arm920t/start.S里,主要是对CPU和存储控制器的初始化,所以调试阶段跳过初始化。然后修改board/fs2410/config.mk:
将TEXT_BASE = 0x33F80000暂时修改为:
TEXT_BASE = 0x33E00000。最后将u-boot.bin下载到这个地址,然后 从这个地址启动u-boot即可。
修改以上步骤以后,接下来我们修改board/fs2410/flash.c:
将:
#define MAIN_SECT_SIZE 0x10000 /* 64 KB */
修改为:
#define MAIN_SECT_SIZE 0x1000 /* 4 KB */(按sector操作)

将:
#define MEM_FLASH_ADDR1     (*(volatile u16 *)(CFG_FLASH_BASE + (0x00000555 << 1)))
#define MEM_FLASH_ADDR2     (*(volatile u16 *)(CFG_FLASH_BASE + (0x000002AA << 1)))
修改为:
#define MEM_FLASH_ADDR1     (*(volatile u16 *)(CFG_FLASH_BASE + (0x000005555 << 1)))
#define MEM_FLASH_ADDR2     (*(volatile u16 *)(CFG_FLASH_BASE + (0x000002AAA << 1)))
这个参数参看SST39VF1601的手册可以得到。

在flash_init函数里仿照:
if defined(CONFIG_AMD_LV400)
            (AMD_MANUFACT & FLASH_VENDMASK) |
            (AMD_ID_LV400B & FLASH_TYPEMASK);
添加对SST39VF1601厂商ID和DEVICE ID的设置:
添加:
#if defined (CONFIG_SST_39VF1601)  
            (SST_MANUFACT & FLASH_VENDMASK)
            (SST_ID_xF1601 & FLASH_TYPEMASK);

由于SST39VF1601每个SECTOR的大小都是一样的。所以修改:
将:
for (j = 0; j < flash_info[i].sector_count; j++) {
            if (j <= 3) {
                /* 1st one is 16 KB */
                if (j == 0) {
                    flash_info[i].start[j] =
                        flashbase + 0;
                }
........
........
修改为:
for (j = 0; j < flash_info[i].sector_count; j++) {
     flash_info[i].start[j] =flashbase + j*MAIN_SECT_SIZE;
                }

当我们键入flinfo命令的时候,将我们的nor flash的信息答应,这里我们在flash_print_info添加相应的支持:
在:
case (AMD_MANUFACT & FLASH_VENDMASK):
        printf ("AMD: ");
        break;
后添加:
case (SST_MANUFACT & FLASH_VENDMASK):
        printf ("SST: ");
        break;

在:
case (AMD_ID_LV800B & FLASH_TYPEMASK):
        printf ("1x Amd29LV800BB (8Mbit)\n");
        break;
之后添加:
case (SST_ID_xF1601& FLASH_TYPEMASK):
        printf ("1x SST39VF1610 (16Mbit)\n");
        break;
接下来修改flash_erase函数,这里我们用SECTOR进行擦出操作。具体修改如下:
将:
if ((info->flash_id & FLASH_VENDMASK) !=
        (AMD_MANUFACT & FLASH_VENDMASK)) {
        return ERR_UNKNOWN_FLASH_VENDOR;
修改为:if ((info->flash_id & FLASH_VENDMASK) !=
        (SST_MANUFACT & FLASH_VENDMASK)) {
        return ERR_UNKNOWN_FLASH_VENDOR;
阅读弄SST39VF1601使用手册,我们对flash_erase()修改如下:
.... if (info->protect[sect] == 0) {      /* not protected */                      vu_short *addr = (vu_short *) (info->start[sect]);                      MEM_FLASH_ADDR1 = CMD_UNLOCK1;                      MEM_FLASH_ADDR2 = CMD_UNLOCK2;                      MEM_FLASH_ADDR1 = CMD_ERASE_SETUP;                        MEM_FLASH_ADDR1 = CMD_UNLOCK1;                      MEM_FLASH_ADDR2 = CMD_UNLOCK2;                      *addr = CMD_ERASE_CONFIRM;                        /* wait until flash is ready */                      while(1){                             unsigned short i;                             i = *((volatile unsigned short *)addr)&0x40;                             if(i!=*((volatile unsigned short *)addr)&0x40)                                    continue;                             if(*((volatile unsigned short *)addr)&0x80)                                     break;                      }                      printf ("ok.\n");               } else {   /* it was protected */                      printf ("protected!\n");               }        }        if (ctrlc ()) ........ 对flash_hword()修改如下: volatile static int write_hword (flash_info_t * info, ulong dest, ushort data) {        vu_short *addr = (vu_short *) dest;        ushort result;        int rc = ERR_OK;        int cflag, iflag;        int chip;          /*         * Check if Flash is (sufficiently) erased         */        result = *addr;        if ((result & 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.         */        cflag = icache_status ();        icache_disable ();        iflag = disable_interrupts ();          MEM_FLASH_ADDR1 = CMD_UNLOCK1;        MEM_FLASH_ADDR2 = CMD_UNLOCK2;        MEM_FLASH_ADDR1 = CMD_PROGRAM;        *addr = data;          /* arm simple, non interrupt dependent timer */        reset_timer_masked ();          /* wait until flash is ready */        while(1){               unsigned short i = *(volatile unsigned short *)addr & 0x40;               if(i != *(volatile unsigned short *)addr & 0x40)   //D6 == D6                      continue;               if((*(volatile unsigned short *)addr & 0x80)==(data & 0x80)){                      rc = ERR_OK;                      break;     //D7 == D7               }        }        if (iflag)               enable_interrupts ();        if (cflag)               icache_enable ();        return rc; } 到此为止,NOR FLASH支持基本修改完毕! 相关连接:http://blog.chinaunix.net/u2/63379/showart_1330720.html
相关阅读 更多 +
排行榜 更多 +
动物大战僵尸I

动物大战僵尸I

飞行射击 下载
龙兽争霸无限零件图纸

龙兽争霸无限零件图纸

飞行射击 下载
车祸卡车模拟器

车祸卡车模拟器

赛车竞速 下载