Linux只读文件系统
By?Toradex?胡珊逢
1.?????簡介
文件系統對于嵌入式系統,正如記憶對于大腦,嵌入式系統失去了文件系統,這往往是嚴重的問題,輕則導致應用無法啟動,數據丟失,嚴重的情況可能是整個系統啟動失敗。Windows?電腦的藍屏、手機變磚,這其中很大比例是由于重要系統文件丟失、損壞所致。如何保護嵌入式文件系統的安全,這是系統開發人員打造一款穩定、可靠產品時應該考慮的事情。
損壞文件系統,除了外部因素如高壓、高溫、強磁場干擾存儲器外,寫文件系統那時的突然掉電往往會造成文件系統結構本身的損壞,例如分區信息。在?Linux?嵌入式系統常見的掛載?VFS?失敗就是由于rootfs?受損所致,而這之前的?U-Boot?和?Linux?kernel?往往任可以正常工作。文件針對此類情況,將介紹如何在?iMX6?平臺上,如何使用只讀文件系統,并將用戶應用和數據保存在獨立的分區,以及利用?Toradex?Easy?Installer?完成分區和系統安裝操作。
2.?????生成只讀文件系統
Yocto/OpenEmbedded?構建框架的一個特點是,系統軟件會根據所構建的目標鏡像的要求自動調整編譯軟件的功能。例如在?IMAGE_FEATURES?中添加?read-only-rootfs,那么?BSP?中包含的軟件將不會往?Flash上寫入文件,包括系統日志。
在?local.conf?配置
------------------------------------
EXTRA_IMAGE_FEATURES?=?"debug-tweakspackage-management?read-only-rootfs"
DISTRO_EXTRA_RDEPENDS_remove?=?"?angstrom-libc-fixup-hack"
------------------------------------
3.?????設置分區掛載
修改用戶分區掛載目錄
------------------------------------
layers/meta-toradex-demos/recipes-core/base-files/base-files/fstab
/dev/root???????????/???????????????????auto??????ro,noatime??????????????1??1
proc????????????????/proc???????????????proc??????defaults?????????????0??0
devpts??????????????/dev/pts????????????devpts?????mode=0620,gid=5???????0??0
usbdevfs????????????/proc/bus/usb????????usbdevfs???noauto???????????????0??0
tmpfs???????????????/run????????????????tmpfs??????mode=0755,nodev,nosuid,strictatime0??0
tmpfs???????????????/var/volatile????????tmpfs??????defaults?????????????0??0
#?uncomment?this?if?your?device?has?aSD/MMC/Transflash?slot
#/dev/mmcblk0p1??????/media/card?????????auto??????defaults,sync,noauto??0?0
/dev/mmcblk0p3???????/mnt?????????ext4??????defaults,sync,noauto??0?0
------------------------------------
將系統根目錄設置為只讀狀態,并將獨立的用戶分區掛載到?/mnt?目錄,該目錄任具有讀寫權限。用戶應用可以在該分區下保存用戶配置文件、應用日志,甚至升級用戶應用本身。
4.?????設置應用自啟動腳本
由于文件系統需要配置為只讀屬性,我們需要在?Yocto/OpenEmbedded?構建時直接包含應用開機啟動腳本。目前?Toradex?的?Linux?BSP?已經采用?systemd?啟動管理,用戶需要添加對應的?systemd?service?文件。為了方便演示,我們直接在?layers/meta-toradex-bsp-common/recipes-core/?目錄下創建用戶自己的recipe?文件,如?user-demo,當然你也可以在?Yocto/OpenEmbedded??根目錄中添加自己的??layer,將所需的?recipe?都包含進來,具體方法請參考這里。
------------------------------------
tdx_cn_ben@LinuxDevSH1:~/Toradex/OE/v2.7/layers/meta-toradex-bsp-common/recipes-core/user-demo$tree?-L?2
.
├──?files
│???└──?user-demo.service
└──?user-demo.bb
------------------------------------
user-demo.bb
------------------------------------
SUMMARY?=?"Add?user?demo"
DESCRIPTION?=?"create?folder?withinhome?and?install?auto-run?service?script"
LICENSE?=?"CLOSED"
PR?=?"r3"
SRC_URI?=??"?\
????file://user-demo.service?\
"
do_install?()?{
????install-m?0644?${WORKDIR}/user-demo.service?${D}${systemd_unitdir}/system
}
NATIVE_SYSTEMD_SUPPORT?=?"1"
SYSTEMD_PACKAGES?=?"${PN}"
SYSTEMD_SERVICE_${PN}?=?"user-demo.service"
inherit?allarch?systemd
------------------------------------
user-demo.service
------------------------------------
[Unit]
Description=launch?user's?demo?on?dedicatedpartition
ConditionFileIsExecutable=/mnt/helloworld
StartLimitIntervalSec=200
StartLimitBurst=5
After=multi-user.target
[Service]
Type=simple
ExecStart=/mnt/helloworld
Restart=on-failure
RestartSec=10
[Install]
WantedBy=multi-user.target
------------------------------------
啟動腳本中使用?ConditionFileIsExecutable來判斷用戶分區是否成功掛載并存在可執行文件,等待分區文件準備完成后才啟動,同時設置Restart?,當啟動失敗后會再次嘗試。
最后執行命令,生成用于?ToradexEasy?Installer?的安裝文件
------------------------------------
bitbake?console-tdx-image
------------------------------------
將下面文件復制到?SD?或者?U盤中
------------------------------------
├──?Colibri-iMX6_Console-Image.bootfs.tar.xz
├──Colibri-iMX6_Console-Image.rootfs.tar.xz
├──?image.json
├──?prepare.sh
├──?slides_vga
├──?SPL
├──?toradexlinux.png
├──?u-boot.imx
├──?userapp.tar.xz
└──?wrapup.sh
------------------------------------
5.?????修改?image.json?配置文件
Toradex?Easy?Installer?中的?image.json??文件可用于配置?iMX?6?模塊上?Flash?的分區情況,并將文件寫入對應的分區中。我們需要在?Flash?創建分區,存放用戶文件??userapp.tar.xz,并去掉?rootfs?分區??want_maximised屬性。
------------------------------------
{
???????????????????"want_maximised":?false,
???????????????????"content":?{
???????????????????????"mkfs_options":?"-E?nodiscard",
???????????????????????"filesystem_type":?"ext4",
???????????????????????"uncompressed_size":?140.03515625,
???????????????????????"filename":"Colibri-iMX6_Console-Image.rootfs.tar.xz",
???????????????????????"label":?"RFS"
???????????????????},
???????????????????"partition_size_nominal":?512
???????????????},
???????????????{
???????????????????"want_maximised":?true,
???????????????????"content":?{
???????????????????????"mkfs_options":?"-E?nodiscard",
???????????????????????"filesystem_type":?"ext4",
???????????????????????"uncompressed_size":?7.01,
???????????????????????"filename":?"userapp.tar.xz",
???????????????????????"label":?"UserData"
???????????????????},
???????????????????"partition_size_nominal":?512
??????}
------------------------------------
userapp.tar.xz?壓縮包中包含了用戶文件,如?helloworld和?taq.mp4,直接將其壓縮成?xz?格式即可。
6.?????用戶應用
由于用戶應用存放在獨立的分區上,因此并不需要將其集成到??Yocto/OpenEmbedded,借助?Toradex?Easy?Installer?可以直接將程序、數據等寫入分區。以下面應用為例,應用將打印“Hello?world!”,并在用戶分區上寫如數據文件。該應用由上面的?user-demo.service?腳本在開機時啟動。
------------------------------------
int?main(int?argc,char?*argv[]){
?int?file_hd;
?unsigned?chardata[16]={0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f};
?file_hd?=?open?("/mnt/log-file",O_CREAT?|O_WRONLY?|?O_TRUNC);
?if(file_hd==-1)
?{
??????printf("filecreate?failed");
??????return?-1;
?}
?write?(file_hd,(unsigned?char?*)data,?16);
?close(file_hd);
?printf("Hello?world!\n");
?return?0;
}
------------------------------------
7.?????測試文件系統
查看掛載情況
------------------------------------
root@colibri-imx6:/etc/udev/rules.d#?mount?-l
/dev/mmcblk0p2?on?/?type?ext4?(ro,noatime,data=ordered)?[RFS]
……?
/dev/mmcblk0p3?on?/media/mmcblk0p3?typeext4?(rw,relatime,data=ordered)[UserData]
------------------------------------
在只讀文件系統上無法創建目錄
------------------------------------
root@colibri-imx6:~#?pwd
/home/root
root@colibri-imx6:~#?mkdirtestfolder
mkdir:?can't?create?directory?'testfolder':Read-only?file?system
------------------------------------
UserData?分區下的用戶文件
------------------------------------
root@colibri-imx6:/media/mmcblk0p3#?ls
helloworld??????lost+found???????taq.mp4
------------------------------------
應用啟動情況
------------------------------------
root@colibri-imx6:~#?journalctl-u?user-demo.service
--?Logs?begin?at?Wed?2018-03-07?04:48:18UTC,?end?at?Mon?2018-03-12?08:30:56?UTC.?--
Mar?12?08:30:51?colibri-imx6?systemd[1]:Started?launch?user's?demo?on?dedicated?partition.
Mar?12?08:30:51?colibri-imx6?helloworld[522]:Hello?world!
root@colibri-imx6:~#?hexdump-b?/mnt/log-file?
0000000?000?001?002?003?004?005?006?007?010011?012?013?014?015?016?017
0000010
------------------------------------
8.?????總結
通過將?rootfs?設置為只讀模式,用戶的寫操作只縮小到一個單獨分區,可以降低由于?rootfs?損壞導致系統啟動失敗的發生。只讀模式的?rootfs?也會帶來其他影響,有些文件是在系統運行時必須創建或者更新的,如密碼、random?seed、SSH?Keys、網絡配置參數等。這些文件的缺失使得系統無法保存之前的配置,每次使用時都需重新建立。以上只是一個簡單的說明,如何使用只讀文件系統提高系統穩定性。用戶也可以將應用直接集成到?BSP?中,當用戶分區上的文件損壞或者丟失時,可以將其用作備份恢復。甚至采用額外的存儲介質,實現系統恢復、A/B?分區、OTA?等其他功能。
總結
以上是生活随笔為你收集整理的Linux只读文件系统的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: CentOS7.4下安装Oracle 1
- 下一篇: Linux删除只读文件系统