UBOOT-2012-10在OK6410平台的移植(十三)完善功能

1.完善saveenv功能(ENV保存于NAND Flash)

在执行saveenv命令时,出现“MTD Erase failure: -22”的问题

原因是erase是nand的整个block,而设置的CONFIG_ENV_SIZE小于block。于是设置:

#define CONFIG_ENV_OFFSET   0x0080000

#define CONFIG_ENV_SIZE        0x80000

该问题解决了,但启动后一直出现“bad CRC,using default environment”

通过查找发现,uboot没有找到复制到CONFIG_NAND_ENV_DST处的环境变量。

我的uboot image放在NAND的第一个BLOCK(512K),而ENV放在第二块BLOCK。

系统启动第一阶段时env_init会查找指到CONFIG_NAND_ENV_DST处的环境变量,如果没有找到则gd->env_valid=0

系统启动第二阶段的env_relocat根据gd->env_valid=0而env_set_defaut("!bad CRC");

再来看nand启动的nand_boot函数,该函数里面只有

nandll_read_blocks(CONFIG_SYS_PHY_UBOOT_BASE,CONFIG_SYS_UBOOT_SIZE, CONFIG_SYS_NAND_PAGE_SIZE);

进一步发现nand_boot启动过程只复制了第一个block到内存(uboot image),所以还需要 把第二个block也复制到内存CONFIG_NAND_ENV_DST处。

修改nand_boot.c中几个函数,内容如下:

#include <common.h>
#include <nand.h>
#include <asm/io.h>
#include <asm/arch/s3c6410.h>

#define NAND_DISABLE_CE()	(NFCONT_REG |= (1 << 1))
#define NAND_ENABLE_CE()	(NFCONT_REG &= ~(1 << 1))
#define NF_TRANSRnB()		do { while(!(NFSTAT_REG & (1 << 0))); } while(0)

static void nandll_read_page (uchar *buf, ulong addr, uint nand_page_size)
{
    int i;
	/*
    int page_size = 512;

    if (large_block==1)
        page_size = 2048;
    if (large_block==2)
        page_size = 4096;
    if(large_block==3)
        page_size = 8192;
    */
    NAND_ENABLE_CE();

    NFCMD_REG = NAND_CMD_READ0;

    /* Write Address */
    NFADDR_REG = 0;

    if (nand_page_size>=2048)
        NFADDR_REG = 0;

    NFADDR_REG = (addr) & 0xff;
    NFADDR_REG = (addr >> 8) & 0xff;
    NFADDR_REG = (addr >> 16) & 0xff;

    if (nand_page_size>=2048)
        NFCMD_REG = NAND_CMD_READSTART;

    NF_TRANSRnB();

    /* for compatibility(2460). u32 cannot be used. by scsuh */
    for(i=0; i < nand_page_size; i++) {
        *buf++ = NFDATA8_REG;
    }

    NAND_DISABLE_CE();
    //return 0;
}

/*
 * Read data from NAND.
 */
static void nandll_read_blocks (ulong dst_addr, ulong offs,ulong read_size, uint nand_page_size)
{
    unsigned char *buf = (unsigned char *)dst_addr;
    unsigned i;
    unsigned page_shift = 9;
	unsigned int block, lastblock;
	unsigned int page;

    if(nand_page_size == 4096) 
    {
        page_shift = 12;//4k page

		block = offs / CONFIG_SYS_NAND_BLOCK_SIZE;
		lastblock = (offs + read_size - 1) / CONFIG_SYS_NAND_BLOCK_SIZE;
		page = (offs % CONFIG_SYS_NAND_BLOCK_SIZE) / CONFIG_SYS_NAND_PAGE_SIZE;
		if(block==0)//we always use first block for uboot image
 		{
           /* Read step 1 */
		   for (i = 2; i < 4; i++, buf+=(1<<(page_shift-1)))
            nandll_read_page(buf, i, nand_page_size);
		   /* Read step 2 */
           for (i = 4; i < (read_size>>page_shift); i++, buf+=(1<<page_shift)) 
            nandll_read_page(buf, i, nand_page_size);
        }
		else
		{
     	   while (block <= lastblock) 
		   {
		     while (page < CONFIG_SYS_NAND_PAGE_COUNT) 
			 	{
			 	 i=page+block*CONFIG_SYS_NAND_PAGE_COUNT;
			 	 nandll_read_page(buf, i, nand_page_size);
  				 buf += CONFIG_SYS_NAND_PAGE_SIZE;
				 page++;
			     }
			page=0;
            block++;
		   }
		}
    }
	else if(nand_page_size == 8192)  //K9GAG08U0E
    {
        page_shift = 13;//8k page
		/* Read pages */
        for (i = 0; i < 4; i++, buf+=(1<<(page_shift-2))) {
            nandll_read_page(buf, i, nand_page_size);
        }


        /* Read pages */
        for (i = 4; i < (read_size>>page_shift); i++, buf+=(1<<page_shift)) {
            nandll_read_page(buf, i, nand_page_size);
        }
    }
    else //if (nand_page_size==2048)
    {
        page_shift = 11; //2k page
        for (i = 0; i < (read_size>>page_shift); i++, buf+=(1<<page_shift)) {
            nandll_read_page(buf, i, nand_page_size);
        }
    }
    //return 0;
}

void nand_boot(void)
{
    int large_block = 0;
    int i;
    vu_char id;
    __attribute__((noreturn)) void (*uboot)(void);

    NAND_ENABLE_CE();
    NFCMD_REG=NAND_CMD_RESET;
    NF_TRANSRnB();


    NFCMD_REG = NAND_CMD_READID;
    NFADDR_REG =  0x00;

    NF_TRANSRnB();
    
    /* wait for a while */
    for (i=0; i<200; i++);

    int factory = NFDATA8_REG;
    id = NFDATA8_REG;

    int cellinfo=NFDATA8_REG;
    int tmp= NFDATA8_REG;

    //int childType=tmp & 0x03; //Page size
    int childType=cellinfo; //Page size

    /* read NAND Block
     * 128KB ->240KB because of U-Boot size increase. by scsuh
     * So, read 0x3c000 bytes not 0x20000(128KB).
     */
    //led test
    writel(0x0023,0x7f008824);
    nandll_read_blocks(CONFIG_SYS_PHY_UBOOT_BASE,
                       CONFIG_SYS_NAND_U_BOOT_OFFS,
                       CONFIG_SYS_UBOOT_SIZE, 
                       CONFIG_SYS_NAND_PAGE_SIZE);
	#ifdef CONFIG_NAND_ENV_DST
	//led test
    writel(0x002a,0x7f008824);
	nandll_read_blocks(CONFIG_NAND_ENV_DST,
	                   CONFIG_ENV_OFFSET,
	                   CONFIG_ENV_SIZE,
	                   CONFIG_SYS_NAND_PAGE_SIZE);
    #endif
	uboot = (void *)CONFIG_SYS_PHY_UBOOT_BASE;
	(*uboot)();
}
重新启动后,bad CRC的提示没有了。

#md 57e80000可以查看到环境变量都已经复制到内存,从而解决了该问题。


<script type=text/javascript charset=utf-8 src="http://static.bshare.cn/b/buttonLite.js#style=-1&uuid=&pophcol=3&lang=zh"></script> <script type=text/javascript charset=utf-8 src="http://static.bshare.cn/b/bshareC0.js"></script>
阅读(3) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~
评论热议
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值