Chinaunix首页 | 论坛 | 博客
  • 博客访问: 61889
  • 博文数量: 32
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 167
  • 用 户 组: 普通用户
  • 注册时间: 2011-08-09 11:39
文章分类
文章存档

2013年(1)

2012年(10)

2011年(21)

我的朋友

分类:

2011-08-09 11:41:09


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 < (nand->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<(datapages);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;

 }

阅读(428) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~