在embedded式Linux上安全地写入压缩闪存

我正在开发一个从Compact Flash和tmpfs运行的embedded式Linux系统。 闪存安装为只读,通常应该保持这种方式,但偶尔我需要写一些东西到闪存。

在写入闪存(通过PATA接口)时应采取哪些预防措施? 由于我不记得的原因,我正在使用一个ext4文件系统安装barrier=1,data=ordered,nodelalloc,noatime,ro这是一个可怕的想法? 系统需要快速启动,无需干预。 我很想做tune2fs -c 0 -i 0 。 这是一个更糟糕的主意?

另外,当我写东西的时候,我显然需要重新挂载flash读写,执行写操作,然后重新挂载只读。 问题是有几个不同的进程(包括c ++二进制和shell脚本)可能需要这样做。 显然,每个进程在完成后不加区分地重新挂载文件系统是一个坏主意。

协调这个最好的方法是什么? flock看起来很有希望; 这是最好的方式,我需要担心什么? 我不想要一个陈旧的锁来阻止写入或使文件系统无限期地写入。

澄清:通过“偶尔”写作,我的意思是这个系统可以多年不需要写任何东西。 当有东西写入时,可能是几百字节。 同时,系统需要忍受不可预知的电力周期,而无需任何干预。

使ext4安全

ext4对于这个并不是很理想。 最糟糕的情况是,当你的分区是RW并损坏文件系统时,电源会失效。

尽管它们是为原始NAND设备而设计的,但像jffs2或yaffs这样的日志文件系统可能仍然有用。 它们有一个有用的特性,即它们的磁盘格式看起来更像是一个列表而不是一棵树,所以更新的数据往往会被打包得更密切,从而不太可能垃圾文件系统的相对静态部分。

在这种情况下,我不能评论如何使“安全”。 文件系统结构和fsck都不知道闪存设备的常见故障模式(值得注意的是,在任何写入过程中,都有一段时间,整个数据块是无效的)。当然,这种行为对于CF卡,所以它不是非常可预测的。

我能想到的最安全和最可预测的方式是在较小的嵌入式设备中使用的倒装缓冲数据布局。 也就是说,你有两个可写区域(两个分区)。在任何给定的时间,至少有一个必须是一致的。 当你想写,选择两个较老的。 如果您启动并检测到缓冲区A中的不一致,请将缓冲区B的内容复制到(并且不允许在此期间向B写入数据)。

管理安装/重新安装

我将编写一个守护进程来代表系统上的所有进程管理卸载/重新安装。 这具有许多优点:

  • 你分开了umount / remount逻辑,只需要执行一次
  • 要写入的进程不需要root权限
  • 你可以建立一些看门狗,以确保该分区不会离开RW太长时间。 如果是这样,你可以杀死违规流程(可能回滚),并重新安装RO。
  • 您可以测量您安装RW的时间,这可以让您了解每次更新所涉及的风险

我做了一个嵌入式系统从一个4GB的CF卡运行。 我用3个分区进行设置:

  • /开机; EXT2; 〜128MB
  • 根; squashfs的; 500MB(因为不可写入,所以无意中将其写入写入模式)。
  • /数据; EXT2; 〜3.5GB我想要保存的任何数据

我使用的是ext2,因为我相信任何日记的FS实际上会导致更多的块被修改为每写。 在CF卡上运行Flash文件系统也没有意义,因为系统不能直接访问Flash块。 CF卡内部包含自己的块映射逻辑。

由于您使用的是CF,因此磨损均衡很可能是内置的,因此您将不会使用像yaffs2,jffs2等内置磨损均衡的文件系统。事实上,大多数磨损均衡文件系统对于内置磨损平衡的CF卡,您需要一个内置日志的文件系统,以便您可以安全地通过电源开关循环,而不会造成系统损坏。 有两种选择 – 选择带有日志记录的文件系统或选择db(假设写入是以db为中心的),并像sqlite一样进行磨损平衡。 对于文件系统,你可以使用ext3或者ext4,虽然我个人推荐使用ext3,因为ext4仍然有一些可以让你头疼的bug。 我也建议像其他人一样,有两个分区,一个是纯粹的只读使用文件系统如squashfs,cramfs和其他读写使用EXT3。

话虽如此,我不确定你的设备是否内置了EEPROM,但是如果它有,而且你只需要每隔几年写入几百个字节,最简单的配置就是使用一个带有EEPROM的只读文件系统作为你的数百个字节的数据区。

我会做一个单独的分区,安装rw。