UBI文件系统遇到的问题

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.

UBI文件系统遇到的问题_第1张图片

遇到这种错误,一般是由于你的分区设置不正确导致的。可以到u-boot/include/configs/xxx.h相应的板子配置文件下去查看自己的分区设置是否正确。主要查看MTDPARTS_DEFAULT和CONFIG_BOOTARGS这两个宏的配置是否正确,MTDPARTS_DEFAULT是设置默认分区的,CONFIG_BOOTARGS是u-boot传递给内核的启动参数的设置,如果这两个宏的设置不正确,内核就无法找到UBI文件系统所在的分区,就无法挂载文件系统。OK,我来说说当时我遇到过的几个错误吧。

1.分区设置与CONFIG_BOOTARGS中指定的分区不一致,导致错误,如下图所示:

UBI文件系统遇到的问题_第2张图片

这个错误是我当初的一时疏忽,以为mtd设备分区号是从1开始的,其实mtd设备的分区号是从0开始的。所以这里应该改成ubi.mtd = 3。

2.分区卷名和CONFIG_BOOTARGS中设置的卷名不一样导致错误,如图所示:

UBI文件系统遇到的问题_第3张图片

这个错误是由于当初我是修改别人的u-boot,忘记别人在设置分区的时候,UBI文件系统的分区的卷名为rootfs,而我在设置启动参数的时候设置成了ubifs。这里要么去改ubi分区的卷名为ubifs,要么改BOOTARGTS启动参数的设备名字为rootfs。两种修改都可以。

3.分区卷名太长,导致无法被识别,如图所示:

UBI文件系统遇到的问题_第4张图片

这个错误时分区名字太长导致的,具体想去研究这个错误的读者,可以自行阅读有关ubi文件系统挂载的函数,追踪u-boot/fs/ubifs/super.c目录下的open_ubi()打开ubi设备的这个函数,看看这个函数是如何根据传入的分区字符串的卷名去打开相应的ubi设备的。

你可能感兴趣的:(Linux,Uboot)