在使用嵌入式?Linux?系統(tǒng)的時(shí),會出現(xiàn)由于設(shè)備意外斷電引起文件系統(tǒng)損壞而最終使該設(shè)備無法啟動的現(xiàn)象。為了應(yīng)對這種情況,通常會從硬件設(shè)計(jì)如采用備用電源,無論是鋰電池還是超級電容等,或者從系統(tǒng)軟件設(shè)上加以規(guī)避。本文接下來將介紹如何使用?squashfs?只讀文件系統(tǒng)制作?Linux?系統(tǒng)文件,并采用?overlayfs?為用戶目錄增加可寫權(quán)限。演示采用?Colibri iMX6?計(jì)算機(jī)模塊,該方法同樣也適用于?Toradex?其他產(chǎn)品,如?iMX8?計(jì)算機(jī)模塊。
Squashfs?是一種只讀壓縮文件系統(tǒng),通常被用于數(shù)據(jù)備份或者系統(tǒng)資源受限的計(jì)算機(jī)系統(tǒng)上使用,如?Linux?發(fā)行版的?LiveCD,OpenWRT?系統(tǒng)也采用?squashfs。OverlayFS?一個(gè)結(jié)合其他文件系統(tǒng)的聯(lián)合掛載,將多個(gè)掛載點(diǎn)疊加為一個(gè)目錄。常見的應(yīng)用是在一個(gè)只讀的分區(qū)上疊加可讀寫的另一個(gè)分區(qū)。嵌入式?Linux?設(shè)備通常的功能都是被設(shè)計(jì)好的,極少需要在后期安裝其他軟件或更改?Linux?系統(tǒng)軟件,更多的是更新設(shè)備應(yīng)用程序和相關(guān)數(shù)據(jù)。因此基于?squashfs?的只讀文件系統(tǒng),結(jié)合?overlayfs?為用戶應(yīng)用和數(shù)據(jù)提供讀寫操作,能夠提高嵌入式?Linux?文件系統(tǒng)可靠性。
在?Colibri iMX6?的?eMMC?上我們將使用以下分區(qū)規(guī)劃。BootFS?為?FAT32?格式,該分區(qū)上包含?Linux?內(nèi)核文件,device tree?等啟動文件,如果是?iMX8,則還包含一些其他固件文件。該分區(qū)通常只在文件系統(tǒng)燒寫階段被寫入。RootFS?分區(qū)是?Linux?運(yùn)行的文件系統(tǒng),usr, bin, lib, etc, home?等目錄都在上面。一般該分區(qū)是EXT3,EXT4?格式,支持文件的寫入和刪除。而文件系統(tǒng)的損壞也常發(fā)生于此,最終導(dǎo)致設(shè)備啟動失敗。因此我們這里會采用只讀格式的?squashfs?。UserData?是能夠讀寫的?EXT4?分區(qū)。該分區(qū)通過?overlayfs?會被掛載到原本位于只讀?squashfs??中的?/home/root?目錄。用戶應(yīng)用可以毫無察覺得使用該目錄,在上面寫入和刪除文件,但不破壞只讀?squashfs?文件系統(tǒng),所有的操作都會被轉(zhuǎn)移到?UserData?分區(qū)上。用戶的應(yīng)用也會存在?UserData?分區(qū)上,啟動的時(shí)候從這里加載應(yīng)用程序。該分區(qū)是可寫的,所有這上面的文件是可以被更新。
下面我們會具體說明如何在?Yocto?環(huán)境生成符合上面規(guī)劃的?BSP?,并通過?Toradex Easy Installer?工具實(shí)現(xiàn)這些分區(qū)和寫入文件。
首先需要在?Yocto?環(huán)境中生成?squashfs?格式的系統(tǒng)文件?rootfs。修改?build/conf/local.conf?,結(jié)尾添加以下內(nèi)容。
------------------------------------
IMAGE_FSTYPES_append = " squashfs"
------------------------------------
默認(rèn)?Linux?內(nèi)核配置下?squahfs?是通過加載內(nèi)核驅(qū)動模塊實(shí)現(xiàn)對其支持,而模塊驅(qū)動文件位于?rootfs?中,為了保證?Linux?內(nèi)核在啟動時(shí)能夠正確處理該格式,需要將?squahfs?內(nèi)核驅(qū)動模塊配置為靜態(tài)驅(qū)動,直接編譯進(jìn)內(nèi)核中。為內(nèi)核配置的文件系統(tǒng)支持添加?squahfs?和?overlay?格式。
------------------------------------
$ MACHINE=colibri-imx6 bitbake -c menuconfig virtual/kernel
→?File systems
<*> Overlay filesystem support
→?File systems?→?Miscellaneous filesystems
<*>?? SquashFS 4.0 - Squashed file system support?
------------------------------------
EXT4?格式的?UserData?分區(qū)會通過?overlay?機(jī)制掛載到只讀的?rootfs?上的?/home/root,但這之前需要通過?fstab?將該分區(qū)掛載到系統(tǒng)中,/dev/mmcblk0p3 -> /media/data-> /home/root。在?Yocto?中,layers/meta-toradex-demos/recipes-core/base-files/base-files/fstab?會被編譯到?Colibri IMX6 BSP?中,在該文件中添加:
------------------------------------
/dev/mmcblk0p3?????? /media/data???????? auto?????? defaults,sync,noauto? 0? 0
------------------------------------
然后再添加一個(gè)開機(jī)自啟動腳本,將??/media/data?使用?overlay掛載到?/home/root。?在?layers/meta-toradex-bsp-common/recipes-core目錄中添加?mount-overlayfs?文件夾,里面包含編譯需要的?bb?文件和?systemd service。mount-overlayfs.bb?中?install -d ${D}/media/data?會在?/media?目錄中創(chuàng)建?data?文件夾,F(xiàn)ILES_${PN} = "/media/data"?將該空文件夾添加到?BSP?中。?mount-overlayfs.service?通過?RequiresMountsFor?保證?/media/data?目錄通過?fstab?掛載后才運(yùn)行。Overlay?的目錄結(jié)構(gòu)如下,lowerdir?為/home/root upperdir?為?/media/data/home/root/upper,workdir?為?/media/data/home/root/work。這樣應(yīng)用可以在?/home/root?下直接讀寫文件,overlayfs?對應(yīng)用和用戶都是透明的。
------------------------------------
[Service]
Type=simple
ExecStart=/bin/sh -c 'mount -t overlay -o lowerdir=/home/root,upperdir=/media/data/home/root/upper,workdir=/media/data/home/root/work overlay /home/root'
------------------------------------
在?build/conf/local.conf?中將?mount-overlayfs?添加到?BSP?中。
------------------------------------
IMAGE_INSTALL_append = " mount-overlayfs"
------------------------------------
由于?rootfs?是只讀格式,無法像之前一樣直接在開發(fā)板上運(yùn)行?systemctl?命令添加開機(jī)自啟動腳本。我們需要像上面一樣,在?Yocto?中增加一個(gè)?test-app?來開機(jī)自動運(yùn)行位于?UserData?分區(qū)(該分區(qū)通過?overlay?會被最終掛載到?/home/root?目錄)上的測試程序?test。在?layers/meta-toradex-bsp-common/recipes-core目錄中添加?test-app?文件夾,里面包含編譯需要的?bb?文件和?systemd service。
在?build/conf/local.conf?中將?test-app?添加到?BSP?中。
------------------------------------
IMAGE_INSTALL_append = " mount-overlayfs test-app"
------------------------------------
至此我們已經(jīng)通過修改?Yocto?能夠生成所需結(jié)構(gòu)的BSP,執(zhí)行下面命令完成編譯任務(wù)。
------------------------------------
$ MACHINE=colibri-imx6 bitbake tdx-reference-minimal-image
------------------------------------
在?build/deploy/images/colibri-imx6?有相關(guān)文件生成,我們需要下面兩個(gè)文件,文件名字中的時(shí)間戳對應(yīng)具體編譯的日期。
Colibri-iMX6_Reference-Minimal-Image-Tezi_5.1.0-devel-20201112022057+build.0.tar
Colibri-iMX6_Reference-Minimal-Image.rootfs.squashfs
解壓?Colibri-iMX6_Reference-Minimal-Image-Tezi_5.1.0-devel-20201112022057+build.0.tar。因?yàn)閞ootfs?是?squahfs?格式,需要使用定制的?boot.src?來啟動。
------------------------------------
$ cd ~/
$ tar vxf Colibri-iMX6_Reference-Minimal-Image-Tezi_5.1.0-devel-20201112022057+build.0.tar
$ cd Colibri-iMX6_Reference-Minimal-Image-Tezi_5.1.0-devel-20201112022057+build.0
$ tar vxf Reference-Minimal-Image-colibri-imx6.bootfs.tar.xz
------------------------------------
修改其中的?emmcargs_set?參數(shù)。
------------------------------------
env set emmcargs_set 'env set rootfsargs root=/dev/mmcblk0p2 rootfstype=squashfs ro rootwait'
------------------------------------
可以使用該?boot.cmd?直接生成對應(yīng)的?boot.src,?替換解壓目錄中同名文件,?重新打包?Reference-Minimal-Image-colibri-imx6.bootfs.tar.xz
------------------------------------
$ cd Reference-Minimal-Image-colibri-imx6.bootfs
$ rm boot.src
$ mkimage -A arm -O linux -T script -C none -a 0 -e 0 -n "Distro boot script" -d boot.cmd boot.scr
$ cd ..
$ tar cJf Reference-Minimal-Image-colibri-imx6.bootfs.tar.xz -C Reference-Minimal-Image-colibri-imx6.bootfs .
------------------------------------
將?squashfs?的?rootfs?文件系統(tǒng)復(fù)制到?Colibri-iMX6_Reference-Minimal-Image-Tezi_5.1.0-devel-20201112022057+build.0?目錄中。
------------------------------------
$ cp Colibri-iMX6_Reference-Minimal-Image.rootfs.squashfs Colibri-iMX6_Reference-Minimal-Image-Tezi_5.1.0-devel-20201112022057+build.0
------------------------------------
接下來創(chuàng)建需要復(fù)制到?UserData?分區(qū)中的文件。如上面提到的?overlay?掛載需要有對應(yīng)目錄結(jié)構(gòu),依次創(chuàng)建以下目錄,并將測試程序?test?復(fù)制到?upper?目錄中。這里的測試程序?test?是一個(gè)非常簡單的?C?應(yīng)用,它會輸出“Hello Toradex!”到系統(tǒng)日志中。
------------------------------------
$ cd ~/Colibri-iMX6_Reference-Minimal-Image-Tezi_5.1.0-devel-20201112022057+build.0
$ mkdir rootfs
$ cd rootfs
$ mkdir -p home/root/upper
$ mkdir -p home/root/work
$ cp ~/test home/root/upper
$ tree
------------------------------------
打包為?rootfs.tar.xz。
------------------------------------
$ cd ..
$ sudo tar cJf rootfs.tar.xz -C rootfs .
------------------------------------
修改?image.json?文件,在blockdevs?中增加?RAW?格式分區(qū)用于直接寫入?squashfs?系統(tǒng)文件,以及?EXT4?格式的DATA分區(qū)用于寫入上面生成的?rootfs.tar.xz。
Colibri-iMX6_Reference-Minimal-Image-Tezi_5.1.0-devel-20201112022057+build.0?目錄下最終包含以下文件。
將上面的?BSP?通過?Toradex Easy Installer?重新安裝到?Colibri iMX6?上,安裝的時(shí)候注意需要點(diǎn)擊?Erase?擦除?eMMC?上的內(nèi)容。
燒寫后重啟模塊??梢酝ㄟ^?mount?命令查看掛載分區(qū)的情況。
------------------------------------
root@colibri-imx6:~# mount
/dev/mmcblk0p2 on / type squashfs (ro,noatime)
……
/dev/mmcblk0p3 on /media/data type ext4 (rw,relatime,sync)
overlay on /home/root type overlay (rw,relatime,lowerdir=/home/root,upperdir=/media/data/home/root/upper,workdir=/media/data/home/root/work)
------------------------------------
mmcblk0p2?為寫入?squashfs?只讀文件系統(tǒng)的分區(qū),例如在?/etc?目錄無法創(chuàng)建文件。
------------------------------------
root@colibri-imx6:/etc# mkdir test-folder
mkdir: can't create directory 'test-folder': Read-only file system
------------------------------------
EXT4?格式的?/dev/mmcblk0p3?分區(qū)上是用戶文件,被掛載到?/media/data。而?/home/root?會通過?overlay?具有可讀寫權(quán)限。
------------------------------------
root@colibri-imx6:~# cd ~/
root@colibri-imx6:~# pwd
/home/root
root@colibri-imx6:~# mkdir test-folder
root@colibri-imx6:~# ls
test???????? test-folder
root@colibri-imx6:~# ls -lh
-rwxrwxr-x??? 1 1000???? 1000?????? 11.3K Nov 11? 2020 test
drwxr-xr-x??? 2 root???? root??????? 4.0K Feb? 7 16:25 test-folder
------------------------------------
位于?UserData?上的測試程序?test??也在開機(jī)的時(shí)候自動運(yùn)行。
------------------------------------
root@colibri-imx6:~# journalctl -u test-app
-- Logs begin at Fri 2020-02-07 15:50:53 UTC, end at Fri 2020-02-07 16:11:49 UTC. --
Feb 07 15:50:57 colibri-imx6 systemd[1]: Started start a demo on overlay mount folder.
Feb 07 15:50:57 colibri-imx6 test[456]: Hello Toradex!
Feb 07 15:50:57 colibri-imx6 systemd[1]: test-app.service: Succeeded.
------------------------------------
總結(jié)
上面我們演示結(jié)合使用?squashfs?和?overlay,將系統(tǒng)文件放在一個(gè)只讀分區(qū),把讀寫操作在單獨(dú)的分區(qū)上進(jìn)行。降低系統(tǒng)文件因意外斷電受損從而導(dǎo)致無法啟動的風(fēng)險(xiǎn)。在使用只讀?squashfs?只讀文件系統(tǒng)時(shí)需要保證?rootfs?盡量精簡,建議在?Reference-Minimal-Image?基礎(chǔ)上構(gòu)建用戶自己的?BSP,甚至對其進(jìn)行裁剪。
審核編輯:黃飛
評論
查看更多