u-boot-2009.11移植(适用于TQ2440和MINI2440)第六篇:添加Yaffs(2)镜像烧写功能

来源:互联网 发布:an99软件下载 编辑:程序博客网 时间:2024/05/22 04:40

注意:红色标记为修改内容

由于现在很多使用Nand Flash 的系统,在Linux 下都用Yaffs(2)作为存储数据的文件系统,甚至是根文件系统。所以在BootLoader 下能够烧写Yaffs(2) 映像文件变得很必要。

(1) 修改common/cmd_nand.c文件

int do_nand(cmd_tbl_t * cmdtp, int flag, int argc,char *argv[])

{

……….

if(read)

                ret= nand_read_skip_bad(nand, off, &size,

                             (u_char *)addr);

            else

                ret= nand_write_skip_bad(nand, off, &size,

                              (u_char *)addr);

#if defined(ENABLE_CMD_NAND_YAFFS)

        }elseif ( s != NULL &&

            (!strcmp(s,".yaffs") || !strcmp(s, ".yaffs1"))){

                if(read) {

                  printf("nand read.yaffs[1] is notprovide 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_tops = {

                .oobbuf= (u8 *)addr,

                .ooblen= size,

                .mode= MTD_OOB_RAW

            };

……….

}

……….

U_BOOT_CMD(nand, CONFIG_SYS_MAXARGS, 1, do_nand,

……….

"nand erase [clean] [off size] - erase 'size'bytes from\n"

    "    offset 'off' (entire device if notspecified)\n"

#if defined(ENABLE_CMD_NAND_YAFFS)

    "nandread[.yaffs[1]] is not provide temporarily!\n"

    "nandwrite[.yaffs[1]]    addr off size - writethe `size' byte yaffs image starting\n"

    "     at offset `off' from memory address `addr'(.yaffs1 for 512+16 NAND)\n"

#endif

    "nandbad - show bad blocks\n"

    "nanddump[.oob] off - dump page\n"

    "nandscrub - really clean NAND erasing bad blocks (UNSAFE)\n"

……….

(2)修改driver/mtd/nand/nand_base.c文件

static int nand_write(struct mtd_info *mtd, loff_t to,size_t len,

              size_t *retlen, const uint8_t *buf)

{

    structnand_chip *chip = mtd->priv;

    int ret;

#if defined(ENABLE_CMD_NAND_YAFFS)

    /*Thanksfor hugerat's code!*/

   

    intoldopsmode = 0;

    if(mtd->rw_oob==1)  {

        size_toobsize = mtd->oobsize; 

        size_tdatasize = mtd->writesize;

        inti = 0;

        uint8_toobtemp[oobsize];

        intdatapages = 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 notallow reads past end of device */

    if ((to +len) > mtd->size)

…………

    chip->ops.len= len;

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

//  chip->ops.oobbuf= NULL;

 

#if defined(ENABLE_CMD_NAND_YAFFS)

    /*Thanksfor 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;

}

(3)修改driver/mtd/nand/nand_util.c文件

int nand_write_skip_bad(nand_info_t *nand, loff_toffset, size_t *length,

            u_char*buffer)

{

    int rval;

    size_tleft_to_write = *length;

    size_tlen_incl_bad;

    u_char*p_buffer = buffer;

#if defined(ENABLE_CMD_NAND_YAFFS)

    /*Thanksfor hugerat's code*/

   

    if(nand->rw_oob==1) {

        size_toobsize = nand->oobsize; 

        size_tdatasize = nand->writesize;

        intdatapages = 0;

 

      

        if(((*length)%(nand->oobsize+nand->writesize)) != 0) {

            printf ("Attempt to write error lengthdata!\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 ||

……….

printf ("Attempt to write outside the flasharea\n");

        return-EINVAL;

    }

   

#if !defined(ENABLE_CMD_NAND_YAFFS)

/*by hugerat */

    if(len_incl_bad == *length) {

        rval =nand_write (nand, offset, length, buffer);

        if (rval!= 0)

            printf("NAND write to offset %llx failed %d\n",

                offset,rval);

 

        returnrval;

    }

#endif

    while(left_to_write > 0) {

        size_tblock_offset = offset & (nand->erasesize - 1);

………

        offset += nand->erasesize - block_offset;

            continue;

        }

#if defined(ENABLE_CMD_NAND_YAFFS)

        /*Thanksfor 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",

                offset,rval);

            *length-= left_to_write;

            returnrval;

        }

 

        left_to_write-= write_size;

        printf("%d%% iscomplete.",100-(left_to_write/(*length/100)));/*Thanks for hugerat'scode*/

        offset        += write_size;

#if defined(ENABLE_CMD_NAND_YAFFS)

        /*Thanksfor 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;

}

(4)修改include/linux/mtd/mtd.h文件

struct mtd_info {

    u_char type;

    u_int32_tflags;

………

u_int32_t writesize;

 

#if defined(ENABLE_CMD_NAND_YAFFS)

        /*Thanksfor hugerat's code*/

    u_charrw_oob;

    u_charskipfirstblk;

#endif

 

    u_int32_toobsize;   /* Amount of OOB data perblock (e.g. 16) */

    u_int32_toobavail;  /* Available OOB bytes perblock */

(5)修改配置文件 include/configs/sunzl2440.h

#endif  /*CONFIG_CMD_NAND */

 

/**********************添加yaffs功能******************/

#define ENABLE_CMD_NAND_YAFFS   1   

#define ENABLE_CMD_NAND_YAFFS_SKIPFB    1

/***************************************************/

 

#define CONFIG_SETUP_MEMORY_TAGS

#define CONFIG_INITRD_TAG

#define CONFIG_CMDLINE_TAG

0 0
原创粉丝点击