Coder
分类: 嵌入式
2010-02-09 02:12:13
第二步、增加对NorFlash的支持
接下来,我们来提供对于Nor Flash的支持。U-Boot的SMDK2410相关部分是完整的支持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 +
这几个宏的意思基本上都还是比较明确的。
接下来来看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函数,这个函数很容易理解也很容易修改。接着来修改用来擦除flash的flash_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。注意,mini2440的flash编程需要四个步骤,第三个步骤是往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移植到mini24440,u-boot版本2008.10:
http://blog.csdn.net/hugerat/archive/2009/01/21/3847025.aspx
移植u-boot2009.8到OK2440V3开发板:
友善之臂们mini2440开发板Linux移植:
http://blog.chinaunix.net/u1/34474/showart.php?id=1316396