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


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.

  • 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.
    – wangt13
    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.
    – wangt13
    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.
    – Philippos
    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.
    – wangt13
    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.
    – wangt13
    Commented Apr 23, 2023 at 8:40

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .