使用Squashfs和Overlayfs提高嵌入式Linux文件系統可靠性【轉】

轉自:https://blog.csdn.net/toradexsh/article/details/109737842

By Toradex胡珊逢

 

在使用嵌入式 Linux 系統的時,會出現由於設備意外斷電引起文件系統損壞而最終使該設備無法啓動的現象。爲了應對這種情況,通常會從硬件設計如採用備用電源,無論是鋰電池還是超級電容等,或者從系統軟件設上加以規避。本文接下來將介紹如何使用 squashfs 只讀文件系統製作 Linux 系統文件,並採用 overlayfs 爲用戶目錄增加可寫權限。演示採用 Colibri iMX6 計算機模塊,該方法同樣也適用於 Toradex 其他產品,如 iMX8 計算機模塊。

 

Squashfs 是一種只讀壓縮文件系統,通常被用於數據備份或者系統資源受限的計算機系統上使用,如 Linux 發行版的 LiveCD,OpenWRT 系統也採用 squashfs。OverlayFS 一個結合其他文件系統的聯合掛載,將多個掛載點疊加爲一個目錄。常見的應用是在一個只讀的分區上疊加可讀寫的另一個分區。嵌入式 Linux 設備通常的功能都是被設計好的,極少需要在後期安裝其他軟件或更改 Linux 系統軟件,更多的是更新設備應用程序和相關數據。因此基於 squashfs 的只讀文件系統,結合 overlayfs 爲用戶應用和數據提供讀寫操作,能夠提高嵌入式 Linux 文件系統可靠性。

 

在 Colibri iMX6 的 eMMC 上我們將使用以下分區規劃。BootFS 爲 FAT32 格式,該分區上包含 Linux 內核文件,device tree 等啓動文件,如果是 iMX8,則還包含一些其他固件文件。該分區通常只在文件系統燒寫階段被寫入。RootFS 分區是 Linux 運行的文件系統,usr, bin, lib, etc, home 等目錄都在上面。一般該分區是EXT3,EXT4 格式,支持文件的寫入和刪除。而文件系統的損壞也常發生於此,最終導致設備啓動失敗。因此我們這裏會採用只讀格式的 squashfs 。UserData 是能夠讀寫的 EXT4 分區。該分區通過 overlayfs 會被掛載到原本位於只讀 squashfs  中的 /home/root 目錄。用戶應用可以毫無察覺得使用該目錄,在上面寫入和刪除文件,但不破壞只讀 squashfs 文件系統,所有的操作都會被轉移到 UserData 分區上。用戶的應用也會存在 UserData 分區上,啓動的時候從這裏加載應用程序。該分區是可寫的,所有這上面的文件是可以被更新。

image001.png

下面我們會具體說明如何在 Yocto 環境生成符合上面規劃的 BSP ,並通過 Toradex Easy Installer 工具實現這些分區和寫入文件。

 

首先需要在 Yocto 環境中生成 squashfs 格式的系統文件 rootfs。修改 build/conf/local.conf ,結尾添加以下內容。

------------------------------------

IMAGE_FSTYPES_append = " squashfs"

------------------------------------

 

默認 Linux 內核配置下 squahfs 是通過加載內核驅動模塊實現對其支持,而模塊驅動文件位於 rootfs 中,爲了保證 Linux 內核在啓動時能夠正確處理該格式,需要將 squahfs 內核驅動模塊配置爲靜態驅動,直接編譯進內核中。爲內核配置的文件系統支持添加 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 分區會通過 overlay 機制掛載到只讀的 rootfs 上的 /home/root,但這之前需要通過 fstab 將該分區掛載到系統中,/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

------------------------------------

 

然後再添加一個開機自啓動腳本,將  /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 目錄中創建 data 文件夾,FILES_${PN} = "/media/data" 將該空文件夾添加到 BSP 中。 mount-overlayfs.service 通過 RequiresMountsFor 保證 /media/data 目錄通過 fstab 掛載後才運行。Overlay 的目錄結構如下,lowerdir 爲/home/root upperdir 爲 /media/data/home/root/upper,workdir 爲 /media/data/home/root/work。這樣應用可以在 /home/root 下直接讀寫文件,overlayfs 對應用和用戶都是透明的。

------------------------------------

[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 是隻讀格式,無法像之前一樣直接在開發板上運行 systemctl 命令添加開機自啓動腳本。我們需要像上面一樣,在 Yocto 中增加一個 test-app 來開機自動運行位於 UserData 分區(該分區通過 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"

------------------------------------

 

至此我們已經通過修改 Yocto 能夠生成所需結構的BSP,執行下面命令完成編譯任務。

------------------------------------

$ MACHINE=colibri-imx6 bitbake tdx-reference-minimal-image

------------------------------------

 

在 build/deploy/images/colibri-imx6 有相關文件生成,我們需要下面兩個文件,文件名字中的時間戳對應具體編譯的日期。

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。因爲rootfs 是 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 參數。

------------------------------------

env set emmcargs_set 'env set rootfsargs root=/dev/mmcblk0p2 rootfstype=squashfs ro rootwait'

------------------------------------

 

可以使用該 boot.cmd 直接生成對應的 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 文件系統複製到 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

------------------------------------

 

接下來創建需要複製到 UserData 分區中的文件。如上面提到的 overlay 掛載需要有對應目錄結構,依次創建以下目錄,並將測試程序 test 複製到 upper 目錄中。這裏的測試程序 test 是一個非常簡單的 C 應用,它會輸出“Hello Toradex!”到系統日誌中。

------------------------------------

$ 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

------------------------------------

image002.png

 

打包爲 rootfs.tar.xz。

------------------------------------

$ cd ..

$ sudo tar cJf rootfs.tar.xz -C rootfs .

------------------------------------

 

修改 image.json 文件,在blockdevs 中增加 RAW 格式分區用於直接寫入 squashfs 系統文件,以及 EXT4 格式的DATA分區用於寫入上面生成的 rootfs.tar.xz。

image003.png

 

Colibri-iMX6_Reference-Minimal-Image-Tezi_5.1.0-devel-20201112022057+build.0 目錄下最終包含以下文件。

image004.png

將上面的 BSP 通過 Toradex Easy Installer 重新安裝到 Colibri iMX6 上,安裝的時候注意需要點擊 Erase 擦除 eMMC 上的內容。

 

燒寫後重啓模塊。可以通過 mount 命令查看掛載分區的情況。

------------------------------------

[email protected]:~# 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 只讀文件系統的分區,例如在 /etc 目錄無法創建文件。

------------------------------------

[email protected]:/etc# mkdir test-folder

mkdir: can't create directory 'test-folder': Read-only file system

------------------------------------

 

EXT4 格式的 /dev/mmcblk0p3 分區上是用戶文件,被掛載到 /media/data。而 /home/root 會通過 overlay 具有可讀寫權限。

------------------------------------

[email protected]:~# cd ~/

[email protected]:~# pwd

/home/root

[email protected]:~# mkdir test-folder

[email protected]:~# ls

test         test-folder

[email protected]:~# 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  也在開機的時候自動運行。

------------------------------------

[email protected]:~# 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.

------------------------------------

 

 

總結

上面我們演示結合使用 squashfs 和 overlay,將系統文件放在一個只讀分區,把讀寫操作在單獨的分區上進行。降低系統文件因意外斷電受損從而導致無法啓動的風險。在使用只讀 squashfs 只讀文件系統時需要保證 rootfs 儘量精簡,建議在 Reference-Minimal-Image 基礎上構建用戶自己的 BSP,甚至對其進行裁剪。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章