0

I am developing for an embedded Linux application using friendlyARM's micro2440. It runs on a Samsung s3c2440 ARM processor and uses squashfs in its NAND flash.

Recently, some flash blocks went bad. u-Boot correctly finds them and creates a bad block table with the offsets given by the nand bad command:

Device 0 bad blocks:
01340000
0abc0000
0f080000
0ff80000
0ffa0000
0ffc0000
0ffe0000

When I try to boot the kernel, it correctly scans the bad blocks and creates its bad block table, as seen in the following messages:

Scanning device for bad blocks
Bad eraseblock 154 at 0x000001340000
Bad eraseblock 1374 at 0x00000abc0000
Bad eraseblock 1924 at 0x00000f080000

But when it comes the time for the kernel to mount the filesystem in the partition where the bad block at 0x000001340000 happens, it seems unable to skip the bad blocks and then it panics. The error messages given were:

SQUASHFS error: squashfs_read_data failed to read block 0xd0e24b
SQUASHFS error: Unable to read metadata cache entry [d0e24b]
SQUASHFS error: Unable to read inode 0x3d1d0f68
------------[ cut here ]------------
WARNING: at fs/inode.c:712 unlock_new_inode+0x20/0x3c()
Modules linked in:
[<c0037750>] (unwind_backtrace+0x0/0xcc) from [<c0044994>]                             (warn_slowpath_null+0x34/0x4c)
[<c0044994>] (warn_slowpath_null+0x34/0x4c) from [<c00a42c8>] (unlock_new_inode+0x20/0x3c)
[<c00a42c8>] (unlock_new_inode+0x20/0x3c) from [<c00a61b8>] (iget_failed+0x14/0x20)
[<c00a61b8>] (iget_failed+0x14/0x20) from [<c00f75cc>] (squashfs_fill_super+0x3c8/0x508)
[<c00f75cc>] (squashfs_fill_super+0x3c8/0x508) from [<c0095990>] (get_sb_bdev+0x110/0x16c)
[<c0095990>] (get_sb_bdev+0x110/0x16c) from [<c00f7164>] (squashfs_get_sb+0x18/0x20)
[<c00f7164>] (squashfs_get_sb+0x18/0x20) from [<c0095008>] (vfs_kern_mount+0x44/0xd8)
[<c0095008>] (vfs_kern_mount+0x44/0xd8) from [<c00950e0>] (do_kern_mount+0x34/0xe0)
[<c00950e0>] (do_kern_mount+0x34/0xe0) from [<c00a9084>] (do_mount+0x5d8/0x658)
[<c00a9084>] (do_mount+0x5d8/0x658) from [<c00a9330>] (sys_mount+0x84/0xc4)
[<c00a9330>] (sys_mount+0x84/0xc4) from [<c0008c60>] (mount_block_root+0xe4/0x20c)
[<c0008c60>] (mount_block_root+0xe4/0x20c) from [<c00090fc>] (prepare_namespace+0x160/0x1c0)
[<c00090fc>] (prepare_namespace+0x160/0x1c0) from [<c00089c8>] (kernel_init+0xd8/0x104)
[<c00089c8>] (kernel_init+0xd8/0x104) from [<c0033738>] (kernel_thread_exit+0x0/0x8)
---[ end trace c21b44698de8995c ]---
VFS: Cannot open root device "mtdblock5" or unknown-block(31,5)
Please append a correct "root=" boot option; here are the available         partitions:
1f00             256 mtdblock0 (driver?)
1f01             128 mtdblock1 (driver?)
1f02             640 mtdblock2 (driver?)
1f03            5120 mtdblock3 (driver?)
1f04            5120 mtdblock4 (driver?)
1f05           40960 mtdblock5 (driver?)
1f06           40960 mtdblock6 (driver?)
1f07          167936 mtdblock7 (driver?)
1f08            1024 mtdblock8 (driver?)
Kernel panic - not syncing: VFS: Unable to mount root fs on unknown-block(31,5)
[<c0037750>] (unwind_backtrace+0x0/0xcc) from [<c02fdd40>] (panic+0x3c/0x114)
[<c02fdd40>] (panic+0x3c/0x114) from [<c0008d44>] (mount_block_root+0x1c8/0x20c)
[<c0008d44>] (mount_block_root+0x1c8/0x20c) from [<c00090fc>] (prepare_namespace+0x160/0x1c0)
[<c00090fc>] (prepare_namespace+0x160/0x1c0) from [<c00089c8>] (kernel_init+0xd8/0x104)
[<c00089c8>] (kernel_init+0xd8/0x104) from [<c0033738>] (kernel_thread_exit+0x0/0x8)

I tried mounting the filesystem in mtdblock6 partition and everywhing worked as expected, as there are no badblocks in that part of the memory. I investigated the mtd source files responsible for the bad block management, but I couldn't find something useful about how the kernel skips the bad blocks.

  • It appears to me that the result isn't from the bad block but because you are trying to mount (31,5). On most systems you would see something like 'root (hd0,0)' where it tries to mount the first drive of the first partition. Are you saying that you you're trying to mount the 32nd (start with 0) drive of the sixth (starting with 0) partition?? That won't work unless you really have that many drives and partitions. It's possible that I'm reading the output wrong. – Jeight May 28 '14 at 20:49
  • Actually, that is expected. I have 9 partitions: 0) u-boot 1) environment 2) guard-uboot 3) kernel 4) guard-kernel 5) filesystem1 6) filesystem2 7) persistent 8) guard-final. So when I try to mount root in the 6th partition, I'm actually mounting it in the filesystem1 partition, as expected. There is a bad block there, but the kernel isn't skipping it. – franchzilla May 30 '14 at 14:14
2

We've figured out that the problem is with squashfs itself. It has no support for bad block detection, as stated here:

http://elinux.org/Support_read-only_block_filesystems_on_MTD_flash

So the possible solution is to use another filesystem or use UBI to manage the bad blocks and then keep using squashfs.

0

Did you try adding something like 'rootdelay=2' (or longer, up to 10 I believe) to your boot arguments? Might give the flash a bit of extra time to sort things out before it is being accessed by the kernel.

  • I've just tried adding this environment variable in u-boot, with value 2 and then 10, but to no result. I got the same problem as before. – franchzilla May 29 '14 at 12:35

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.