您的位置:首页 > 其它

U-boot在S3C2440上的移植详解(二)

2013-06-22 15:26 323 查看
4)准备进入u-boot的第二阶段(在u-boot中添加对我们开发板上NorFlash的支持)

通常,在嵌入式bootloader中,有两种方式来引导启动内核:从NorFlash启动和从NandFlash启动。u-boot中默认是从NorFlash启动,再从上一节这个运行结果图中看,还发现几个问题:第一,我开发板的NorFlash是2M的,而这里显示的是512kB;第二,出现Warning-badCRC,usingdefaultenvironment的警告信息。不是u-boot默认是从NorFlash启动的吗?为什么会有这些错误信息呢?这是因为我们还没有添加对我们自己的Nor
Flash的支持,u-boot默认的是其他型号的NorFlash,而我们的NorFlash的型号是SST39VF1601。另外怎样将命令行提示符前面的SMDK2410变成我自己定义的呢?

下面我们一一来解决这些问题,让u-boot完全对我们NorFlash的支持。首先我们修改头文件代码如下:

#gedit
include/configs/my2440.h//修改命令行前的名字和NorFlash参数部分的定义


#defineCONFIG_SYS_PROMPT"[MY2440]#"//将命令行前的名字改成[MY2440]


/*-----------------------------------------------------------------------

*FLASHandenvironmentorganization

*/

#if0//注释掉下面两个类型的Nor
Flash设置,因为不是我们所使用的型号

#defineCONFIG_AMD_LV4001/*uncommentthisifyouhaveaLV400flash*/

#define
CONFIG_AMD_LV8001/*uncommentthisifyouhaveaLV800flash*/

#endif

#define
CONFIG_SYS_MAX_FLASH_BANKS1/*maxnumberofmemorybanks*/

#ifdefCONFIG_AMD_LV800

#define
PHYS_FLASH_SIZE0x00100000/*1MB*/

#define
CONFIG_SYS_MAX_FLASH_SECT(19)
/*maxnumberofsectorsononechip*/

#defineCONFIG_ENV_ADDR
(CONFIG_SYS_FLASH_BASE
+0x0F0000)
/*addrofenvironment*/

#endif

#ifdefCONFIG_AMD_LV400

#definePHYS_FLASH_SIZE0x00080000/*512KB*/

#defineCONFIG_SYS_MAX_FLASH_SECT(11)/*max
numberofsectorsononechip*/

#defineCONFIG_ENV_ADDR(CONFIG_SYS_FLASH_BASE
+0x070000)
/*addrofenvironment*/

#endif

#define
CONFIG_SST_39VF16011//添加mini2440开发板NorFlash设置

#define
PHYS_FLASH_SIZE0x200000//我们开发板的NorFlash是2M

#define
CONFIG_SYS_MAX_FLASH_SECT(512)//根据SST39VF1601的芯片手册描述,对其进行操作有两种方式:块方式和扇区方式。现采用扇区方式(sector),1
sector=2Kword=4Kbyte,所以2M的NorFlash共有512个sector

#define
CONFIG_ENV_ADDR(CONFIG_SYS_FLASH_BASE
+0x040000)
//暂设置环境变量的首地址为0x040000(即:256Kb)

然后添加对我们mini2440开发板上2M的NorFlash(型号为SST39VF1601)的支持。在u-boot中对NorFlash的操作分别有初始化、擦除和写入,所以我们主要修改与硬件密切相关的三个函数flash_init、flash_erase、write_hword,修改代码如下:

#gedit
board/samsung/my2440/flash.c


//修改定义部分如下:

//#defineMAIN_SECT_SIZE0x10000

#defineMAIN_SECT_SIZE0x1000
//定义为4k,刚好是一个扇区的大小

//#defineMEM_FLASH_ADDR1(*(volatileu16*)(CONFIG_SYS_FLASH_BASE+(0x00000555<<1)))

//#defineMEM_FLASH_ADDR2(*(volatileu16*)(CONFIG_SYS_FLASH_BASE+(0x000002AA<<1)))

#defineMEM_FLASH_ADDR1(*(volatile
u16*)(CONFIG_SYS_FLASH_BASE
+
(0x00005555
<<1)))//这两个参数看SST39VF1601手册

#defineMEM_FLASH_ADDR2(*(volatile
u16*)(CONFIG_SYS_FLASH_BASE
+
(0x00002AAA
<<1)))



//修改flash_init函数如下:

#elifdefined(CONFIG_AMD_LV800)

(AMD_MANUFACT
&FLASH_VENDMASK)
|

(AMD_ID_LV800B
&FLASH_TYPEMASK);

#elif
defined(CONFIG_SST_39VF1601)//在CONFIG_AMD_LV800后面添加CONFIG_SST_39VF1601

(SST_MANUFACT
&FLASH_VENDMASK)
|

(SST_ID_xF1601
&FLASH_TYPEMASK);



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

//if(j<=3){

///*1stoneis16KB*/

//if(j==0){

//flash_info[i].start[j]=
flashbase+0;

//}

///*2ndand3rdareboth8KB*/

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

//flash_info[i].start[j]=
flashbase+0x4000+(j-
1)*
0x2000;

//}

///*4th32KB*/

//if(j==3){

//flash_info[i].start[j]=
flashbase+0x8000;

//}

//}else{

//flash_info[i].start[j]=flashbase+(j-3)*MAIN_SECT_SIZE;

//}

flash_info[i].start[j]
=flashbase
+j
*MAIN_SECT_SIZE;

}



//修改flash_print_info函数如下:

case
(AMD_MANUFACT&FLASH_VENDMASK):

printf
("AMD:");

break;

case
(SST_MANUFACT
&FLASH_VENDMASK)://添加SST39VF1601的

printf
("SST:
");

break;

case(AMD_ID_LV800B
&FLASH_TYPEMASK):

printf
("1xAmd29LV800BB(8Mbit)\n");

break;

case
(SST_ID_xF1601
&FLASH_TYPEMASK)://添加SST39VF1601的

printf("1xSST39VF1610
(16Mbit)\n");

break;



//修改flash_erase函数如下:

//if((info->flash_id&FLASH_VENDMASK)!=

//(AMD_MANUFACT&FLASH_VENDMASK)){

//returnERR_UNKNOWN_FLASH_VENDOR;

//}

if
((info->flash_id
&FLASH_VENDMASK)
!=

(SST_MANUFACT
&FLASH_VENDMASK))
{

returnERR_UNKNOWN_FLASH_VENDOR;

}

///*waituntilflashisready*/

//chip=0;

//do{

//result=*addr;

///*checktimeout*/

//if(get_timer_masked()>

//CONFIG_SYS_FLASH_ERASE_TOUT){

//MEM_FLASH_ADDR1=CMD_READ_ARRAY;

//chip=TMO;

//break;

//}

//if(!chip

//&&(result&0xFFFF)&BIT_ERASE_DONE)

//chip=READY;

//if(!chip

//&&(result&0xFFFF)&BIT_PROGRAM_ERROR)

//chip=ERR;

//}while(!chip);

//MEM_FLASH_ADDR1=CMD_READ_ARRAY;

//if(chip==ERR){

//rc=ERR_PROG_ERROR;

//gotooutahere;

//}

//if(chip==TMO){

//rc=ERR_TIMOUT;

//gotooutahere;

//}

while
(1)

{

if
((*addr
&0x40)
!=
(*addr
&0x40))

continue;

if
(*addr
&0x80)

{

rc=ERR_OK;

break;

}

}



//修改write_hword函数如下:

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;

///*waituntilflashisready*/

//chip=0;

//do{

//result=*addr;

///*checktimeout*/

//if(get_timer_masked()>CONFIG_SYS_FLASH_ERASE_TOUT){

//chip=ERR|TMO;

//break;

//}

//if(!chip&&((result&0x80)==(data&0x80)))

//chip=READY;

//if(!chip&&((result&0xFFFF)&BIT_PROGRAM_ERROR)){

//result=*addr;

//if((result&0x80)==(data&0x80))

//chip=READY;

//else

//chip=ERR;

//}

//}while(!chip);

//*addr=CMD_READ_ARRAY;

//if(chip==ERR||*addr!=data)

//rc=ERR_PROG_ERROR;

while
(1)

{

if
((*addr
&0x40)
!=
(*addr
&0x40))

continue;

if
((*addr
&0x80)
==
(data
&0x80))

{

rc=ERR_OK;

break;

}

}


#gedit
include/configs/my2440.h//修改命令行前的名字和NorFlash参数部分的定义

#defineCONFIG_SYS_PROMPT"[MY2440]#"//将命令行前的名字改成[MY2440]


/*-----------------------------------------------------------------------

*FLASHandenvironmentorganization

*/

#if0//注释掉下面两个类型的Nor
Flash设置,因为不是我们所使用的型号

#defineCONFIG_AMD_LV4001/*uncommentthisifyouhaveaLV400flash*/

#define
CONFIG_AMD_LV8001/*uncommentthisifyouhaveaLV800flash*/

#endif

#define
CONFIG_SYS_MAX_FLASH_BANKS1/*maxnumberofmemorybanks*/

#ifdefCONFIG_AMD_LV800

#define
PHYS_FLASH_SIZE0x00100000/*1MB*/

#define
CONFIG_SYS_MAX_FLASH_SECT(19)
/*maxnumberofsectorsononechip*/

#defineCONFIG_ENV_ADDR
(CONFIG_SYS_FLASH_BASE
+0x0F0000)
/*addrofenvironment*/

#endif

#ifdefCONFIG_AMD_LV400

#definePHYS_FLASH_SIZE0x00080000/*512KB*/

#defineCONFIG_SYS_MAX_FLASH_SECT(11)/*max
numberofsectorsononechip*/

#defineCONFIG_ENV_ADDR(CONFIG_SYS_FLASH_BASE
+0x070000)
/*addrofenvironment*/

#endif

#define
CONFIG_SST_39VF16011//添加mini2440开发板NorFlash设置

#define
PHYS_FLASH_SIZE0x200000//我们开发板的NorFlash是2M

#define
CONFIG_SYS_MAX_FLASH_SECT(512)//根据SST39VF1601的芯片手册描述,对其进行操作有两种方式:块方式和扇区方式。现采用扇区方式(sector),1
sector=2Kword=4Kbyte,所以2M的NorFlash共有512个sector

#define
CONFIG_ENV_ADDR(CONFIG_SYS_FLASH_BASE
+0x040000)
//暂设置环境变量的首地址为0x040000(即:256Kb)

#gedit
board/samsung/my2440/flash.c

//修改定义部分如下:

//#defineMAIN_SECT_SIZE0x10000

#defineMAIN_SECT_SIZE0x1000
//定义为4k,刚好是一个扇区的大小

//#defineMEM_FLASH_ADDR1(*(volatileu16*)(CONFIG_SYS_FLASH_BASE+(0x00000555<<1)))

//#defineMEM_FLASH_ADDR2(*(volatileu16*)(CONFIG_SYS_FLASH_BASE+(0x000002AA<<1)))

#defineMEM_FLASH_ADDR1(*(volatile
u16*)(CONFIG_SYS_FLASH_BASE
+
(0x00005555
<<1)))//这两个参数看SST39VF1601手册

#defineMEM_FLASH_ADDR2(*(volatile
u16*)(CONFIG_SYS_FLASH_BASE
+
(0x00002AAA
<<1)))



//修改flash_init函数如下:

#elifdefined(CONFIG_AMD_LV800)

(AMD_MANUFACT
&FLASH_VENDMASK)
|

(AMD_ID_LV800B
&FLASH_TYPEMASK);

#elif
defined(CONFIG_SST_39VF1601)//在CONFIG_AMD_LV800后面添加CONFIG_SST_39VF1601

(SST_MANUFACT
&FLASH_VENDMASK)
|

(SST_ID_xF1601
&FLASH_TYPEMASK);



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

//if(j<=3){

///*1stoneis16KB*/

//if(j==0){

//flash_info[i].start[j]=
flashbase+0;

//}

///*2ndand3rdareboth8KB*/

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

//flash_info[i].start[j]=
flashbase+0x4000+(j-
1)*
0x2000;

//}

///*4th32KB*/

//if(j==3){

//flash_info[i].start[j]=
flashbase+0x8000;

//}

//}else{

//flash_info[i].start[j]=flashbase+(j-3)*MAIN_SECT_SIZE;

//}

flash_info[i].start[j]
=flashbase
+j
*MAIN_SECT_SIZE;

}



//修改flash_print_info函数如下:

case
(AMD_MANUFACT&FLASH_VENDMASK):

printf
("AMD:");

break;

case
(SST_MANUFACT
&FLASH_VENDMASK)://添加SST39VF1601的

printf
("SST:
");

break;

case(AMD_ID_LV800B
&FLASH_TYPEMASK):

printf
("1xAmd29LV800BB(8Mbit)\n");

break;

case
(SST_ID_xF1601
&FLASH_TYPEMASK)://添加SST39VF1601的

printf("1xSST39VF1610
(16Mbit)\n");

break;



//修改flash_erase函数如下:

//if((info->flash_id&FLASH_VENDMASK)!=

//(AMD_MANUFACT&FLASH_VENDMASK)){

//returnERR_UNKNOWN_FLASH_VENDOR;

//}

if
((info->flash_id
&FLASH_VENDMASK)
!=

(SST_MANUFACT
&FLASH_VENDMASK))
{

returnERR_UNKNOWN_FLASH_VENDOR;

}

///*waituntilflashisready*/

//chip=0;

//do{

//result=*addr;

///*checktimeout*/

//if(get_timer_masked()>

//CONFIG_SYS_FLASH_ERASE_TOUT){

//MEM_FLASH_ADDR1=CMD_READ_ARRAY;

//chip=TMO;

//break;

//}

//if(!chip

//&&(result&0xFFFF)&BIT_ERASE_DONE)

//chip=READY;

//if(!chip

//&&(result&0xFFFF)&BIT_PROGRAM_ERROR)

//chip=ERR;

//}while(!chip);

//MEM_FLASH_ADDR1=CMD_READ_ARRAY;

//if(chip==ERR){

//rc=ERR_PROG_ERROR;

//gotooutahere;

//}

//if(chip==TMO){

//rc=ERR_TIMOUT;

//gotooutahere;

//}

while
(1)

{

if
((*addr
&0x40)
!=
(*addr
&0x40))

continue;

if
(*addr
&0x80)

{

rc=ERR_OK;

break;

}

}



//修改write_hword函数如下:

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;

///*waituntilflashisready*/

//chip=0;

//do{

//result=*addr;

///*checktimeout*/

//if(get_timer_masked()>CONFIG_SYS_FLASH_ERASE_TOUT){

//chip=ERR|TMO;

//break;

//}

//if(!chip&&((result&0x80)==(data&0x80)))

//chip=READY;

//if(!chip&&((result&0xFFFF)&BIT_PROGRAM_ERROR)){

//result=*addr;

//if((result&0x80)==(data&0x80))

//chip=READY;

//else

//chip=ERR;

//}

//}while(!chip);

//*addr=CMD_READ_ARRAY;

//if(chip==ERR||*addr!=data)

//rc=ERR_PROG_ERROR;

while
(1)

{

if
((*addr
&0x40)
!=
(*addr
&0x40))

continue;

if
((*addr
&0x80)
==
(data
&0x80))

{

rc=ERR_OK;

break;

}

}


修改完后重新编译u-boot,下载到RAM中运行结果如下图:



从运行结果图看,NorFlash的大小可以正确检测到了,命令行前面的名字也由原来的SMDK2410改成我自己定义的[MY2440]了,但是还会出现badCRC的警告信息,其实这并不是什么问题,只是还没有将环境变量设置到NorFlash中,我们执行一下u-boot的:saveenv命令就可以了。如下图:



再重新下载u-boot.bin文件到RAM中运行,可以观察到不会出现警告信息了,这时候u-boot已经对我们开发板上的NorFlash完全支持了。如下:

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: