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

来源:互联网 发布:软件下载大全360 编辑:程序博客网 时间:2024/06/10 06:27

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 pageblock = 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);    #endifuboot = (void *)CONFIG_SYS_PHY_UBOOT_BASE;(*uboot)();}
重新启动后,bad CRC的提示没有了。

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


阅读(3) | 评论(0) | 转发(0) |
0

上一篇:Linux3.6.7在OK6410平台的移植(十二)TS

下一篇:Qtopia 2.2.0在OK6410平台的移植(一)Tslib

相关热门文章
  • 欢迎ssw218在ChinaUnix博客安...
  • 欢迎dadamouse在ChinaUnix博客...
  • 欢迎zjkida在ChinaUnix博客安...
  • 欢迎我是月下在ChinaUnix博客...
  • 欢迎wenzishaniu在ChinaUnix博...
  • linux 常见服务端口
  • 【ROOTFS搭建】busybox的httpd...
  • 什么是shell
  • linux socket的bug??
  • linux的线程是否受到了保护?...
  • 虚拟机中ubuntu无线连接问题...
  • IBM DS3400 盘阵怎么查看是单...
  • 启动auditd时,报错如下,怎么...
  • CGSL系统中root密码正确,但无...
  • 在CGSL系统中,如何为不同的用...
给主人留下些什么吧!~~
评论热议
0 0