问题情况

       开发板在测试过程中出现多次(目前发现6次)重启后EMMC分区挂载失败问题,有些2个分区数据都丢失,有些只有1个分区数据丢失。偶现2次在不断电测试过程中出现了EMMC分区文件系统数据全部消失的情况。

问题现象

       出现问题后启动挂载分区失败,查看分区是存在的,如下图所示:

emmc 部分数据不能写读 emmc损坏原因_重启

       手动进行挂载,挂载失败:

emmc 部分数据不能写读 emmc损坏原因_重启_02

       尝试进行修复,修复失败:

emmc 部分数据不能写读 emmc损坏原因_文件系统_03

       查看分区表原始数据,2个分区数据正常:

emmc 部分数据不能写读 emmc损坏原因_数据_04

       查看文件系统原始数据,数据全部为0不正常:

emmc 部分数据不能写读 emmc损坏原因_emmc 部分数据不能写读_05

问题复现

       在启动脚本中添加对emmc分区目录不断写文件,并在写的过程中硬件断电反复进行测试,测试3天没有复现。

       不断电进行读写文件反复测试,测试7天没有复现出问题。

问题分析

       现象分析,出现问题后分区数据正常,但是分区中文件系统数据和用户数据全部被清空,导致启动后不能识别到文件系统挂载失败,下面进行问题的分析。

  1. 用户使用什么方式可以达到清空全部数据效果。
  2. rm命令删除全部文件,这只会删除用户数据而不会破坏文件系统数据,排除。
  3. mtd erase命令擦除,mtd命令只对MTD设备有效对EMMC设备无效,排除。
  4. dd if=/dev/zero of=/dev/mmcblk1p1,这样确实可以达到清除文件系统数据和用户数据。在已经挂载的情况下执行上面命令后,挂载依然存在,但是读写文件会马上报如下错误打印:

emmc 部分数据不能写读 emmc损坏原因_文件系统_06

          重启后分区挂载失败,修复也失败,因为已经把超级块破坏。

          没有查找到启动脚本和用户脚本用dd命令对emmc设备的操作,排除。

  1. 检查格式化、挂载、修复参数是否异常。
  2. 格式化参数

emmc 部分数据不能写读 emmc损坏原因_重启_07

       -c 格式化前检查坏块,没有问题。

       -E lazy_itable_init=0,lazy_journal_init=0     关闭惰性初始化,在格式化时进行相应初始化,不必在挂载时初始化节约挂载时间。

       -T largefile 存储大文件,默认文件16K,大文件是1M,需要看场景中主要存储什么文件,存储大文件才能使用此参数,否则会限制文件个数导致创建文件失败的风险。

  1. 挂载参数

         -t ext4    文件系统类型。

       -rw 以读写,默认就是这样的。

       -o inode_readahead_blks=4096,调整预读索引表块大小,默认是32,调整为4096,测试后可以看到IO吞吐量得到极大提升。   

  1. 修复参数

      

emmc 部分数据不能写读 emmc损坏原因_重启_08

       -f  强制检查,Force checking even if filesystem is marked clean

       -p 自动修复,不需要询问和选择,有什么风险?Automatic repair (no questions)

       -c 检查坏块,Check for bad blocks and add them to the badblock list

       -v 输出详细信息,Be verbose

       参数暂无发现异常。

  1. 驱动配置有无异常

       EMMC硬件版本是4.51,驱动中配置无异常:

      

emmc 部分数据不能写读 emmc损坏原因_emmc 部分数据不能写读_09

       驱动代码也是支持4.5版本的:

      

emmc 部分数据不能写读 emmc损坏原因_文件系统_10

  1. dts表配置有无异常

       emmc配置,没有发现异常。

      

emmc 部分数据不能写读 emmc损坏原因_重启_11

      

emmc 部分数据不能写读 emmc损坏原因_文件系统_12

  1. 手动拉低RST_n管脚

       测试手动拉低RST_n管脚是否对emmc读写和数据有影响。

      

emmc 部分数据不能写读 emmc损坏原因_文件系统_13

       焊接引线出来接在GND,开机启动挂载和读写数据都没有影响,看emmc手册描述,没有使用到RST_n输入管脚,实际上是用CMD0命令来让emmc进行复位进入idle状态:

      

emmc 部分数据不能写读 emmc损坏原因_重启_14

       结论:所以RST_n管脚对读写和数据没有影响。

  1. 手动发送CMD42命令

       看网上一篇文章说emmc设备支持CMD42命令设置密码和加锁,在忘记密码的情况下可以进行强制清除密码并解锁,但强行清除会清除用户数据,不会清除boot和rpmb分区数据,下面进行验证:

       在uboot中增加mmc lock、unlock、force_clear命令,分别实现加锁解锁和强制清除功能。emmc加锁后读返回失败状态,执行强制清除后能正常读,但是删除了emmc的2个分区,分区中的文件系统数据和用户数据都被清除。

       结论:手动发送CMD42命令进行强制清除会把分区都删除,恢复成出厂的状态;但是我们出现问题的情况是分区还在,但文件系统数据和用户数据被清除。且在uboot和内核中没有地方调用CMD42命令,所以排除CMD42的影响。

  1. 查看出问题盒子的测试前后几天打印

       通过查看保留的串口和SSH打印,可知盒子在12月10日突然出现emmc两个分区没有文件系统数据,查看打印可知此前没有做任何危害emmc设备的操作命令。通过查看车牌得知盒子是在石家庄过标的设备,12月10日调换了设备,所以出现问题的第一现场不在张*位置。怀疑是在很早之前就已经出现问题,只是使用过程中没有发现问题。

  1. 排查公司现有福田盒子哪些emmc没有挂载成功

        排查了7台盒子,发现尹*的盒子也出现了没有挂载情况,有2个分区却没有文件系统数据,查看/mnt/emmc目录下文件时间日期,是工厂生产的日期,很大可能是工厂生产后emmc就没有挂载成功,因为里面的文件数据后面一直没有更新。用自己的盒子,删除2个分区重启进行分区和格式化,在格式化时断电,很大概率出现了第2分区格式化失败,和遇到的问题现象相似。

问题原因

       盒子第一次上电启动系统时,对emmc分区后格式化时(分区后格式化前有2秒延时)断电会很大概率出现格式化失败情况,会导致第二次启动时检测已经有分区就不会进行格式化文件系统的问题。

问题优化

       emmc挂载优化框图:

emmc 部分数据不能写读 emmc损坏原因_emmc 部分数据不能写读_15

问题总结

       emmc挂载脚本的不健壮和容错性差原因导致,应该多考虑异常情况,多画流程图。