【全志A33】解决文件系统错误

这个平板第一次开机就给我了一个惊喜,文件系统不可写,WTF,这还玩啥。但是查了一下内核日志,发现这事不简单~~~

内核日志

[    1.690765] EXT4-fs (nandd): barriers disabled
[    1.698331] EXT4-fs (nandd): mounted filesystem with ordered data mode. Opts: noauto_da_alloc,barrier=0,data=ordered
[    6.190083] EXT4-fs error (device nandd): ext4_init_inode_table:1116: comm ext4lazyinit: Something is wrong with group 0: used itable blocks: 427; itable unused count: 0
[    6.213432] EXT4-fs (nandd): Remounting filesystem read-only
[    6.219880] EXT4-fs error (device nandd) in ext4_init_inode_table:1160: IO failure

很明显,是ext4_init_inode_table这个函数报了错“comm ext4lazyinit: Something is wrong with group 0: used itable blocks: 427; itable unused count: 0”,然后内核强行把文件系统重新挂载成只读的了。因为我们是将文件系统做成镜像然后直接烧写进nand的,我首先怀疑是制作的文件系统镜像有问题。

文件系统制作过程

在执行./build.sh之后,文件系统编译流程如下,

Created with Raphaël 2.1.2 ./build.sh ./build.sh mkcommon.sh mkcommon.sh mkcmd.sh mkcmd.sh build.sh build.sh mkcommon.sh $@ buildroot/scripts/ mklichee mkrootfs buildroot/target/dragonboard/

所以最终的文件系统的制作过程发生在buildroot/target/dragonboard/build.sh里面。其中最核心的就是下面两行代码

make_ext4fs -l $NEW_NR_SIZE"M" $TARGET_IMAGE rootfs/
fsck.ext4 -y $TARGET_IMAGE > /dev/null
echo "success in generating rootfs"

熟悉安卓系统开发的人对make_ext4fs一定很熟悉,这是安卓用来制作根文件系统的工具,当然,它也可以用来制作linux的根文件系统,问题是这个根文件系统的制作过程看不出有什么错误。

一个不完美的解决方式

既然根文件系统镜像的制作没问题,假设烧写也没有问题,那么问题只可能出在nand flash本身了,如果nand flash有坏块,那么的确有可能出现这个问题。
那么回到问题本身,内核日志显示,是ext4_init_inode_table:1116这里报了问题,那么就去内核源码里看一下代码到底在做什么。

if ((used_blks < 0) || (used_blks > sbi->s_itb_per_group)) {
        ext4_error(sb, "Something is wrong with group %u: "
                   "used itable blocks: %d; "
                   "itable unused count: %u",
                   group, used_blks,
                   ext4_itable_unused_count(sb, gdp));
        ret = 1; 
        goto err_out;
}

结合日志,我们发现这里used_blks是427,因此是因为(used_blks > sbi->s_itb_per_group)这个条件进入分支的,那么这两个比较的值肯定有错误,由于sbi->s_itb_per_group是一个属性值,是在格式化的时候就确定了,因此可以大体判定used_blks是错误的,这里有一种可能性比较大的假设是nand flash本身存在坏块,但是烧录工具在烧写的时候并没有跳过这些坏块,因此系统启动后文件系统结构被损坏。

因为我不需要向根文件系统频繁写入大量数据,所以这里我选择接受这个错误,但要求内核不能将文件系统挂载为只读,解决方式就是把ext4_error这个函数注释掉。

重新编译内核,这时根文件系统已经是可写的了,我也尝试做了简单的压力测试,并没有出现宕机的情况,所以可以认为文件系统的结构的损坏程度完全处于可接受的状态。

你可能感兴趣的:(全志A33,嵌入式)