分类: LINUX
2011-07-28 11:03:15
上接:《1 uboot 在mini2440上的移植环境构建》
参考说明:
(1)本文参考了singleboy:
(2)参考了Tekkaman Ninja的blog文章,http://blog.chinaunix.net/space.php?uid=20543672&do=blog&cuid=2085154
(3)参考了黄刚的blog:http://blogold.chinaunix.net:80/u3/101649/showart.php?id=2276917
向上述作者表示感谢!一、移植环境说明
1,主机环境:VMWare下RHEL5;
2,编译器:arm-linux-gcc v4.4.3;
3,开发板:mini2440,2M nor flash,256M nand flash(自改,原64M),NEC屏;
4,u-boot版本:u-boot-2009.08。
二、移植任务描述
1.修改终端命令行前的提示符“SMDK2410#”为自定义;
2.实现uboot对开发板上Nor Flash(型号SST39VF1601)的支持。
三、移植步骤
虽然 S3C2440 和S3C2410 对于Nor Flash 的链接都是一样的,但是S3C2410 使用的AMD 的Nor Flash 芯片,而mini2440 使用的SST 的Nor Flash。这两款芯片在写入时所使用的块大小、时序和指令代码有差别,所以必须根据芯片的数据手册进行修改。主要的差别请看数据手册的对比:
SST39VF1601:
Am29LV160:
【1】修改开发板终端命令行提示符及Nor Flash参数的部分定义
gedit include/configs/mini2440.h头文件,定位到120行,其中的 "SMDK2410 # " 就是开发板在终端中显示的提示符,现在将其改为 "[MINI2440]# " ,如下所示:
/*
* Miscellaneous configurable options
*/
#define CONFIG_SYS_LONGHELP /* undef to save memory */
#define CONFIG_SYS_PROMPT "[MINI2440]# " /* Monitor Command Prompt */
然后定位到157行附近,注释掉下面两个类型的Nor Flash设置,因为不是我们所使用的型号,然后加入新的定义,如下所示:
/*-----------------------------------------------------------------------
* FLASH and environment organization
*/
//注释掉下面两个类型的Nor Flash设置,因为不是我们所使用的型号
//#define CONFIG_AMD_LV400 1 /* uncomment this if you have a LV400 flash */
//#if0
//#define CONFIG_AMD_LV800 1 /* uncomment this if you have a LV800 flash */
//#endif
#define CONFIG_SST_VF1601 1 //添加mini2440开发板Nor Flash设置
... ...
#ifdef CONFIG_AMD_LV400
#define PHYS_FLASH_SIZE 0x00080000 /* 512KB */
#define CONFIG_SYS_MAX_FLASH_SECT (11) /* max number of sectors on one chip */
#define CONFIG_ENV_ADDR (CONFIG_SYS_FLASH_BASE + 0x070000) /* addr of environment */
#endif
#ifdef CONFIG_SST_VF1601
# 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
【2】然后添加对mini2440开发板上2M的Nor Flash(型号为SST39VF1601)的支持。在u-boot中对Nor Flash的操作分别有初始化、擦除和写入,所以我们主要修改与硬件密切相关的三个函数flash_init、flash_erase、 write_hword,修改代码如下:
(1)修改定义部分如下:
#gedit board/gy/mini2440/flash.c
定位到31行附近,修改如下:
//#define MAIN_SECT_SIZE 0x10000
# define MAIN_SECT_SIZE 0x1000 //定义为4k,刚好是一个扇区的大小
Nor Flash硬件连接
由原理图可知,一般NorFlash放在Bank0。所以CONFIG_SYS_BASE=0,但是开启mmu后baseaddr=地址0映射到的新地址。0x555<<1的原因是LADDR1与A0连接。也就是0x555表示片内第0x555个word(16bit)。
#define CMD_UNLOCK_BYPASS 0x00000020
#if defined(CONFIG_SST_VF1601)
#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
#define BIT_ERASE_DONE 0x00000080
(2)在flash_init 函数中修改或添加后代码如下:
ulong flash_init (void)
{
int i, j;
ulong size = 0;
for (i = 0; i < CONFIG_SYS_MAX_FLASH_BANKS; i++) {
ulong flashbase = 0;
... ...
#elif defined(CONFIG_AMD_LV800)
(AMD_MANUFACT & FLASH_VENDMASK) |
(AMD_ID_LV800B & FLASH_TYPEMASK);
#elif defined(CONFIG_SST_VF1601)
(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_VF1601
if (j <= 3) {
/* 1st one is 16 KB */
... ...
/* 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
}
size += flash_info[i].size;
}
... ...
return size;
}
(3)在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 SST39VF1610 (16Mbit)\n");
break;
default:
printf ("Unknown Chip Type\n");
goto Done;
break;
}
... ...
Done:;
}
(4)在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;
.... ....
if ((s_first < 0) || (s_first > s_last)) {
return ERR_INVAL;
}
if ((s_first < 0) || (s_first > s_last)) {
return ERR_INVAL;
}
#ifdef CONFIG_SST_VF1601
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;
... ...
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 */
#if 0
chip = 0;
do {
... ...
printf ("ok.\n");
} else { /* it was protected */
printf ("protected!\n");
}
}
#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");
}
}
(5)在write_hword函数中修改或添加后代码如下:
tatic 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;
... ...
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;
/* arm simple, non interrupt dependent timer */
reset_timer_masked ();
/* wait until flash is ready */
#if 0
chip = 0;
do {
result = *addr;
... ...
} while (!chip);
*addr = CMD_READ_ARRAY;
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)
enable_interrupts ();
if (cflag)
icache_enable ();
return rc;
}
修改完后重新编译u-boot,下载到RAM中运行结果如下:
##### FriendlyARM BIOS 2.0 for 2440 #####
[x] format NAND FLASH for Linux
[v] Download vivi
[k] Download linux kernel
[y] Download root_yaffs image
[a] Absolute User Application
[n] Download Nboot for WinCE
[l] Download WinCE boot-logo
[w] Download WinCE NK.bin
[d] Download & Run
[z] Download zImage into RAM
[g] Boot linux from RAM
[f] Format the nand flash
[b] Boot the system
[s] Set the boot parameters
[u] Backup NAND Flash to HOST through USB(upload)
[r] Restore NAND Flash from HOST through USB
[q] Goto shell of vivi
[i] Version: 0945-2K
Enter your selection: d
Clear the free memory
USB host is connected. Waiting a download.
Now, Downloading [ADDRESS:31000000h,TOTAL:99946]
RECEIVED FILE SIZE: 99946 (97KB/S, 1S)
ownloaded file at 0x30000000, size = 99936 bytes
U-Boot 2009.08 (Jul 27 2011 - 07:39:53)
modified by gy (robinfit01@163.com)
Love Linux and pore forever!!
DRAM: 64 MB
Flash: 2 MB
*** Warning - bad CRC, using default environment
In: serial
Out: serial
Err: serial
[mini2440] # saveenv
Saving Environment to Flash...
Un-Protected 16 sectors
Erasing Flash...Erasing sector 64 ... ok.
Erasing sector 65 ... ok.
Erasing sector 66 ... ok.
Erasing sector 67 ... ok.
Erasing sector 68 ... ok.
Erasing sector 69 ... ok.
Erasing sector 70 ... ok.
Erasing sector 71 ... ok.
Erasing sector 72 ... ok.
Erasing sector 73 ... ok.
Erasing sector 74 ... ok.
Erasing sector 75 ... ok.
Erasing sector 76 ... ok.
Erasing sector 77 ... ok.
Erasing sector 78 ... ok.
Erasing sector 79 ... ok.
Erased 16 sectors
Writing to Flash... done
Protected 16 sectors
[mini2440] #
重新下载运行后,无“*** Warning - bad CRC, using default environment”
##### FriendlyARM BIOS 2.0 for 2440 #####
[x] format NAND FLASH for Linux
[v] Download vivi
[k] Download linux kernel
[y] Download root_yaffs image
[a] Absolute User Application
[n] Download Nboot for WinCE
[l] Download WinCE boot-logo
[w] Download WinCE NK.bin
[d] Download & Run
[z] Download zImage into RAM
[g] Boot linux from RAM
[f] Format the nand flash
[b] Boot the system
[s] Set the boot parameters
[u] Backup NAND Flash to HOST through USB(upload)
[r] Restore NAND Flash from HOST through USB
[q] Goto shell of vivi
[i] Version: 0945-2K
Enter your selection: d
Clear the free memory
USB host is connected. Waiting a download.
Now, Downloading [ADDRESS:31000000h,TOTAL:99966]
RECEIVED FILE SIZE: 99966 (97KB/S, 1S)
Downloaded file at 0x30000000, size = 99956 byte
U-Boot 2009.08 (Jul 27 2011 - 07:50:36)
modified by gy (robinfit01@163.com)
Love Linux and pore forever!!
DRAM: 64 MB
Flash: 2 MB
In: serial
Out: serial
Err: serial
[mini2440] #
接下来为u-boot-2009.08-2增加nand flash支持,未完待续。