移植u-boot-2009.08到mini2440(三) NorFlash设置

该博客主要记录和总结我在工作中遇到的问题和积累的经验。如有错误之处,谢请指正。

共享资源,欢迎转载:http://blog.csdn.net/fzu_dianzi

一、环境

目标板:mini2440

u-boot版本:u-boot-2009.08

交叉编译器:arm-linux-gcc-4.3.2

操作系统:Linux(Ubuntu-11.10)

二、目的

从上一节的成果我们观察到Flash的信息不正确,mini2440板子上为2M的Nor Flash(型号为SST39VF1601),还有就是提示*** Warning - bad CRC, using default environment的警告。

本节,笔者主要完成这2项的修改工作。


三、修改Flash配置

1、 修改命令行前的名字

这个一般是在.h文件里面定义,首先笔者查找了include/configs/mini2440.h。在115行找到如下语句

#define    CONFIG_SYS_PROMPT            "SMDK2410 # "    /* Monitor Command Prompt       */

我们将其修改为

#define    CONFIG_SYS_PROMPT            "mini2440/care # " /* Monitor Command Prompt       */

2、 修改flash部分代码

使用source insight 阅读源代码,我们可以找到Flash:512KB的打印信息所对应的函数位置。

lib_arm/board.c [214行] void display_flash_config (ulongsize)函数

找到调用该函数的地方,在本文件329行

#ifndef CONFIG_SYS_NO_FLASH
	/* configure available FLASH banks */
	display_flash_config (flash_init ());
#endif /* CONFIG_SYS_NO_FLASH *

flash_init()函数定义在board/samsung/mini2440/flash.c

		flash_info[i].flash_id =
#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);
#else
#error "Unknown flash configured"
#endif

CONFIG_AMD_LV400并不是mini2440的NorFlash id。

接下来,我们修改mini2440.h关于NorFlash 的一些定义
include/configs/mini2440.h

#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

在176行后添加

#define CONFIG_SST_39VF1601        1        
#define PHYS_FLASH_SIZE            0x200000 //2m NorFlash 
#define CONFIG_SYS_MAX_FLASH_SECT  (512)		//扇区大小,一扇区4k    
#define CONFIG_ENV_ADDR            (CONFIG_SYS_FLASH_BASE + 0x040000)
修改board/samsung/mini2440/flash.c norflash的参数宏定义

#define MAIN_SECT_SIZE  0x1000	/* 4 KB */
#define MEM_FLASH_ADDR1		(*(volatile u16 *)(CONFIG_SYS_FLASH_BASE + (0x00005555 << 1)))
#define MEM_FLASH_ADDR2		(*(volatile u16 *)(CONFIG_SYS_FLASH_BASE + (0x00002AAA << 1)))
修改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)   //添加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++) 
{
flash_info[i].start[j] = flashbase + j * MAIN_SECT_SIZE;
}

 修改flash_print_info函数

switch (info->flash_id & FLASH_VENDMASK) {
	case (AMD_MANUFACT & FLASH_VENDMASK):
		printf ("AMD: ");
		break;
	case (SST_MANUFACT & FLASH_VENDMASK):    //添加SST39VF1601
    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):   //添加SST39VF1601的
    printf ("1x SST39VF1610 (16Mbit)\n");
    break;
	default:
		printf ("Unknown Chip Type\n");
		goto Done;
		break;
	}

修改flash_erase函数

if ((info->flash_id & FLASH_VENDMASK) !=
 (AMD_MANUFACT & FLASH_VENDMASK)) {
return ERR_UNKNOWN_FLASH_VENDOR;
}

修改为

if ((info->flash_id & FLASH_VENDMASK) != (SST_MANUFACT & FLASH_VENDMASK)) {
    return ERR_UNKNOWN_FLASH_VENDOR;
}

将以下代码删掉

/* wait until flash is ready */

                     chip= 0;

开始 至

if (chip == TMO) {

rc = ERR_TIMOUT;

goto outahere;

}

然后添加

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_PROGRAM;
	//*addr = CMD_PROGRAM;
	*addr = data;

将从

       /*wait until flash is ready */

       chip= 0;

开始至

       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; 
    }
}

3、 成果

将编译生成的u-boot.bin烧写到NorFlash。

证明该阶段关于Flash的修改成功,并且命令行前的名字也成功修改了。

四、*** Warning- bad CRC, using default environment

将这段语句作为关键词,使用sourceinsight进行搜索,发现这个警告的出现是和环境变量有关。

u-boot stage2的入口函数在lib_arm/board.c 的start_armboot函数。该函数主要进行一系列的初始化。我们找到环境变量初始化的函数。

       /*initialize environment */

       env_relocate();

通过分析得知,如果是readenv读取环境变量失败,那么就会使用默认的环境变量。

如果即使数据读的对了,但是crc32校验失败,那么也是使用默认环境变量。

我们执行一下u-boot的:saveenv命令,将环境变量设置到Nor Flash中。

这里附上一篇介绍该解决方法的文章,里面详细阐述了分析过程。

【已解决】*** Warning - bad CRC or NAND,using default environment
















你可能感兴趣的:(bootloader)