0.
ubifs_iget: failed to read inode 1, error -22
经常是由于没有写全整个数据,最好检测下写入的数据大小是否对,尤其是通过环境变量 filesize 去获得,ubifsload 是否有设置这个环境变量。
1 .执行ubi part kernel时报错-12
Creating 1 MTD partitions on "nand0":
0x000004200000-0x00001e200000 : "mtd=3"
UBI: attaching mtd1 to ubi0
UBI warning: io_init: EC and VID headers are in thesame minimal I/O unit, switch to read-only mode
UBI: physical eraseblock size: 1048576 bytes (1024KiB)
UBI: logical eraseblock size: 1044480 bytes
UBI: smallest flash I/O unit: 4096
UBI: VID header offset: 2048 (aligned 0)
UBI: data offset: 4096
UBI error: ubi_init: cannot attach mtd1
UBIerror: ubi_init: UBI error: cannot initialize UBI, error -12
UBI init error 12
Error, no UBI device/partition selected!
网上一般都是说将CONFIG_SYS_MALLOC_LEN,增大到1M(1024*1024)。但我修改后同样报错
找到源码中报错的地方(/drivers/mtd/ubi/build.c/ubi_attach_mtd_dev函数)
err = -ENOMEM;
ubi->peb_buf1 = vmalloc(ubi->peb_size);
if (!ubi->peb_buf1)
goto out_free;
ubi->peb_buf2 = vmalloc(ubi->peb_size);
if (!ubi->peb_buf2)
goto out_free;
malloc大小为ubi->peb_size,经过查找最终是在(/driver/mtd/nand/nand_base.cnand_get_flash_type函数)
/* Calc blocksize */
mtd->erasesize = (128 * 1024) <<
(((extid >> 1) & 0x04) | (extid &0x03));
实际该值就是物理擦出块大小,通过芯片ID获取芯片类型,查看手册
查阅include/asm-generic/error.h发现12号错误的定义为“#define ENOMEM 12 /* Out of memory */”。
经过追踪,是在driver/mtd/ubi/build.c的ubi_attach_mtd_dev函数中第二次 vmalloc时死掉
该值为1024KB,那么问题就来了,CONFIG_SYS_MALLOC_LEN设置成1M,现在一次malloc的大小也是1M,连续两次malloc就会报错了,所以当nand芯片的块大小大于等于1M时,CONFIG_SYS_MALLOC_LEN就应该相应增大,我设置成4M了
2. 执行ubi part kernel时报错
Creating 1 MTD partitions on "nand0":
0x000004200000-0x00001e200000 : "mtd=3"
UBI: attaching mtd1 to ubi0
UBI warning: io_init: EC and VID headers are in the same minimal I/O unit, switch to read-only mode
UBI: physical eraseblock size: 1048576 bytes (1024 KiB)
UBI: logical eraseblock size: 1044480 bytes
UBI: smallest flash I/O unit: 4096
UBI: VID header offset: 2048 (aligned 0)
UBI: data offset: 4096
UBI: empty MTD device detected
UBI: create volume table (copy #1)
UBI error: ubi_io_sync_erase: read-only mode
UBI error: ubi_io_sync_erase: read-only mode
UBI error: ubi_io_sync_erase: read-only mode
UBI error: ubi_io_sync_erase: read-only mode
可以看到创建卷时提示ubi处于只读模式,同时注意到一个warning,找到源码位置(/drivers/mtd/ubi/build.c io_init函数)
/*
* It may happen that EC and VID headers are situated in one minimal
* I/O unit. In this case we can only accept this UBI image in
* read-only mode.
*/
if (ubi->vid_hdr_offset + UBI_VID_HDR_SIZE <= ubi->hdrs_min_io_size) {
ubi_warn("EC and VID headers are in the same minimal I/O unit, "
"switch to read-only mode");
ubi->ro_mode = 1;
}
经过打印
UBI_VID_HDR_SIZE = 64
ubi->vid_hdr_offset = 2048
ubi->hdrs_min_io_size = 4096
确实有问题,从nand手册上来看,最小的页为4k,所以hdrs_min_io_size应该没问题
而vid_hdr_offset就有点奇怪,最后找到这个值是由ubi part传进来的参数
修正命令
ubi part kernel -->ubi part kernel 4096
3. 执行 ubifsmount kernel报错-19
UBIFS error (pid 0): ubifs_get_sb: cannot open"ubi:kernel1", error -19
UBIFS error (pid 0): ubifs_mount: Error readingsuperblock on volume 'ubi:kernel1' errno=-19!
这应该是制作kernel镜像时mkfs.ubifs参数的问题了(都是跟nand相关的参数)
4.
UBI warning: ubi_scan: 35 PEBs are corrupted
corrupted PEBs are: 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 84 85 86
kernel中的注释是这样解释的:
/*
* Few corrupted PEBs are not a problem and may be just a result of
* unclean reboots. However, many of them may indicate some problems
* with the flash HW or driver. Print a warning in this case.
*/
有注释可知,出现这种打印的原因可能是不干净的断电(类似突然断电?),更多的是驱动的有问题。我想可能有这几种情况吧:
a. 制作ubi文件系统参数与flash参数不匹配(应该概率很小,如果不匹配,一般都直接失败,attach就会失败)
b. 驱动使用的ecc算法与nand所要求的不匹配?
c. 烧写工具烧录ubi文件系统有问题。
我这里的原因是uboot烧录ubi文件系统烧录的有问题,烧录ubi需要跳过全0xff的页,而这里没有跳过,造成ECC错误。
5.
UBI error: ubi_io_write: error -5 while writing 512 bytes to PEB 0:512, written 0 bytes
查阅include/asm-generic/error.h发现5号错误的定义为“#define EIO 5 /* I/O error */”。
在http://www.linux-mtd.infradead.org/faq/ubi.html#L_subpage_verify_fail有对这个问题的专门描述:
I get "ubi_io_write: error -5 while writing 512 bytes to PEB 5:512"
If you have a 2048 bytes per NAND page device, and have CONFIG_MTD_NAND_VERIFY_WRITE enabled in your kernel, you will need to turn it off. The code does not currently (as of 2.6.26) perform verification of sub-page writes correctly. As UBI is one of the few users of sub-page writes, not much else seems to be affected by this bug.
虽然是说Linux内核配置,可是u-boot中同样有CONFIG_MTD_NAND_VERIFY_WRITE ,在smartarm3250.h中将这个宏注释掉,问题解决。看来是内核的问题,既然u-boot很大程度上使用了Linux内核的驱动,应该是ubi驱动的问题。
6.
Cannot start volume update。
在common/cmd_ubi.c中的ubi_volume_write函数中找到打印这句话的地方,打印err发现仍然为12号错误。解决办法和1一样
7. linux内核启动时输出以下信息,并停住:
UBIFS error (pid 1): ubifs_read_node: bad node type (0 but expected 6)
UBIFS error (pid 1): ubifs_read_node: bad node at LEB 0:0
List of all partitions:
1f00 1536 mtdblock0 (driver?)
1f01 256 mtdblock1 (driver?)
1f02 4096 mtdblock2 (driver?)
1f03 16384 mtdblock3 (driver?)
1f04 239616 mtdblock4 (driver?)
No filesystem could mount root, tried: ubifs
Kernel panic - not syncing: VFS: Unable to mount root fs on unknown-block(0,0)
这个问题是由于写入命令错误引起的,原来的写入命令为ubi write 0x01600000 rootfs $(filesize),应该为ubi write 0x080008000 rootfs $(filesize)。也就是说原来根本没有把文件系统写入flash。
如果你也有此类错误,要么是你的文件系统镜像没有写入(或者没正确写入),要么是你做的文件系统镜像有问题。其他问题可能不大。
8. 软件版本问题。
linux内核启动过程中出现以下信息并停住:
UBIFS error (pid 1): ubifs_check_node: bad CRC: calculated 0x9f186f96, read 0x3baee010
UBIFS error (pid 1): ubifs_check_node: bad node at LEB 0:0
UBIFS error (pid 1): ubifs_read_node: expected node type 6
VFS: Cannot open root device "ubi0:rootfs" or unknown-block(0,0)
Please append a correct "root=" boot option; here are the available partitions:
1f00 1536 mtdblock0 (driver?)
1f01 256 mtdblock1 (driver?)
1f02 4096 mtdblock2 (driver?)
1f03 16384 mtdblock3 (driver?)
1f04 239616 mtdblock4 (driver?)
Kernel panic - not syncing: VFS: Unable to mount root fs on unknown-block(0,0)
我的文件系统镜像使用mtd-utils2010做的,我后来改为mtd-utils2009,问题解决。
我的内核版本是2.6.27.8。我猜测因为我的内核版本比较旧,所以内核和mtd-utils2010中的crc算法有差异才会出现bad CRC。
如果你也碰到类似问题,请确保内核版本和mtd-utils版本匹配。看是否匹配只要看内核和mtd-utils是不是一年出的就行,或者时间接近。总之,两个出现时间较远的软件协同工作会有可能出错。
9.
遇到这种错误,一般是由于你的分区设置不正确导致的。可以到u-boot/include/configs/xxx.h相应的板子配置文件下去查看自己的分区设置是否正确。主要查看MTDPARTS_DEFAULT和CONFIG_BOOTARGS这两个宏的配置是否正确,MTDPARTS_DEFAULT是设置默认分区的,CONFIG_BOOTARGS是u-boot传递给内核的启动参数的设置,如果这两个宏的设置不正确,内核就无法找到UBI文件系统所在的分区,就无法挂载文件系统。OK,我来说说当时我遇到过的几个错误吧。
1.分区设置与CONFIG_BOOTARGS中指定的分区不一致,导致错误,如下图所示:
这个错误是我当初的一时疏忽,以为mtd设备分区号是从1开始的,其实mtd设备的分区号是从0开始的。所以这里应该改成ubi.mtd = 3。
2.分区卷名和CONFIG_BOOTARGS中设置的卷名不一样导致错误,如图所示:
这个错误是由于当初我是修改别人的u-boot,忘记别人在设置分区的时候,UBI文件系统的分区的卷名为rootfs,而我在设置启动参数的时候设置成了ubifs。这里要么去改ubi分区的卷名为ubifs,要么改BOOTARGTS启动参数的设备名字为rootfs。两种修改都可以。
3.分区卷名太长,导致无法被识别,如图所示:
这个错误时分区名字太长导致的,具体想去研究这个错误的读者,可以自行阅读有关ubi文件系统挂载的函数,追踪u-boot/fs/ubifs/super.c目录下的open_ubi()打开ubi设备的这个函数,看看这个函数是如何根据传入的分区字符串的卷名去打开相应的ubi设备的。