免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 798 | 回复: 0
打印 上一主题 下一主题

移植U-Boot.2008.10到友善之臂mini2440(四)【转】 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2009-12-05 00:24 |只看该作者 |倒序浏览

1.2.5 修改u-boot支持烧写yaffs映像文件


    (1) /common/cmd_nand.cdo_nand函数中,加入代码,实现对nand write.yaffs命令的支持。在对jffs2操作的下面加入,如下:
在else if (s != NULL && !strcmp(s, ".oob"))前加入
else if(s != NULL && !strcmp(s, ".yaffs"))
               {
                       if(read)
                         {
               printf("nand read.yaffs is not provide!"); /*不支持读取yaffs*/
                         }
                       else
                         {
                               nand->writeoob = 1;
                               ret = nand_write_skip_bad(nand,off,&size,(u_char *)addr); //写入yaffs
                               nand->writeoob = 0;
                         }
                       
               }

    在 nand 的命令中加入对 nand write.yaffs 的描述,加入如下3行:
           "    to/from memory address 'addr', skipping bad blocks.\n"
           "nand write.yaffs - addr off|partition size\n"
           "    write 'size' bytes starting at offset 'off'\n"
           "    to/from yaffs image in memory address 'addr', skipping bad blocks.\n"
           "nand erase [clean] [off size] - erase 'size' bytes from\n"

    (2) include/linux/mtd/mtd.h mtd_info 结构体定义中加入两个变量如下:

struct mtd_info {
        u_char writeoob;
        u_char skipfirstblock;
        u_char type;
        u_int32_t flags;
        u_int32_t size; /* Total size of the MTD */

    (3) drivers/mtd/nand/nand_util.cnand_write_skip_bad函数中加两段程序,一段是为了计算正常数据的长度,一段是为了在写入一段数据后,数据指针能正常跳到下一段数据,修改如下:

        size_t left_to_write = *length;
        size_t len_incl_bad;
        u_char *p_buffer = buffer;
        
        /*这段程序主要是从yaffs映像中提取要写入的正常数据的长度,即不包括oob数据的数据长度*/
        if(nand->writeoob==1)
        {
               size_t oobsize = nand->oobsize;  //定义oobsize的大小
               size_t datasize = nand->writesize;

               int datapages = 0;

            //长度不是528整数倍,认为数据出错。
            if (((*length)%(nand->oobsize+nand->writesize)) != 0) {
               printf ("Attempt to write error length data!\n");
               return -EINVAL;
        }

               datapages = *length/(datasize+oobsize);

               *length = datapages*datasize;
               left_to_write = *length;
               nand->skipfirstblock=1;
        }
/* Reject writes, which are not page aligned */

以下的程序程序本意是没有坏块时,不进行坏块检查直接写,但没有达到目的,所以注释掉:
        /*if (len_incl_bad == *length) {
               printf("first write\n");
               rval = nand_write (nand, offset, length, buffer);
               if (rval != 0) {
                       printf ("NAND write to offset %x failed %d\n",
                               offset, rval);
                       return rval;
               }
        }*/
    在while(left_to_write>0)循环中添加:
                       offset += nand->erasesize - block_offset;
                       continue;
               }
               if(nand->skipfirstblock==1) //如需跳过第一个好块,则跳过第一个好块。
               {
                       nand->skipfirstblock=0;
                       printf ("Skip the first good block 0x%08x\n",
                               offset & ~(nand->erasesize - 1));
                       offset += nand->erasesize - block_offset;
                       continue;
               }
               if (left_to_write erasesize - block_offset))
                       write_size = left_to_write;

修改p_buffer处的代码如下:
               left_to_write -= write_size;
               printf("%ld%% is complete.",100-(left_to_write/(*length/100)));      
               offset        += write_size;
               //p_buffer      += write_size;
               if(nand->writeoob==1)
               {
             p_buffer += write_size+(write_size/nand->writesize*nand->oobsize);
               }
               else
               {
                       p_buffer += write_size;
               }
(4)/drivers/mtd/nand/nand_base.cnand_write函数中,加入一段把正常数据与oob数据分离的代码,再加入页写时的模式设置为MTD_OOB_RAW,在页写时,不进行ECC的校验,ECC的校验在yaffsoob数据中已自带了,不能重写。此模式下,写入正常数据后,会把oob的数据写入nandoob区。修改后如下:
static int nand_write(struct mtd_info *mtd, loff_t to, size_t len,
     size_t *retlen, const uint8_t *buf)
{
        struct nand_chip *chip = mtd->priv;
        int ret;
        //printf("0 len is %d ",len);
        //此段数据是将要写入的数据中的正常数据移到buf中的前段,把oob数据移到后段。
        int oldopsmode = 0;
        if(mtd->writeoob==1)
        {

               size_t oobsize = mtd->oobsize;  //定义oobsize的大小
               size_t datasize = mtd->writesize;
               int i = 0;
               uint8_t oobtemp[16];
               int datapages = 0;
               datapages = len/(datasize); //传进来的len是没有包括oob的数据长度
               for(i=0;i
               {
                       memcpy(oobtemp,buf+datasize*(i+1),oobsize);
               memmove(buf+datasize*(i+1),buf+datasize*(i+1)+oobsize,(datapages-(i+1))*(datasize)+(datapages-1)*oobsize);
                       memcpy(buf+(datapages)*(datasize+oobsize)-oobsize,oobtemp,oobsize);
               }

        }

        //printf("1 len is %d ",len);
        /* Do not allow reads past end of device */
        if ((to + len) > mtd->size)
               return -EINVAL;
        if (!len)
               //return 0;
               {printf("Write data length is %d ",len);return 0;}

        nand_get_device(chip, mtd, FL_WRITING);

        chip->ops.len = len;
        chip->ops.datbuf = (uint8_t *)buf;
        //chip->ops.oobbuf = NULL;

        if(mtd->writeoob!=1)
        {
               chip->ops.oobbuf = NULL;
        }
        else
        {
               chip->ops.oobbuf = (uint8_t *)(buf+len); //将oob缓存的指针指向buf的后段,即oob数据区的起始地址。
               chip->ops.ooblen = mtd->oobsize;
               oldopsmode = chip->ops.mode;
               chip->ops.mode = MTD_OOB_RAW;            //将写入模式改为直接书写oob区,即写入数据时,不进行ECC校验的计算和写入。(yaffs映像的oob数据中,本身就带有ECC校验)
        }

        ret = nand_do_write_ops(mtd, to, &chip->ops);

        *retlen = chip->ops.retlen;

        nand_release_device(mtd);
        chip->ops.mode = oldopsmode; //恢复原模式
        return ret;
}
......
        /* Do not replace user supplied command function ! */
        if (mtd->writesize > 512 && chip->cmdfunc == nand_command)
               chip->cmdfunc = nand_command_lp;

        //MTDDEBUG (MTD_DEBUG_LEVEL0, "NAND device: Manufacturer ID:"
          //        " 0x%02x, Chip ID: 0x%02x (%s %s)\n", *maf_id, dev_id,
            //      nand_manuf_ids[maf_idx].name, type->name);
        printf("NAND device: Manufacturer ID:"
                 " 0x%02x, Chip ID: 0x%02x (%s %s)\n", *maf_id, dev_id,
                  nand_manuf_ids[maf_idx].name, type->name);
        return type;
}

1.2.6 修改DM9000驱动


    修改文件 u-boot-2008.10/drivers/net/dm9000x.c
      /* Enable TX/RX interrupt mask */
        DM9000_iow(DM9000_IMR, IMR_PAR);

/* 注释掉与MII接口相关的语句----*/
#if 0
        i = 0;
        while (!(phy_read(1) & 0x20)) {       /* autonegation complete bit */
               udelay(1000);
……
               break;
        }
        printf("mode\n");
#endif
        return 0;
}


本文来自ChinaUnix博客,如果查看原文请点:http://blog.chinaunix.net/u3/107284/showart_2111617.html
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP