问题描述

环境:

Linux内核版本 ---- 2.6.15.7;采用的flash类型 ---- nor flash;arm通过spi去操作该flash。

现象

设备的data分区用于保存掉电需要存放的数据,采用ext2文件系统,rcs启动脚本中采用mount -o sync /dev/mtdblkdata /data的方式进行挂载,这样只要这个data分区有数据的改变,都会马上写入到flash上。但是因为是同步写的方式,所以假如tftp一个100多k的文件到data分区,需要写的时间很久,这样就会导致播放的视频持续卡顿,且如果这时候断电,很容易就会导致etx2文件系崩溃;因为它正在往data分区写文件,可能在写superblock块,但是这时候掉电,superblock块损坏就无法恢复了。
上电的时候会采用e2fsck工具进行data分区的检测,只要superblock没有损坏,那么就还能够进行修复,只是那个写一半的文件会不存在。
在这里插入图片描述
如果superblock块损坏的话,就会无法修复,如下图:
在这里插入图片描述
出现这种情况,该分区已经损坏了,无法挂载也无法再被修复,只能通过重新刷分区的方式,把分区刷新为ext2文件系统;

文件系统基础知识

Ext

全称Linux extended file system, extfs,即Linux扩展文件系统,Ext2就代表第二代文件扩展系统,Ext3/Ext4以此类推,它们都是Ext2的升级版,只不过为了快速恢复文件系统,减少一致性检查的时间,增加了日志功能,所以Ext2被称为索引式文件系统,而Ext3/Ext4被称为日志式文件系统。

核心设计

数据存放区

在这里插入图片描述

中介数据

在这里插入图片描述

inode的作用

在这里插入图片描述

解决方案

上述问题,如果出现在写文件的过程中掉电,就有可能再也无法保存配置文件了。这是ext2文件系统的弊端,目前来看是无法解决的。所以考虑换文件系统,采用ext3日志型文件系统;现在ubuntu上编译好ext3文件系统,编译命令如下:

dd if=/dev/zero of=myext3 bs=1k count=4096
sudo losetup /dev/loop15 ./myext3
sudo mkfs.ext3 /dev/loop15
file myext3
losetup -f可以查看哪个磁盘是空闲的

这样就创建出来了一个ext3的文件系统;然后把它tftp到板子上,先umount /data分区;然后把myext3 dd到mtdblkdata设备下,然后再mount 到data分区,这样data分区就是ext3文件系统了;并且e2fsck是可以通用与ext2、ext3、ext4这些文件系统。
现在文件系统已经是ext3了,那就继续对它进行暴力测试,采取-o sync挂载的方式,然后tftp文件到data分区,因为是sync同步写的方式,所以会卡主不动等待写完成,这时候进行掉电的操作,然后再上电,tftp文件。。。反复测试几轮,看文件系统是否会损坏。结果出现如下图:
在这里插入图片描述
在这里插入图片描述
有几个目录已经不能操控了,也就是打不开,也删除不了,大概就是保存了这个目录的名字信息,但是对应的block块找不到了,所以删除不了也不能对它进行操作,重新上电之后也还是这样。这种时候可以采用e2fsck -f强制进行修复,这样就会把这些文件信息给删除掉,然后上电的时候就变成默认值了。所以如果采用ext3文件系统,写过程异常掉电也是有可能产生破损文件,但是可以被e2fsck工具给修复,所以在rcs脚本中需要加上e2fsck -f来检查一遍ext3文件系统清除破损的文件。
由于ext3是日志型文件系统,所以当tftp一个文件到该系统下时,写入的时间会比ext2慢一些,因为需要写一些日志来保存信息。

更换为ext3后,工厂批量大规模生产,贴片前烧录flash,仍然发现有不良的情况,不能够保存数据。

先看下报错信息:
在这里插入图片描述
跟ext2的报错信息时一样的,仍然是超级块损坏,找不到对应的块了;不是说超级块都有备份的吗,为啥还是会损坏呢。查看data.ext3文件系统的信息。
在这里插入图片描述
发现它只有一个超级块;并没有备份信息,当这个超级块损坏了,也是一样会导致起不来。那么能否自己制作一个超级块的备份信息呢?
使用如下命令制作出有两个group组的超级块备份:
mkfs.ext3 -b 1024 -g 2048 loop.img
在这里插入图片描述
-b表示block size的大小,有1K、2K、4K;-g指定每个块组含有多少block。如上图可以看到有一个超级块的备份块,在2049这个block上;当主超级块损坏的时候,就可以让它手动去寻找备份超级块的信息。
含有备份超级块的文件系统做好了,下一步就是需要复现与工厂一样的现象,也就是把超级块给搞死;那么应该如何做到呢?Ext3文件系统超级块中38H~39H偏移处有两个字节的固定签名值,为十六进制数值“53 EF”
在这里插入图片描述
那么只要往这个块里写入0就可以了;dd if=/dev/zero of=/dev/mtdblkdata seek=1079 bs=1 count=20,然后重启,果然就出现了上述的错误,超级块损坏。根据它的提示信息,是可以用e2fsck工具进行修复的。
在这里插入图片描述
输入命令试试:e2fsck -b 2049 /dev/mtdblkdata -y
发现是能修复成功的
在这里插入图片描述

OK,问题解决。

Logo

更多推荐