Table of contents
- I cannot mount JFFS2 and see "Magic bitmask 0x1985 not found" messages
- I am going to use JFFS2 on top of my hard drive, is it OK?
- I am going to use JFFS2 on top of my USB stick/CF card/etc, is it OK?
- JFFS2 generates messages, is there a problem
- I cannot loop mount a JFFS2 image
- Do I need to use mtdblock to mount my JFFS2 filesystem?
- How do I get the 2.6 kernel to recognize JFFS2 as my rootfs?
- How is ensured, that data is written to flash?
- How to program an image to FLASH?
- How does JFFS2 handle a block going bad in NAND flash?
- What is cleanmarker and what it is used for?
I cannot mount JFFS2 and see "Magic bitmask 0x1985 not found" messages
If you cannot mount your JFFS2 file system and you see many messages like
jffs2_scan_eraseblock(): Magic bitmask 0x1985 not found at 0x00000024: 0x2b10 instead
...
Further such events for this erase block will not be printed
this means that the data on your flash device is not a valid JFFS2 file system. There is no single solution for this problem, but we will try to provide you some ideas how to fix this.
The first question you should try to answer is "why the data on my flash device is incorrect so that JFFS2 rejects to deal with it?". There are may be a plenty of reasons, e.g.:
- you flash driver is severely buggy so it reads trash instead of valid data;
- you flashed some trash instead of a valid JFFS2 image;
- you did not manage to flash JFFS2 image correctly so that you ended up with garbage on your flash, although the original image was perfectly fine;
- you forgot to erase your flash before flashing it, etc.
Anyways, JFFS2 wouldn’t complain if it was able to find correct data. As it does complain, there is something wrong with the data it reads.
One common mistake is to use /dev/mtdX
or /dev/mtdblockX
devices to flash JFFS2 images on NAND flashes. E.g.
cp jffs2_fs.img /dev/mtd2
This is incorrect because when dealing with NAND flashes one has to skip bad eraseblocks and write only in NAND page size chunks. Please, use the nandwrite
utility instead.
Also please, do not forget to erase your flash before flashing the image. You may use the flash_eraseall
utility for this. And it makes sense to make sure the erase functionality actually works my reading the erase MTD device back and checking that only 0xFF bytes were read.
You may try to check if your flash driver works correctly and if you flashed the file system image correctly by means of reading the flash back after you have flashed your image, and compare the read image with the original one. Please, use the nandread
utility to read from NAND flashes.
You can also do the following experiment to make sure JFFS2 works well. Erase your MTD device and mount it to JFFS2. You will end up with an empty file system. Copy some files to the JFFS2 file system and unmount it. Then mount it again and see if it mounts without problems. If it does, this is most probably not a JFFS2 bug.
I am going to use JFFS2 on top of my hard drive, is it OK?
First off, JFFS2 was designed for MTD devices, not for block devices like hard drives. These are two very different types of devices. Please, read this, and this and realize this difference.
Now you understand that you are going to use JFFS2 with devices it was not designed for, is it OK? Obviously, it is generally not OK.
It is possible to use JFFS2 with the block2mtd
driver. The driver emulates an MTD device on top of a block device so that you may feed the emulated MTD device to JFFS2 and utilize the file system on top of it. But do not complain when you have noticed that the performance suffers.
Owing to peculiarities of flash devices, JFFS2 is very different to conventional HDD-oriented file system. And one of its drawbacks is that mount time as well as memory consumption grow linearly with growing flash size. So beware you may end up with tremendous amount memory eaten and huge mount time if your block device is very large. Also, JFFS2 implements only write-trough caching (while convectional FS-es have write-back) and does many thing which are not really needed in case of hard drives.
So, beware of this and think twice. Also, nobody guarantees block2mtd
is bug-free. It it mostly used for debugging purposes, when it is easier to utilize emulated mtd device on the host development machine rather then debug on the target board. But of course, if you tested it and everything is OK with you – go ahead.
I am going to use JFFS2 on top of my USB stick/CF card/etc, is it OK?
USB sticks, CompactFlash cards and other removable flash media are not MTD devices. They are block devices. They do contain flash chip inside, but they also contain some translation layer above which emulates block device. This translation layer is implemented in hardware. So for outside world these devices look exactly as hard drives, not like MTD devices.
Please, read this FAQ entry about using JFFS2 on top of hard drives.
So, the answer is probably yes, you technically can, but be sure you realize why you do this. In general it is bad idea. It is much better to use any conventional file system like ext2.
Also note, these devices are "black boxes". The way they implement this flash-to-block device translation layer is not usually published. And in many cases the algorithms used at this layer are far from brilliant. For example, many USB sticks and other cards lose data in case of unclean reboots/power cuts. So, be very careful.
JFFS2 generates messages, is there a problem?
JFFS2 adopts the philosophy of keeping the user completely appraised of what is going on. This can catch out the unwary novice. The following messages can be moved to a higher log level once you are sure that they are benign.
Empty flash at 0xXXXXXXXX ends at 0xXXXXXXXX
This message is generated if a block of data is partially written. It is generally not a sign of any problem.
Name CRC failed on node at 0x00b620c8: Read 0x640c8ca3, calculated 0x795111fe
or similar message about CRC failures. If you have ever done unclean reboots – this is harmless. This just means that the unclean reboot happened (1) during data write or write buffer sync or (2) while GC was working or (3) while the write-buffer contained some data and was not yet synced before the unclean reboot happened. In them first and the third cases, you just lose the very last data you have written, in the second case you lose nothing. The wrong nodes will eventually be recycled by Garbage Collector and the massages will go (but they may leave quite long).
But this also may mean that data on your flash was corrupted for sum reasons. Unfortunately JFFS2 cannot distinguish between node corruptions cause by unclean reboots and by real media corruptions. But the latter case is very rare.
You cannot use older JFFS2 filesystems with newer kernels
Please, update your MTD utilities and use newer mkfs.jffs2.
I cannot loop mount a JFFS2 image
JFFS2 images can not be loop mounted. The loop device is essentially a driver which represents files as block devices. But JFFS2 works on top of MTD devices which are different. So an "mtdloop" device would be needed for this, but nobody implemented it yet.
The only way to manipulate JFFS2 images is by copying them into a mtdram device and mounting the device with JFFS2.
Also, if you are desperate, then fix jffs2_dump to recreate the filesystem from the image. It’s not hard. All the basics are done already.
Do I need to use mtdblock to mount my JFFS2 filesystem?
In general, mtdblock is not required to mount JFFS2 filesystems. One can use the MTD device name or minor number to specify the MTD device that contains the JFFS2 filesystem. For example, both:
mount -t jffs2 mtd2 /foo
mount -t jffs2 mtd:name_of_device /foo
should both work assuming the device specified actually contains a valid JFFS2 filesystem.
There are two cases where this does not work. The first is when JFFS2 is used as a root filesystem. For now, this requires the mtdblock device to be specified for root=
on the kernel commandline. The second case is when the mount binary that is being used does not play nicely with the above format. The busybox version of mount is known to not work without the mtdblock device.
How do I get the 2.6 kernel to recognize JFFS2 as my rootfs?
With the 2.6 kernel, you will need to specify: rootfstype=jffs2
on the kernel command line to use it as a root filesystem
How is ensured, that data is written to flash?
On NOR FLASH each write goes directly into the FLASH.
On NAND FLASHM and NOR ECC FLASH we have a write-buffer for writing only full pages to the chips. There could be a loss of data, when the write-buffer is not flushed before power down. There are some mechanisms to ensure, that the write-buffer is flushed. You can force the flush of the write-buffer by using fsync()
or sync()
in your application. JFFS2 has a timed flush of the write buffer, which forces the flush of the buffer to flash, if there are no writes to the filesystem for more than about 5 seconds. The time depends on the cycle-time of kupdated, which can be adjusted via /proc/sys/vm/dirty_expire_centisecs
.
When you unmount the filesystem the buffer is flushed too.
If the partition is being used as a root filesystem, which obviously cannot be dismounted, the filesystem should be remounted read only on shutdown. In the case of JFFS2 this will cause the garbage collector to flush its write buffers. Failure to do this may cause the filesystem to generate warnings regarding bad CRC. These are partially collected garbage blocks which will be rescheduled for garbage collection some time later. This kind of behaviour may also be observed after a system crash.
How to program an image to FLASH?
There are several possibilities to do so:
- From Linux
- From bootloader
- Via JTAG
- At production time
For NOR FLASH there are no restrictions. For NAND FLASH please read the NAND FAQ section.
How does JFFS2 handle a block going bad in NAND flash?
If an error occurs when writing to a page, JFFS2 will attempt recovery of the data. If the block contains nodes that have already been written to flash, the block is refiled onto the list of blocks that are bad but still in use (the bad_used_list). Then the write buffer itself is recovered. This takes into account any data that has been partially written to flash. Once the write buffer has been recovered, normal operation continues. Garbage collection is responsible for moving the valid nodes from the block that was refiled.
Once garbage collection has written all of the valid nodes to a different eraseblock, the block is moved to the erase pending list. From there JFFS2 will erase the eraseblock. If the erase failed, it is put on the erase pending list again for a retry. If the erase fails at the device level a total of three times, it is marked as bad in the OOB area and filed onto the bad_block_list. If the erase succeeds, a clean marker is written to the OOB area and the block is filed onto the free list. This is done because NAND flash can have non-permanent failures due to over-programing or write-disturb errors. A block erase clears these conditions.
What is cleanmarker and what it is used for?
Cleanmarker is a special JFFS2 node which is written to the beginning of a block just after the block has been erased. On NOR flashes it is a special small JFFS2 node at the beginning of the block. On NAND flashes it is placed to the spare area of the first page.
The main reason why cleanmarkers are used is the need to be sure that the block erase operation was correctly completed. All 0xFF bytes in the block are not necessarily mean the block is ready to be utilized. For example, if an unclean reboot happened just at the end of the block erase cycle, the block might have unstable bits, which are read as "1" one time and might be read as "0" next time.
When preparing a flash partition for JFFS2, it is recommended to put cleanmarkers to the erased blocks. This might be done by means of "-j" option of the "flash_eraseall" MTD utility. Otherwise, JFFS2 will re-erase the blocks which contain all 0xFF and have no cleanmarker. This is an unneeded wasting of time.