FL2440--YAFFS2系统移植(一)

作者详细记录了将YAFFS2文件系统移植到NANDFlash的过程,包括修改U-Boot支持YAFFS2的相关代码,解决了在直接下载到NANDFlash中遇到的问题。分享了补丁文件和关键步骤。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

   经过十多天的重复移植,不断的烧文件,不断的修改文件,终于把YAFFS2文件系统给弄出来了.先高兴一下...接着写移植过程遇到的各种问题.

我这里的移植是直接把YAFFS2当做根文件系统,直接下载到nandflash中,因为目前的uboot并不支持YAFFS2的烧写,所以就要修改uboot.(我使用的是u-boot-2010.09)

一、修改uboot支持yaffs2

注(以下的patch文件是Tekkaman Ninja 提供的)

diff -uaNr u-boot-2009.08/common/cmd_nand.c u-boot-2009.08_tekkaman/common/cmd_nand.c
--- u-boot-2009.08/common/cmd_nand.c    2009-09-01 01:57:42.000000000 +0800
+++ u-boot-2009.08_tekkaman/common/cmd_nand.c   2009-10-28 21:20:49.000000000 +0800
@@ -389,6 +389,28 @@
            else
                ret = nand_write_skip_bad(nand, off, &size,
                              (u_char *)addr);
+#if defined(ENABLE_CMD_NAND_YAFFS)
+       }else if ( s != NULL &&
+           (!strcmp(s, ".yaffs") || !strcmp(s, ".yaffs1"))){
+               if(read)  {
+                 //nand->rw_oob = 1;
+                 //ret = nand_read_skip_bad(nand,off,&size,(u_char *)addr);
+                // nand->rw_oob = 0;
+                 printf("nand read.yaffs[1] is not provide temporarily!"); 
+               } else    {
+               nand->rw_oob = 1;
+#if defined(ENABLE_CMD_NAND_YAFFS_SKIPFB)
+               nand->skipfirstblk = 1;
+#else
+               nand->skipfirstblk = 0;
+#endif
+               ret = nand_write_skip_bad(nand,off,&size,(u_char *)addr);
+#if defined(ENABLE_CMD_NAND_YAFFS_SKIPFB)
+               nand->skipfirstblk = 0;
+#endif
+               nand->rw_oob = 0;
+               }
+#endif
        } else if (!strcmp(s, ".oob")) {
            /* out-of-band data */
            mtd_oob_ops_t ops = {
@@ -496,6 +518,13 @@
    "    to/from memory address 'addr', skipping bad blocks.\n"
    "nand erase [clean] [off size] - erase 'size' bytes from\n"
    "    offset 'off' (entire device if not specified)\n"
+#if defined(ENABLE_CMD_NAND_YAFFS)
+// "nand read[.yaffs[1]]    addr off size - read the `size' byte yaffs image starting\n"
+// "     at offset `off' to memory address `addr' (.yaffs1 for 512+16 NAND)\n"
+   "nand read[.yaffs[1]] is not provide temporarily!\n"
+   "nand write[.yaffs[1]]    addr off size - write the `size' byte yaffs image starting\n"
+   "     at offset `off' from memory address `addr' (.yaffs1 for 512+16 NAND)\n"
+#endif
diff -uaNr u-boot-2009.08/drivers/mtd/nand/nand_base.c u-boot-2009.08_tekkaman/drivers/mtd/nand/nand_base.c
--- u-boot-2009.08/drivers/mtd/nand/nand_base.c 2009-09-01 01:57:42.000000000 +0800
+++ u-boot-2009.08_tekkaman/drivers/mtd/nand/nand_base.c    2009-10-28 21:19:23.000000000 +0800
@@ -1958,7 +1958,30 @@
 {
    struct nand_chip *chip = mtd->priv;
    int ret;
-
+#if defined(ENABLE_CMD_NAND_YAFFS)
+   /*Thanks for hugerat's code!*/
+   
+   int oldopsmode = 0;
+   if(mtd->rw_oob==1)  {
+       size_t oobsize = mtd->oobsize;  
+       size_t datasize = mtd->writesize;
+       int i = 0;
+       uint8_t oobtemp[oobsize];
+       int datapages = 0;
+       datapages = len/(datasize); 
+       for(i=0;i<(datapages);i++)  {
+           memcpy((void *)oobtemp,
+               (void *)(buf+datasize*(i+1)),
+               oobsize);
+           memmove((void *)(buf+datasize*(i+1)),
+               (void *)(buf+datasize*(i+1)+oobsize),
+               (datapages-(i+1))*(datasize)+(datapages-1)*oobsize);
+           memcpy((void *)(buf+(datapages)*(datasize+oobsize)-oobsize),
+               (void *)(oobtemp),
+               oobsize);
+       }
+   }
+#endif
    /* Do not allow reads past end of device */
    if ((to + len) > mtd->size)
        return -EINVAL;
@@ -1969,14 +1992,30 @@

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

+#if defined(ENABLE_CMD_NAND_YAFFS)
+   /*Thanks for hugerat's code!*/
+   if(mtd->rw_oob!=1)  {
+     chip->ops.oobbuf = NULL;
+   } else  {
+     chip->ops.oobbuf = (uint8_t *)(buf+len); 
+     chip->ops.ooblen = mtd->oobsize;
+     oldopsmode = chip->ops.mode;
+     chip->ops.mode = MTD_OOB_RAW; 
+   }
+#else
+   chip->ops.oobbuf = NULL;
+#endif
    ret = nand_do_write_ops(mtd, to, &chip->ops);

    *retlen = chip->ops.retlen;

    nand_release_device(mtd);

+#if defined(ENABLE_CMD_NAND_YAFFS)
+   /*Thanks for hugerat's code!*/
+   chip->ops.mode = oldopsmode; 
+#endif
    return ret;
 }

diff -uaNr u-boot-2009.08/drivers/mtd/nand/nand_util.c u-boot-2009.08_tekkaman/drivers/mtd/nand/nand_util.c
--- u-boot-2009.08/drivers/mtd/nand/nand_util.c 2009-09-01 01:57:42.000000000 +0800
+++ u-boot-2009.08_tekkaman/drivers/mtd/nand/nand_util.c    2009-11-01 14:18:28.000000000 +0800
@@ -480,6 +480,26 @@
    size_t left_to_write = *length;
    size_t len_incl_bad;
    u_char *p_buffer = buffer;
+#if defined(ENABLE_CMD_NAND_YAFFS)
+   /*Thanks for hugerat's code*/
+   
+   if(nand->rw_oob==1) {
+       size_t oobsize = nand->oobsize;  
+       size_t datasize = nand->writesize;
+       int datapages = 0;
+
+       
+       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;
+   }
+#endif

    /* Reject writes, which are not page aligned */
    if ((offset & (nand->writesize - 1)) != 0 ||
@@ -494,7 +514,9 @@
        printf ("Attempt to write outside the flash area\n");
        return -EINVAL;
    }
-
+   
+#if !defined(ENABLE_CMD_NAND_YAFFS)
+
    if (len_incl_bad == *length) {
        rval = nand_write (nand, offset, length, buffer);
        if (rval != 0)
@@ -503,7 +525,7 @@

        return rval;
    }
-
+#endif
    while (left_to_write > 0) {
        size_t block_offset = offset & (nand->erasesize - 1);
        size_t write_size;
@@ -516,12 +538,21 @@
            offset += nand->erasesize - block_offset;
            continue;
        }
-
+#if defined(ENABLE_CMD_NAND_YAFFS)
+       /*Thanks for hugerat's code*/
+       if(nand->skipfirstblk==1)   {       
+           nand->skipfirstblk=0;
+           printf ("Skip the first good block %llx\n",
+               offset & ~(nand->erasesize - 1));
+           offset += nand->erasesize - block_offset;
+           continue;
+       }
+#endif
        if (left_to_write < (nand->erasesize - block_offset))
            write_size = left_to_write;
        else
            write_size = nand->erasesize - block_offset;
-
+       printf("\rWriting at 0x%llx -- ",offset);   /*Thanks for hugerat's code*/
        rval = nand_write (nand, offset, &write_size, p_buffer);
        if (rval != 0) {
            printf ("NAND write to offset %llx failed %d\n",
@@ -531,8 +562,18 @@
        }

        left_to_write -= write_size;
+       printf("%d%% is complete.",100-(left_to_write/(*length/100)));/*Thanks for hugerat's code*/
        offset        += write_size;
+#if defined(ENABLE_CMD_NAND_YAFFS)
+       /*Thanks for hugerat's code*/
+       if(nand->rw_oob==1) {
+           p_buffer += write_size+(write_size/nand->writesize*nand->oobsize);
+       } else  {
+           p_buffer += write_size;
+       }
+#else
        p_buffer      += write_size;
+#endif
    }

    return 0;
diff -uaNr u-boot-2009.08/include/linux/mtd/mtd.h u-boot-2009.08_tekkaman/include/linux/mtd/mtd.h
--- u-boot-2009.08/include/linux/mtd/mtd.h  2009-09-01 01:57:42.000000000 +0800
+++ u-boot-2009.08_tekkaman/include/linux/mtd/mtd.h 2009-10-28 21:19:23.000000000 +0800
@@ -129,6 +129,12 @@
     */
    u_int32_t writesize;

+#if defined(ENABLE_CMD_NAND_YAFFS)
+       /*Thanks for hugerat's code*/
+   u_char rw_oob;
+   u_char skipfirstblk;
+#endif

可直接去http://blog.chinaunix.net/uid-20543672-id-94384.html 下载补丁. 在此多谢前人分享经验..



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值