费话小说,这个教程目的也很明确:让我们的uboot识别出Nor Flash(mirco 2440上的Nor Flash 是SST VF1601 2MB)并能对Nor Flash进行写操作!(未识别出Nor Flash uboot 并不能对Nor Flash进行写操作).当然我们这是在uboot能在mirco 2440跑起来的基础(跑不起来的可参考http://blog.163.com/ds_liang/blog/static/1619822122010511114351608/ )上做进行的.
1)很不幸uboot-1.1.6不支持SST V1601芯片,我们必须自己写相关的函数(幸好board/dave开发板中有相关代码我们复制过来做一点修改就行了)
$ cp board/dave/common/flash.c board/ds_liang2440/flash.c
$ vi board/dave/B2/flash.c
把 board/dave/B2/flash.c 中的unsigned long flash_init (void)函数拷贝到board/ds_liang2440/flash.c文件的最后,把条件编译去掉
dest2[i] = data2[i];
/* re-enable interrupts if necessary */
if (flag)
enable_interrupts();
/* data polling for D7 */
start = get_timer (0);
while ((dest2[i] & (CFG_FLASH_WORD_SIZE)0x00800080) !=
(data2[i] & (CFG_FLASH_WORD_SIZE)0x00800080)) {
if (get_timer(start) > CFG_FLASH_WRITE_TOUT) {
return (1);
}
}
}
return (0);
}
/*-----------------------------------------------------------------------
*/
unsigned long flash_init (void)
{
// #ifdef __DEBUG_START_FROM_SRAM__
// return CFG_DUMMY_FLASH_SIZE;
//#else
unsigned long size_b0;
int i;
/* Init: no FLASHes known */
for (i=0; i<CFG_MAX_FLASH_BANKS; ++i) {
flash_info[i].flash_id = FLASH_UNKNOWN;
}
/* Static FLASH Bank configuration here - FIXME XXX */
size_b0 = flash_get_size((vu_long *)CFG_FLASH_BASE, &flash_info[0]);
if (flash_info[0].flash_id == FLASH_UNKNOWN) {
printf ("## Unknown FLASH on Bank 0 - Size = 0x%08lx = %ld MB\n",
size_b0, size_b0<<20);
}
/* Setup offsets */
flash_get_offsets (0, &flash_info[0]);
/* Monitor protection ON by default */
(void)flash_protect(FLAG_PROTECT_SET,
-CFG_MONITOR_LEN,
0xffffffff,
&flash_info[0]);
flash_info[0].size = size_b0;
return (size_b0);
// #endif
}
2)因为本来uboot默认使用amd_lv400,我们把它去了加上SST VF1601的配置
$ vi include/configs/ds_liang2440.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
为:
#define CONFIG_SST_VF160 1
#ifdef CONFIG_SST_VF160
#define PHYS_FLAHS_SIZE 0x00200000
#define CFG_MAX_FLASH_SECT (32)
#define CFG_ENV_ADDR (CFG_FLASH_BASE + 0x030000)
#define FLASH_BANK_SIZE 0x01000000
#define CFG_FLASH_ADDR0 0x5555
#define CFG_FLASH_ADDR1 0x2AAA
#define CFG_FLASH_WORD_SIZE unsigned short
#define CFG_FLASH_READ0 0x0000
#define CFG_FLASH_READ1 0x0001
#define CFG_FLASH_READ2 0x0002
#define CFG_MONITOR_LEN (256*1024)
#define CFG_MONITOR_BASE TEXT_BASE
#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
3)修改flash.c中的函数
$ vi board/ds_liang2440/flash.c
在flash_erase函数中
令:
if ((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_SST) {
addr[CFG_FLASH_ADDR0] = (CFG_FLASH_WORD_SIZE)0x00AA00AA;
addr[CFG_FLASH_ADDR1] = (CFG_FLASH_WORD_SIZE)0x00550055;
addr[CFG_FLASH_ADDR0] = (CFG_FLASH_WORD_SIZE)0x00800080;
addr[CFG_FLASH_ADDR0] = (CFG_FLASH_WORD_SIZE)0x00AA00AA;
addr[CFG_FLASH_ADDR1] = (CFG_FLASH_WORD_SIZE)0x00550055;
addr2[0] = (CFG_FLASH_WORD_SIZE)0x00500050; /* block erase */
为:
if ((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_SST) {
addr[CFG_FLASH_ADDR0] = (CFG_FLASH_WORD_SIZE)0x00AA;
addr[CFG_FLASH_ADDR1] = (CFG_FLASH_WORD_SIZE)0x0055;
addr[CFG_FLASH_ADDR0] = (CFG_FLASH_WORD_SIZE)0x0080;
addr[CFG_FLASH_ADDR0] = (CFG_FLASH_WORD_SIZE)0x00AA;
addr[CFG_FLASH_ADDR1] = (CFG_FLASH_WORD_SIZE)0x0055;
addr2[0] = (CFG_FLASH_WORD_SIZE)0x0050; /* block erase */
令:
if (sect == s_first) {
addr[CFG_FLASH_ADDR0] = (CFG_FLASH_WORD_SIZE)0x00AA00AA;
addr[CFG_FLASH_ADDR1] = (CFG_FLASH_WORD_SIZE)0x00550055;
addr[CFG_FLASH_ADDR0] = (CFG_FLASH_WORD_SIZE)0x00800080;
addr[CFG_FLASH_ADDR0] = (CFG_FLASH_WORD_SIZE)0x00AA00AA;
addr[CFG_FLASH_ADDR1] = (CFG_FLASH_WORD_SIZE)0x00550055;
}
addr2[0] = (CFG_FLASH_WORD_SIZE)0x00300030; /* sector erase */
为:
if (sect == s_first) {
addr[CFG_FLASH_ADDR0] = (CFG_FLASH_WORD_SIZE)0x00AA;
addr[CFG_FLASH_ADDR1] = (CFG_FLASH_WORD_SIZE)0x0055;
addr[CFG_FLASH_ADDR0] = (CFG_FLASH_WORD_SIZE)0x0080;
addr[CFG_FLASH_ADDR0] = (CFG_FLASH_WORD_SIZE)0x00AA;
addr[CFG_FLASH_ADDR1] = (CFG_FLASH_WORD_SIZE)0x0055;
}
addr2[0] = (CFG_FLASH_WORD_SIZE)0x0030; /* sector erase */
令:
addr = (CFG_FLASH_WORD_SIZE *)(info->start[l_sect]);
while ((addr[0] & (CFG_FLASH_WORD_SIZE)0x00800080) != (CFG_FLASH_WORD_SIZE)0x00800080)
为:
addr = (CFG_FLASH_WORD_SIZE *)(info->start[l_sect]);
while ((addr[0] & (CFG_FLASH_WORD_SIZE)0x0080) != (CFG_FLASH_WORD_SIZE)0x0080)
令:
addr[0] = (CFG_FLASH_WORD_SIZE)0x00F000F0; /* reset bank */
为:
addr[0] = (CFG_FLASH_WORD_SIZE)0x00F0; /* reset bank */
在flash_get_size函数中:
令:
addr2[CFG_FLASH_ADDR0] = (CFG_FLASH_WORD_SIZE)0x00AA00AA;
addr2[CFG_FLASH_ADDR1] = (CFG_FLASH_WORD_SIZE)0x00550055;
addr2[CFG_FLASH_ADDR0] = (CFG_FLASH_WORD_SIZE)0x00900090;
为:
addr2[CFG_FLASH_ADDR0] = (CFG_FLASH_WORD_SIZE)0x00AA;
addr2[CFG_FLASH_ADDR1] = (CFG_FLASH_WORD_SIZE)0x0055;
addr2[CFG_FLASH_ADDR0] = (CFG_FLASH_WORD_SIZE)0x0090;
在第二个switch中加入:
case (CFG_FLASH_WORD_SIZE)SST_ID_xF1601:
info->flash_id += FLASH_SST1601;
info->sector_count = 32;
info->size = 0x00200000;
break;
在write_buff函数中:
令全部#ifdef CONFIG_B2改写为#ifdef CONFIG_SMDK2410
在flash_print_info函数中:
switch个添加
case FLASH_SST1601: printf ("SST39LF/VF1601(16 Mbit, bottom boot sect)\n");
break;
4)在include/flash.h中添加
#define FLASH_SST1601 0x0048
(加在SST那组)
Nor Flash驱动就到此结束了
$ make clean
$ make ds_liang2440_config
$ make all
当前目录生成的u-boot.bin文件支持nor flash 的写操作
串口输出中多了
如:
pro off all
//解除保护,不解除不能进行擦除操作
erase all