After embedded board run to kernel, it will called a file system. It is NAND flash in mini2440 system board, so take a yaffs file system to the flash. This part is for porting yaffs file system function in u-boot.
1.Edit /common/cmd_nand.c:
diff -uNr u-boot-2009.08_nand/common/cmd_nand.c u-boot-2009.08_yaffs/common/cmd_nand.c
--- u-boot-2009.08_nand/common/cmd_nand.c 2017-03-19 15:24:58.000000000 +0800
+++ u-boot-2009.08_yaffs/common/cmd_nand.c 2017-04-25 16:26:18.501859985 +0800
@@ -389,6 +389,26 @@
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){
+ printf("nand read.yaffs[1] is not provide by nicholas!");
+ }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 = {
2.Edit /drivers/mtd/nand/nand_base.c:
diff -uNr u-boot-2009.08_nand/drivers/mtd/nand/nand_base.c u-boot-2009.08_yaffs/drivers/mtd/nand/nand_base.c
--- u-boot-2009.08_nand/drivers/mtd/nand/nand_base.c 2017-03-19 15:24:54.000000000 +0800
+++ u-boot-2009.08_yaffs/drivers/mtd/nand/nand_base.c 2017-04-25 16:52:28.501848090 +0800
@@ -1959,6 +1959,29 @@
struct nand_chip *chip = mtd->priv;
int ret;
+#if defined(ENABLE_CMD_NAND_YAFFS)
+ 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,7 +1992,18 @@
chip->ops.len = len;
chip->ops.datbuf = (uint8_t *)buf;
+#if defined(ENABLE_CMD_NAND_YAFFS)
+ 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);
@@ -1977,6 +2011,10 @@
nand_release_device(mtd);
+#if defined(ENABLE_CMD_NAND_YAFFS)
+ chip->ops.mode = oldopsmode;
+#endif
+
return ret;
}
3.Edit /drivers/mtd/nand/nand_util.c:
diff -uNr u-boot-2009.08_nand/drivers/mtd/nand/nand_util.c u-boot-2009.08_yaffs/drivers/mtd/nand/nand_util.c
--- u-boot-2009.08_nand/drivers/mtd/nand/nand_util.c 2017-03-19 15:24:54.000000000 +0800
+++ u-boot-2009.08_yaffs/drivers/mtd/nand/nand_util.c 2017-04-25 16:53:16.317847727 +0800
@@ -481,6 +481,22 @@
size_t len_incl_bad;
u_char *p_buffer = buffer;
+#if defined(ENABLE_CMD_NAND_YAFFS)
+ 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;
+ }
+#endif
+
/* Reject writes, which are not page aligned */
if ((offset & (nand->writesize - 1)) != 0 ||
(*length & (nand->writesize - 1)) != 0) {
@@ -495,6 +511,7 @@
return -EINVAL;
}
+#if !defined(ENABLE_CMD_NAND_YAFFS)
if (len_incl_bad == *length) {
rval = nand_write (nand, offset, length, buffer);
if (rval != 0)
@@ -503,6 +520,7 @@
return rval;
}
+#endif
while (left_to_write > 0) {
size_t block_offset = offset & (nand->erasesize - 1);
@@ -516,6 +534,14 @@
offset += nand->erasesize - block_offset;
continue;
}
+#if defined(ENABLE_CMD_NAND_YAFFS)
+ 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;
@@ -531,8 +557,17 @@
}
left_to_write -= write_size;
+ printf("%d%% is complete.\r", 100 - (left_to_write/(*length/100)));
offset += write_size;
+#if defined(ENABLE_CMD_NAND_YAFFS)
+ 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. Edit /include/linux/mtd/mtd.h:
diff -uNr u-boot-2009.08_nand/include/linux/mtd/mtd.h u-boot-2009.08_yaffs/include/linux/mtd/mtd.h
--- u-boot-2009.08_nand/include/linux/mtd/mtd.h 2017-03-19 15:24:58.000000000 +0800
+++ u-boot-2009.08_yaffs/include/linux/mtd/mtd.h 2017-04-25 16:51:27.333848553 +0800
@@ -129,6 +129,11 @@
*/
u_int32_t writesize;
+#if defined(ENABLE_CMD_NAND_YAFFS)
+ u_char rw_oob;
+ u_char skipfirstblk;
+#endif
+
u_int32_t oobsize; /* Amount of OOB data per block (e.g. 16) */
u_int32_t oobavail; /* Available OOB bytes per block */