嵌入式Linux系统在运行时,除了小概率的因突然断电等非正常关机造成的文件系统损坏之外,更大概率的是因为应用程序编程不当,造成对Nandflash的频繁擦写,行业术语称之为 过度编程(Over Program) ,逼近Nandflash约十万次的擦写寿命,表现为Nandflash的某些块/页陆续出现位反转(bit flip,所谓位反转,指的是原先Nandflash中存储的某个数据位变化了,即要么从1变成了0,要么从0变成了1)的现象,少量的位反转是可以靠硬件/软件ECC(Error Checking and Correction,错误检查和纠正)算法自纠过来的,但大量的位反转超出ECC的纠正能力之后,会导致文件系统数据损坏,严重时会导致系统崩溃,终端运行不起来。
对于大规模量产的终端设备而言,这种问题一旦发生,往往不是升级下应用程序就能解决的,因为底层存储器件的寿命已到,必需要更换硬件才行,这会给公司带来大量的人力、物力及财力消耗,公司产品口碑也会受到影响,后果是非常严重的。
然而现实中,采用嵌入式Linux系统的应用程序,其代码规模一般都不会很小,少则几万十几万行,多则几十上百万行,想要快速找到应用程序中对文件写操作比较频繁的地方,犹如大海捞针。这种情况下,寻找一种快速有效的方法,协助我们研发人员快速定位问题所在,将有问题的应用程序在家里提前暴露出来,不要流到现场等着问题去爆发,就显得尤为重要。
Linux内核从2.6.13版本起,加入了inotify特性,这是一种文件系统的变化通知机制,通过inotify可以监控文件系统中添加、删除、修改,移动等各种文件操作,当事件发生时可及时发出相关的事件警告。利用这个内核接口,第三方软件就可以监控文件系统下文件的各种变化情况。
具体实施方式
以嵌入式Linux系统常用的ubi文件系统为例,具体步骤如下:
步骤1: 观察内核启动时挂载ubi文件系统时的打印信息,或者在系统正常运行过程中随时输入ubinfo命令,查看目前文件系统对Nandflash闪存的最大擦写次数。
ubinfo -d 0
ubi0
Volumes count: 1
Logical eraseblock size: 126976 bytes, 124.0 KiB
Total amount of logical eraseblocks: 400 (50790400 bytes, 48.4 MiB)
Amount of available logical eraseblocks: 0 (0 bytes)
Maximum count of volumes 128
Count of bad physical eraseblocks: 0
Count of reserved physical eraseblocks: 8
Current maximum erase counter value: 36864
Minimum input/output unit size: 2048 bytes
Character device major/minor: 251:0
Present volumes: 0
步骤2: 正常如果应用程序没有过度编程的话,上面显示的最大擦写次数(Current maximum erase counter value)一般不会很大,如果看到这种几万次的擦写次数,或者短时间内这个最大擦写次数增长比较快,说明应用程序中应该有过度编程的情况,这时我们可以借助Linux系统中的文件操作监控工具inotify协助定位。
步骤3: 在inotify的站点下载inotify-tools监控工具源代码,这里以版本inotify-tools-3.13.tar.gz为例。
步骤4: 由于嵌入式Linux系统一般运行在ARM平台上,需要将上面下载的源代码进行交叉编译(cross-compiling,所谓交叉编译,就是在一种平台上编译,编译出来的程序,放到别的平台上运行,即编译环境和运行环境不一样,这个概念主要和嵌入式开发有关,一般是在x86平台上编译,在ARM平台上运行),生成inotifywait、inotifywatch可执行程序及运行时需要的库文件。
make CC=arm-none-linux-gnueabi-gcc
步骤5: 将交叉编译后生成的inotifywait、inotifywatch可执行程序上传到嵌入式Linux设备的/sbin目录下,并修改可执行权限。
chmod 755 inotifywait
chmod 755 inotifywatch
步骤6: 将交叉编译后生成的库文件libinotifytools.so.0.4.1上传到嵌入式Linux设备的/lib目录下,并在/lib目录下建立符号链接。
ln -s libinotifytools.so.0.4.1 libinotifytools.so.0
步骤7: 执行如下命令即可启动对文件操作的监听。
inotifywait -mrq --timefmt '%y/%m/%d %H:%M' --format '%T %w %f %e' -e modify,delete,create,attrib --exclude 'ptmx|pts|ttyS*' /
其中:
--timefmt选项用于控制打印出来的时间格式,这里采用了“年/月/日 时:分”的格式。
--exclude选项用于剔除过滤不需要监控的文件名称,支持通配符*过滤。
-e选项用于注册要监听的文件操作事件。
步骤8: 这时应该就可以看到inotify打印的监听到的文件操作,根据打印信息再到代码里面去搜索对应的文件操作,便可以很容易定位。
全部0条评论
快来发表一下你的评论吧 !