1

I am working on an embedded Linux system (5.10.24), where there is a NAND FLASH as storage.
The NAND FLASH is partitioned into 4 parts, part 0 is used for u-boot, part 1 is used for kernel, part 2 is used as UBIFS, part 3 is another UBIFS partition.
So when Linux boots up, it shows there are /dev/mtd0, /dev/mtd1, /dev/mtd2, /dev/mtd3.

Now I can read data of u-boot from /dev/mtd0 (raw FLASH, no filesystem) through POSIX-C file operations.
Then I want to saved some data to NAND FLASH partition 0 by writing to /dev/mtd0.

All the file reading/writing operations are done well, no error reported.
But when I reboot system back to u-boot, it complains that there are lots of errors like spi nand read oob error ,ret= -74 , oob addr e0000, ooboffs 0, ooblen 64.

It seemed that NAND OOB has something wrong, why does this error happen and how to write data to raw NAND FLASH through /dev/mtd interface?

1 Answer 1

2

NAND flash needs to be erased (blockwise) before writing to it. There are ioctls to do that. mtd-utils is the toolset of choice to interact with your mtd volumes from within Linux with utilities like flashcp, but it is also a good entry point to get information on how to do it yourself on a low level, see http://www.linux-mtd.infradead.org/doc/general.html

That said, the much more common way to interact with your mtd volumes from within U-Boot is using it as the storage of your U-Boot environment. Instead of writing to the mtd volume directly, do some setenv and saveenv to write it to the NAND including all checksumming. From Linux, you can use fw_printenv and so on.

5
  • Philippos, thanks for your pointing out the IOCTL on MTD device, I will try it. Then I did try fw_printenv in my environment, but I failed to build it (I don't know why it is compiled with host CC not with the cross compiler) and it also seemed that fw_printenv needs to re-partition the NAND FLASH,,, I am not sure about that. So I decided to R/W U-boot NAND partition directly by myself. I will check if fw_printenv can meet my requirement in this system. Commented Apr 20, 2023 at 23:46
  • I tried with ioctl(fd, MEMERASE, &erase) in my code, to erase one eraseblock (128KB) of U-boot partition (1MB), and I can write my data into the block. But when I reboot to u-boot, I got the same error about spi nand read oob error ,ret= -74, I am not sure if I need to explicitly set OOB?? I am also checking if I can compile fw_printenv of u-boot for my target. Commented Apr 21, 2023 at 6:50
  • How do you build your Linux board support package? There is a Yocto recipe for u-boot-fw-utils, I think. I'm sorry I fail to help with the read error. Commented Apr 21, 2023 at 7:11
  • The LSP is packed within buildroot and I found it has uboot-tools-fwprintenv, I booted it and installed it to target then ran it, it partially working!!! Since the u-boot ENV is not written, only using default env (u-boot is NOT built from within buildroot). I will run saveenv in u-boot to have some data in the FLASH. As for the error of spi nand read oob error, it seemed that something wrong in OOB, maybe ECC, I am not sure it I needs to write data to OOB... I am still reading the NAND FLASH data sheet. Commented Apr 21, 2023 at 7:43
  • I just read the codes of fw_printenv, I think it is using /dev/mtdblockN instead of /dev/mtdN, so I changed my code to use /dev/mtdblock0 also, I can succeed in reading/writing data to raw FLASH of u-boot, the u-boot reboot well without comlaining about the oob errors. So I think in this case I should use /dev/mtdblockN not /dev/mtdN. This question is from my lack of knowledge of Linux MTD, and Philippos's answer is correct on /dev/mtd0 which is asked by me, I vote for his answer. Commented Apr 23, 2023 at 8:40

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.