遇顺境,处之淡然;遇逆境,处之泰然
分类: LINUX
2012-03-10 19:41:15
u-boot-2010.06在mini2440上的移植(二)---增加nor flash功能
移植环境
1,主机环境:VMware7.1.4 + Ubuntu10.04
2,编译环境:arm-linux-gcc v4.3.2
3,开发板:mini2440,2M nor flash,256M nand flash,DM9000网卡。
4,u-boot版本:u-boot-2010.06
注:修改或添加的地方都用红色表示
移植步骤
(一)修改mini2440的配置头文件
$ gedit include/configs/mini2440.h
(1)增加自动补齐和历史记录命令
#define CONFIG_AUTO_COMPLETE /*command auto complete*/
#define CONFIG_CMDLINE_EDITING /*command history record*/
(2)注释掉下面两个类型的Nor Flash设置,并定义我们所使用的型号
/*-----------------------------------------------------------------------
* FLASH and environment organization
*/
#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_39VF1601 1
#ifdef CONFIG_SST_39VF1601 //添加mini2440开发板Nor Flash设置
#define PHYS_FLASH_SIZE 0x200000 //我们开发板的Nor Flash是2M
#define CONFIG_SYS_MAX_FLASH_SECT (512) //根据SST39VF1601的芯片手册描述,对其进行操作有两种方式:块方式和扇区方式。现采用扇区方式(sector),1 sector = 2Kword = 4Kbyte,所以2M的Nor Flash共有512个sector
#define CONFIG_ENV_ADDR (CONFIG_SYS_FLASH_BASE + 0x040000) //暂设置环境变量的地址为0x040000(即:256Kb)
#endif
(二)然后添加对我们mini2440开发板上2M的Nor Flash(型号为SST39VF1601)的支持。在u-boot中对Nor Flash的操作分别有初始化、擦除和写入,所以我们主要修改与硬件密切相关的三个函数flash_init、flash_print_info、flash_erase、write_hword,修改代码如下:
$ gedit board/jason/mini2440/flash.c
(1)定义一个扇区的大小
//#define MAIN_SECT_SIZE 0x10000 /* 64 KB */
#define MAIN_SECT_SIZE 0x1000 //定义为4k,刚好是一个扇区的大小
(2)修改映射的地址
#ifdef CONFIG_SST_39VF1601
#define MEM_FLASH_ADDR1 (*(volatile u16 *)(CONFIG_SYS_FLASH_BASE + (0x000005555 << 1)))
#define MEM_FLASH_ADDR2 (*(volatile u16 *)(CONFIG_SYS_FLASH_BASE + (0x000002AAA << 1)))
#else
#define MEM_FLASH_ADDR1 (*(volatile u16 *)(CONFIG_SYS_FLASH_BASE + (0x00000555 << 1)))
#define MEM_FLASH_ADDR2 (*(volatile u16 *)(CONFIG_SYS_FLASH_BASE + (0x000002AA << 1)))
#endif
(3)在flash_init函数中修改或添加代码如下
#if defined(CONFIG_AMD_LV400)
(AMD_MANUFACT & FLASH_VENDMASK) |
(AMD_ID_LV400B & FLASH_TYPEMASK);
#elif defined(CONFIG_AMD_LV800)
(AMD_MANUFACT & FLASH_VENDMASK) |
(AMD_ID_LV800B & FLASH_TYPEMASK);
#elif defined(CONFIG_SST_39VF1601)
(SST_MANUFACT & FLASH_VENDMASK) |
(SST_ID_xF1601 & FLASH_TYPEMASK);
#else
#error "Unknown flash configured"
#endif
………………
for (j = 0; j < flash_info[i].sector_count; j++) {
#ifndef CONFIG_SST_39VF1601
if (j <= 3) {
………………
#else
flash_info[i].start[j] =
flashbase + (j) * MAIN_SECT_SIZE;
#endif
}
size += flash_info[i].size;
………………
(4) 在flash_print_info 函数中修改或添加后代码如下:
void flash_print_info (flash_info_t * info)
{
int i;
switch (info->flash_id & FLASH_VENDMASK) {
case (AMD_MANUFACT & FLASH_VENDMASK):
printf ("AMD: ");
break;
case (SST_MANUFACT & FLASH_VENDMASK):
printf ("SST: ");
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 (SST_ID_xF1601 & FLASH_TYPEMASK):
printf ("1x SST39VF1601 (16Mbit)\n");
break;
default:
printf ("Unknown Chip Type\n");
goto Done;
break;
}
……………………
Done:;
}
(5) 在flash_erase函数中修改或添加后代码如下:
int flash_erase (flash_info_t * info, int s_first, int s_last)
{
ushort result;
int iflag, cflag, prot, sect;
int rc = ERR_OK;
int chip;
/* first look for protection bits */
if (info->flash_id == FLASH_UNKNOWN)
return ERR_UNKNOWN_FLASH_TYPE;
if ((s_first < 0) || (s_first > s_last)) {
return ERR_INVAL;
}
#ifdef CONFIG_SST_39VF1601
if ((info->flash_id & FLASH_VENDMASK) !=
(SST_MANUFACT & FLASH_VENDMASK)) {
return ERR_UNKNOWN_FLASH_VENDOR;
}
#else
if ((info->flash_id & FLASH_VENDMASK) !=
(AMD_MANUFACT & FLASH_VENDMASK)) {
return ERR_UNKNOWN_FLASH_VENDOR;
}
#endif
prot = 0;
…………
*addr = CMD_ERASE_CONFIRM;
#if 0
/* wait until flash is ready */
……………
if (chip == TMO) {
rc = ERR_TIMOUT;
goto outahere;
}
#endif
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");
}
}
…………………
(6) 在write_hword函数中修改或添加后代码如下:
static int write_hword (flash_info_t * info, ulong dest, ushort data)
{
vu_short *addr = (vu_short *) dest;
……………………….
MEM_FLASH_ADDR1 = CMD_UNLOCK1;
MEM_FLASH_ADDR2 = CMD_UNLOCK2;
//MEM_FLASH_ADDR1 = CMD_UNLOCK_BYPASS;
MEM_FLASH_ADDR1 = CMD_PROGRAM;
//*addr = CMD_PROGRAM;
*addr = data;
reset_timer_masked ();
#if 0
/* wait until flash is ready */
………………….
if (chip == ERR || *addr != data)
rc = ERR_PROG_ERROR;
#endif
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)
………..
return rc;
}
(三)修改完后重新编译u-boot,从运行结果图看
(四)从运行结果图看,Nor Flash的大小可以正确检测到了,但是还会出现bad CRC的警告信息,其实这并不是什么问题,只是还没有将环境变量设置到Nor Flash中,我们执行一下u-boot的:saveenv命令就可以了。如下图:
(五)重启开发板之后显示如下:
可以看到环境变量保存成功,将开发板重启后不会再有bad CRC警告,nor flash 移植成功。
(六)增加标语显示
$ gedit arch/arm/lib/board.c
static int display_banner (void)
{
printf ("\n\n%s\n\n", version_string);
printf (" Modified by JASON \n"); //display on serial console
printf (" Love Linux Forever!\n\n");
debug ("U-Boot code: %08lX -> %08lX BSS: -> %08lX\n",
………………..
return (0);
}