我的任务是在嵌入式设备上运行 Linux 作为操作系统。
目标具有 x86 处理器和 8 GB CompactFlash 存储设备。
我已经成功地使用 buildroot 来创建内核映像和交叉编译工具。我已将 CF 设备分区为一个小的 FAT 分区,其中包含内核映像以及syslinux
引导配置和ext3
文件系统,我将 buildroot 生成的根文件系统解压到其中。
syslinux
通过将根目录设置为我的buildroot文件系统所在的CF ext3分区,系统可以成功启动。
我的问题集中在面对立即(和频繁)断电时的鲁棒性需求,因为断电后设备成功启动至关重要。我读到,将根文件系统安装为只读是确保数据完整性的一种方法。这对我来说是一个明智的继续方式吗?
我还了解了将根文件系统加载到 RAM 中以实现相同目的的可能性,但目前还不知道如何做到这一点。
是否有实现此目标的首选方法?如果有,我继续前进的最佳方法是什么?
答案1
新答案 (2015-03-22)
(笔记:这个答案比以前更简单,但并不更安全。我的第一个答案更强,因为你可以保存文件只读经过文件系统挂载选项 前权限标志。所以强迫未经许可写入文件根本不起作用。)
它使用aufs
(默认情况下,但可以使用其他unionfs
工具)来允许实时会话更改但默认情况下在 RAM 中,因此重启时一切都会被忘记。
您可以通过简单地运行以下命令来安装它们:
apt-get install fsprotect
完成后,从在线文档:
在那之后:
- 编辑
/boot/grub/menu.lst
或/etc/default/grub2
或/etc/lilo.conf
并将“fsprotect=1G
”添加到内核参数中。- 根据需要修改1G。
- 应用更改(即运行
update-grub
)- 如果
/etc/default/fsprotect
您想保护/
.- 重启
您可能还想用密码保护 grub 引导加载程序或禁止对其进行任何更改。
从那里开始,如果某些文件受到保护以防止更改,例如
chmod ugo-w myfile
如果您使用示例vi myfile
并尝试使用命令在其上写入:w!
,这将起作用并且您的内容 myfile
会发生变化。您可以重新启动以检索未修改的myfile
.
我的以下第一个解决方案甚至不可能做到这一点:
旧的(第一个)答案:
是的,这是一个强大的解决方案,而且功能强大!
让 r/o 可用
您必须安装一些目录读写,喜欢/var
,/etc
也许/home
。这可以通过使用完成奥夫斯或者联盟。我喜欢这个其他方式,使用/dev/shm
和mount --bind
:
cp -a /var /dev/shm/
mount --bind /dev/shm/var /var
您之前可以将在正常操作中无需更改的所有目录移动到 a 中static-var
,而不是在 /var 中创建符号链接:
mkdir /static-var
mkdir /static-var/cache
mkdir /static-var/lib
mv /var/lib/dpkg /static-var/lib/dpkg
ln -s /static-var/lib/dpkg /var/lib/dpkg
mv /var/cache/apt /static-var/cache/apt
ln -s /static-var/cache/apt /var/cache/apt
... # an so on
因此,在 ro 中重新挂载时,复制/var
不会/dev/shm
占用太多空间,因为大多数文件都会移动到/static-var
ram 中,并且只复制符号链接。
精细地做到这一点的更好方法是进行一次完整的电源循环,一天的完整工作,并精细地运行如下命令:
find / -type f -o -type f -mtime -1
因此您将看到哪些文件需要位于读写分区上。
记录
由于该主机不存在可写静态内存,为了存储历史记录和其他日志,您必须配置远程syslog
服务器。
echo >/etc/syslog.conf '*.* @mySyslogServer.localdomain'
这样,如果您的系统因任何原因崩溃,之前的所有内容都会被记录下来。
升级中
当运行某些mount --bind
正在使用的系统时,为了在系统正在使用时进行此类升级(无需运行init 1
,以减少停机时间),更简单的方法是重新构建一个干净的系统根,可以进行升级:
重新挂载'/'后读写模式:
mount -o remount,rw /
for mpnt in /{,proc,sys,dev{,/pts}};do
mount --bind $mnpt /$mnt$mpnt;
done
chroot /mnt
apt-get update && apt-get dist-upgrade
exit
umount /mnt/{dev{/pts,},proc,sys,}
sync
mount -o remount,ro /
现在:
shutdown -r now
答案2
我只有使用更新的 buildroot (2014-02) 的经验。在该版本中,您可以在配置文件中禁用“启动时重新挂载根文件系统读写”:
BR2_TARGET_GENERIC_REMOUNT_ROOTFS_RW 未设置
我设法创建了一个仅将其 ext4/分区用作只读的映像,因此拔掉系统电源根本不会造成任何损害。它工作得很好,所以如果你不需要写入你的文件系统,也许这是一个比上面提到的更简单的解决方案(这似乎或多或少适用于 Debian 系统,因为它指的是 apt-get)。