Chinaunix首页 | 论坛 | 博客
  • 博客访问: 819740
  • 博文数量: 117
  • 博客积分: 2583
  • 博客等级: 少校
  • 技术积分: 1953
  • 用 户 组: 普通用户
  • 注册时间: 2008-12-06 22:58
个人简介

Coder

文章分类
文章存档

2013年(1)

2012年(10)

2011年(12)

2010年(77)

2009年(13)

2008年(4)

分类: 嵌入式

2010-02-09 02:12:13

第二步、增加对NorFlash的支持

接下来,我们来提供对于Nor Flash的支持。U-BootSMDK2410相关部分是完整的支持AMD的两块NorFlash的,可惜我们的板子上带的是SST39VF1601。不过,对于NorFlash的支持还是比较简单的。

我们依然来追踪U-Boot的执行流,在lib_arm/board.c文件中我们可以看到:

#ifndef CONFIG_SYS_NO_FLASH

    /* configure available FLASH banks */

    display_flash_config (flash_init ());

#endif /* CONFIG_SYS_NO_FLASH */

默认情况下,U-Boot实际上支持了Nor Flash的。追踪flash_init函数,在board/Samsung/mini2440/mini2440.c文件中可以找到它。我们的flash移植修改的主要代码也就在这儿了。

首先,修改配置文件中的相关部分。

include/configs/mini2440.h文件中,

#define CONFIG_AMD_LV400 1 /* uncomment this if you have a LV400 flash */
#if 0
#define CONFIG_AMD_LV800 1 /* uncomment this if you have a LV800 flash */
#endif

修改为:
#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_SST_xF1601   1
#ifdef CONFIG_SST_xF1601
#define PHYS_FLASH_SIZE   0x00200000  /* 2MB */
#define CONFIG_SYS_MAX_FLASH_SECT (32)  /* max number of sectors on one chip */
#defne CONFIG_ENV_ADDR  (CONFIG_SYS_FLASH_BASE + 1F0000)

这几个宏的意思基本上都还是比较明确的。

接下来来看board/Samsung/mini2440/flash.c文件中的flash_init函数,添加设置flash_id的代码:

#elif defined(CONFIG_SST_VF1601)

           (SST_MANUFACT & FLASH_VENDMASK) |

           (SST_ID_xF1601 & FLASH_TYPEMASK);

#else

找到了AMD_MANUFACT定义的地方,也就能找到这些我们需要的宏了。

接着,修改设置各个sector起始地址的代码,将原来的循环改为:

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

#ifndef CONFIG_SST_VF1601

           if (j <= 3) {

              /* 1st one is 16 KB */

              if (j == 0) {

                  flash_info[i].start[j] =

                     flashbase + 0;

              }

 

              /* 2nd and 3rd are both 8 KB */

              if ((j == 1) || (j == 2)) {

                  flash_info[i].start[j] =

                     flashbase + 0x4000 + (j -1) *0x2000;

              }

 

              /* 4th 32 KB */

              if (j == 3) {

                  flash_info[i].start[j] =

                     flashbase + 0x8000;

              }

           } else {

              flash_info[i].start[j] =

                  flashbase + (j - 3) * MAIN_SECT_SIZE;

           }

#else

              flash_info[i].start[j] =

                  flashbase + (j) * MAIN_SECT_SIZE;

#endif

接着修改flash_print_info函数,这个函数很容易理解也很容易修改。接着来修改用来擦除flashflash_erase函数。原来的代码,前面判断如果不是AMD的芯片,它会直接返回,这个地方需要修改。另外,SST39VF1601的命令和原来带的是不一样的,修改几个命令的宏定义,将原来的改为:

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

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

#define CMD_ERASE_CONFIRM   0x00000050

等待完成的部分也需要做一些小小的改动,注释掉原来的代码,添加:

/* 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;

  }

接下来,修改flash的编程函数write_hword注意,mini2440flash编程需要四个步骤,第三个步骤是往MEM_FLASH_ADDR1里写CMD_PROGRAM然后修改等待完成的部分,将原来的修改为:

     /* 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

}

这样,就完成了flash驱动的移植。可以通过cp命令,往flash中写东西来进行测试。

注意,U-Boot里面用的词sector和手册里面用的词sector指的不是同一个意思,U-Boot里的sector和手册里的block是等价的,是一个更大的单位

主要参考的文档:

u-boot移植到mini24440u-boot版本2008.10

http://blog.csdn.net/hugerat/archive/2009/01/21/3847025.aspx
移植u-boot2009.8OK2440V3开发板:

友善之臂们mini2440开发板Linux移植:
http://blog.chinaunix.net/u1/34474/showart.php?id=1316396

阅读(1747) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~