Chinaunix首页 | 论坛 | 博客
  • 博客访问: 32341
  • 博文数量: 12
  • 博客积分: 445
  • 博客等级: 下士
  • 技术积分: 150
  • 用 户 组: 普通用户
  • 注册时间: 2012-10-06 16:49
文章分类

全部博文(12)

文章存档

2012年(12)

我的朋友

分类: 嵌入式

2012-10-21 23:00:38

11、u-boot支持烧写yaffs2文件系统

   u-boot默认不支持yaffs2文件系统镜像的烧写,现在加入烧写yaffs2文件系统的命令,并修改NandFlash程序中写操作的处理方式,移植的步骤如下:
(1)在smdk2440.h中加入支持yaffs2的配置,修改的代码如下:
  1. #define ENABLE_CMD_LOADB_X    1 
  2. #define ENABLE_CMD_NAND_YAFFS    1           
  3. #define ENABLE_CMD_NAND_YAFFS_SKIPFB   

(2)在common/cmd_nand.c中增加烧写yaffs2的命令支持,先是修改do_nand函数,修改的代码如下:
  1. s = strchr(cmd, '.');
  2.         if (!s || !strcmp(s, ".jffs2") ||
  3.          !strcmp(s, ".e") || !strcmp(s, ".i")) {
  4.             if (read)
  5.                 ret = nand_read_skip_bad(nand, off, &size,
  6.                              (u_char *)addr);
  7.             else
  8.                 ret = nand_write_skip_bad(nand, off, &size,
  9.                              (u_char *)addr);                         
  10. #if defined(ENABLE_CMD_NAND_YAFFS)
  11.         }else if ( s != NULL &&
  12.             (!strcmp(s, ".yaffs") || !strcmp(s, ".yaffs1"))){
  13.              if(read) {
  14.                  printf("nand read.yaffs[1] is not provide temporarily!"); 
  15.              } else {
  16.                 nand->rw_oob = 1;
  17. #if defined(ENABLE_CMD_NAND_YAFFS_SKIPFB)
  18.                 nand->skipfirstblk = 1;
  19. #else
  20.                 nand->skipfirstblk = 0;
  21. #endif
  22.                 ret = nand_write_skip_bad(nand,off,&size,(u_char *)addr);
  23. #if defined(ENABLE_CMD_NAND_YAFFS_SKIPFB)
  24.                 nand->skipfirstblk = 0;
  25. #endif
  26.                 nand->rw_oob = 0;
  27.              }
  28. #endif
  29.         } else if (!strcmp(s, ".oob")) {
  30.             /* out-of-band data */
  31.             mtd_oob_ops_t ops = {
  32.                 .oobbuf = (u8 *)addr,
  33.                 .ooblen = size,
  34.                 .mode = MTD_OOB_RAW
  35.             };

    接着在U_BOOT_CMD处修改代码如下:
  1. U_BOOT_CMD(nand, CONFIG_SYS_MAXARGS, 1, do_nand,
  2.     "NAND sub-system",
  3.     "info - show available NAND devices\n"
  4.     "nand device [dev] - show or set current device\n"
  5.     "nand read - addr off|partition size\n"
  6.     "nand write - addr off|partition size\n"
  7.     " read/write 'size' bytes starting at offset 'off'\n"
  8.     " to/from memory address 'addr', skipping bad blocks.\n"
  9.     "nand erase [clean] [off size] - erase 'size' bytes from\n"
  10.     " offset 'off' (entire device if not specified)\n"
  11. #if defined(ENABLE_CMD_NAND_YAFFS)
  12.     "nand read[.yaffs[1]] is not provide temporarily!\n"
  13.     "nand write[.yaffs[1]] addr off size - write the `size' byte yaffs image starting\n"
  14.     " at offset `off' from memory address `addr' (.yaffs1 for 512+16 NAND)\n"
  15. #endif
  16.     "nand bad - show bad blocks\n"
  17.     "nand dump[.oob] off - dump page\n"
  18.     "nand scrub - really clean NAND erasing bad blocks (UNSAFE)\n"
  19.     "nand markbad off [...] - mark bad block(s) at offset (UNSAFE)\n"
  20.     "nand biterr off - make a bit error at offset (UNSAFE)"
  21. #ifdef CONFIG_CMD_NAND_LOCK_UNLOCK
  22.     "\n"
  23.     "nand lock [tight] [status]\n"
  24.     " bring nand to lock state or display locked pages\n"
  25.     "nand unlock [offset] [size] - unlock section"
  26. #endif
  27. );

(3)修改include/linux/mtd/目录下的mtd.h文件,在mtd_info结构体中增加两个变量,这两个变量要在后面修改NandFlash驱动时使用,修改的代码如下:
  1.     u_int32_t writesize;    
  2.     u_char rw_oob;
  3.     u_char skipfirstblk;
  4.     u_int32_t oobsize; /* Amount of OOB data per block (e.g. 16) */
  5.     u_int32_t oobavail; /* Available OOB bytes per block */

    接着修改结构体erase_info结构体中的uint64_t addr成员,修改的代码如下:
  1. struct erase_info {
  2.     struct mtd_info *mtd;
  3.     u_long addr;     //uint64_t addr
  4.     uint64_t len;
  5.     uint64_t fail_addr;
  6.     u_long time;
  7.     u_long retries;
  8.     u_int dev;
  9.     u_int cell;
  10.     void (*callback) (struct erase_info *self);
  11.     u_long priv;
  12.     u_char state;
  13.     struct erase_info *next;
  14. };

(4)修改drivers/mtd/nand/目录下nand_util.c文件中的nand_write_skip_bad函数,修改的代码如下:
  1. int nand_write_skip_bad(nand_info_t *nand, __kernel_ino_t offset, size_t *length,
  2.             u_char *buffer) /* zjw modify 20121021 */
  3. {
  4.     int rval;
  5.     size_t left_to_write = *length;
  6.     size_t len_incl_bad;
  7.     u_char *p_buffer = buffer;   
  8. #if defined(ENABLE_CMD_NAND_YAFFS)
  9.     
  10.     if(nand->rw_oob==1)    {
  11.         size_t oobsize = nand->oobsize; 
  12.         size_t datasize = nand->writesize;
  13.         int datapages = 0;

  14.      
  15.     //if (((*length)%(nand->oobsize+nand->writesize)) != 0) {
  16.          //printf ("Attempt to write error length data!\n");
  17.          //return -EINVAL;
  18.     //}

  19.         datapages = *length/(datasize+oobsize);
  20.         *length = datapages*datasize;
  21.         left_to_write = *length;
  22.         //nand->skipfirstblock=1;
  23.     }
  24. #endif
  25.     /* Reject writes, which are not page aligned */
  26.     if ((offset & (nand->writesize - 1)) != 0 ||
  27.      (*length & (nand->writesize - 1)) != 0) {
  28.         printf ("Attempt to write non page aligned data\n");
  29.         return -EINVAL;
  30.     }

  31.     len_incl_bad = get_len_incl_bad (nand, offset, *length);

  32.     if ((offset + len_incl_bad) > nand->size) {
  33.         printf ("Attempt to write outside the flash area\n");
  34.         return -EINVAL;
  35.     }
  36. #if !defined(ENABLE_CMD_NAND_YAFFS) 
  37.     if (len_incl_bad == *length) {
  38.         rval = nand_write (nand, offset, length, buffer);
  39.         if (rval != 0)
  40.             printf ("NAND write to offset %llx failed %d\n",
  41.                 offset, rval);

  42.         return rval;
  43.     }
  44. #endif 
  45.     while (left_to_write > 0) {
  46.         size_t block_offset = offset & (nand->erasesize - 1);
  47.         size_t write_size;

  48.         WATCHDOG_RESET ();

  49.         if (nand_block_isbad (nand, offset & ~(nand->erasesize - 1))) {
  50.             printf ("Skip bad block 0x%08lx\n",
  51.                 offset & ~(nand->erasesize - 1));
  52.             offset += nand->erasesize - block_offset;
  53.             continue;
  54.         }       
  55. #if defined(ENABLE_CMD_NAND_YAFFS)
  56.         if(nand->skipfirstblk==1)    {        
  57.             nand->skipfirstblk=0;
  58.             printf ("Skip the first good block %08lx\n",
  59.                 offset & ~(nand->erasesize - 1));
  60.             offset += nand->erasesize - block_offset;
  61.             continue;
  62.         }
  63. #endif
  64.         if (left_to_write < (nand->erasesize - block_offset))
  65.             write_size = left_to_write;
  66.         else
  67.             write_size = nand->erasesize - block_offset;
  68.         
  69.         printf("\rWriting at 0x%08lx -- ",offset); // zjw add 20121021

  70.         rval = nand_write (nand, offset, &write_size, p_buffer);
  71.         if (rval != 0) {
  72.             printf ("NAND write to offset %08lx failed %d\n",
  73.                 offset, rval);
  74.             *length -= left_to_write;
  75.             return rval;
  76.         }

  77.          left_to_write -= write_size;
  78.         printf("%d%% is complete.",100-(left_to_write/(*length/100)));
  79.          offset += write_size;

  80. #if defined(ENABLE_CMD_NAND_YAFFS)
  81.         if(nand->rw_oob==1)    {
  82.             p_buffer += write_size+(write_size/nand->writesize*nand->oobsize);
  83.         } else    {
  84.             p_buffer += write_size;
  85.         }
  86. #else
  87.          p_buffer += write_size;
  88. #endif
  89.     }
  90.     return 0;
  91. }

(5)修改drivers/mtd/nand/目录下的nand_base.c文件,先修改nand_do_write_ops函数,修改的代码如下:
  1. writelen -= bytes;
  2.         if (!writelen)
  3.             break;

  4.         column = 0;
  5. #if defined(ENABLE_CMD_NAND_YAFFS)
  6.     if(mtd->rw_oob == 1) {
  7.         oob = oob + bytes;
  8.         buf = buf + ops->ooblen; 
  9.     }
  10. #endif
  11.         buf += bytes;
  12.         realpage++;

    接着修改nand_write函数,修改的代码如下:
  1. static int nand_write(struct mtd_info *mtd, loff_t to, size_t len,
  2.              size_t *retlen, const uint8_t *buf)
  3. {
  4.     struct nand_chip *chip = mtd->priv;
  5.     int ret;  
  6. #if defined(ENABLE_CMD_NAND_YAFFS)
  7.     int oldopsmode = 0;
  8.     if(mtd->rw_oob != 1) {
  9.         chip->ops.oobbuf = NULL;
  10.     } else {
  11.         chip->ops.oobbuf = (uint8_t *)(buf + mtd->writesize);
  12.         chip->ops.ooblen = mtd->oobsize;
  13.         chip->ops.ooboffs = 0;
  14.         oldopsmode = chip->ops.mode;
  15.         chip->ops.mode = MTD_OOB_RAW;
  16.     }
  17. #else
  18.     chip->ops.oobbuf = NULL;
  19. #endif

  20. #if 0
  21. #if defined(ENABLE_CMD_NAND_YAFFS)
  22.     int oldopsmode = 0;
  23.     if(mtd->rw_oob == 1){
  24.         size_t oobsize = mtd->oobsize;
  25.         size_t datasize = mtd->writesize;
  26.         int i = 0;
  27.         uint8_t oobtemp[oobsize];
  28.         int datapages = 0;
  29.         
  30.         datapages = len/(datasize);
  31.         for(i=0;i<(datapages);i++)    {
  32.             memcpy((void *)oobtemp,
  33.                 (void *)(buf+datasize*(i+1)),
  34.                 oobsize);
  35.             memmove((void *)(buf+datasize*(i+1)),
  36.                 (void *)(buf+datasize*(i+1)+oobsize),
  37.                 (datapages-(i+1))*(datasize)+(datapages-1)*oobsize);
  38.             memcpy((void *)(buf+(datapages)*(datasize+oobsize)-oobsize),
  39.                 (void *)(oobtemp),
  40.                 oobsize);
  41.         }
  42.     }
  43. #endif
  44. #endif
  45.     /* Do not allow reads past end of device */
  46.     if ((to + len) > mtd->size)
  47.         return -EINVAL;
  48.     if (!len)
  49.         return 0;

  50.     nand_get_device(chip, mtd, FL_WRITING);

  51.     chip->ops.len = len;
  52.     chip->ops.datbuf = (uint8_t *)buf;
  53.     //chip->ops.oobbuf = NULL; // zjw del 20121021
  54. #if 0
  55. #if defined(ENABLE_CMD_NAND_YAFFS)
  56.     if(mtd->rw_oob!=1)    {
  57.      chip->ops.oobbuf = NULL;
  58.     } else    {
  59.      chip->ops.oobbuf = (uint8_t *)(buf+len); 
  60.      chip->ops.ooblen = mtd->oobsize;
  61.      oldopsmode = chip->ops.mode;
  62.      chip->ops.mode = MTD_OOB_RAW; 
  63.     }
  64. #else
  65.     chip->ops.oobbuf = NULL;
  66. #endif
  67. #endif
  68.     ret = nand_do_write_ops(mtd, to, &chip->ops);

  69.     *retlen = chip->ops.retlen;

  70.     nand_release_device(mtd);   
  71. #if defined(ENABLE_CMD_NAND_YAFFS)
  72.     chip->ops.mode = oldopsmode;
  73. #endif
  74.     return ret;
  75. }

(6)修改include/nand.h文件中关于nand_write_skip_bad函数的声明,修改的代码如下:
  1. int nand_read_skip_bad(nand_info_t *nand, loff_t offset, size_t *length, u_char *buffer);
  2. int nand_write_skip_bad(nand_info_t *nand, __kernel_ino_t offset, size_t *length, u_char *buffer);
  3. int nand_erase_opts(nand_info_t *meminfo, const nand_erase_options_t *opts);

(7)在nand_util.c中修改nand_erase_opts函数,修改后的代码如下:
  1. if (!opts->scrub && bbtest) {
  2.             int ret = meminfo->block_isbad(meminfo, erase.addr);
  3.             if (ret > 0) {
  4.                 if (!opts->quiet)
  5.                     printf("\rSkipping bad block at "
  6.                      "0x%08lx " /* zjw modify 20121021 */
  7.                      " \n",
  8.                      erase.addr);
  9.                 continue;

  10.             } else if (ret < 0) {
  11.                 printf("\n%s: MTD get bad block failed: %d\n",
  12.                  mtd_device,
  13.                  ret);
  14.                 return -1;
  15.             }
  16.         }

 if (percent != percent_complete) {
percent_complete = percent;
printf("\rErasing at 0x%08lx -- %3d%% complete.",    erase.addr, percent);

if (opts->jffs2 && result == 0)
  printf(" Cleanmarker written at 0x%08lx.", erase.addr);
}

    最后重新编译u-boot,下载到NandFlash中运行,u-boot此时就可以支持烧写yaffs2文件系统镜像了。

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