はじめに
2021-03-25 Yocto リードオンリーなルートファイルシステムを構築するでリードオンリーなシステムの構築方法をまとめたが、情報が古くなってきたのでまとめ直す。
ターゲットボードはラズベリーパイ4、使用するYoctoProjectのバージョンはkirkstone(4.0)とする。
環境構築
作業環境
$ mkdir -p ~/yocto/rpi-kirkstone $ cd ~/yocto/rpi-kirkstone
pokyの取得
$ git clone -b kirkstone git://git.yoctoproject.org/poky.git
環境変数の設定
$ source poky/oe-init-build-env
レイヤの取得
$ bitbake-layers layerindex-fetch meta-raspberrypi
local.confを編集
conf/local.conf
に下記の部分を追加
MACHINE = "raspberrypi4-64" DL_DIR = "${TOPDIR}/../downloads" # systemd DISTRO_FEATURES:append = " systemd" VIRTUAL-RUNTIME_init_manager = "systemd" DISTRO_FEATURES_BACKFILL_CONSIDERED = "sysvinit" VIRTUAL-RUNTIME_initscripts = "" # enable uart ENABLE_UART = "1"
overlayfs.bbclassとoverlayfs-etc.bbclassはinitがsystemdでないと使用できない。
リードオンリーなルートFS
local.conf
などのconfファイルで指定する場合は下記のようにする。
EXTRA_IMAGE_FEATURES += "read-only-rootfs"
core-image-minimal.bbappendなどを作成してレシピから指定する場合は下記のようにする。
IMAGE_FEATURES += "read-only-rootfs"
書き込み可能ディレクトリの追加
kirkstoneからoverlayfs.bbclass
とoverlayfs-etc.bbclass
が追加されており、簡単に書き込み可能ディレクトリを定義できるようになっている。
下記の2つで使用するクラスが異なる。
- /etc以外の任意の場所を書き込み可能にしたい場合
- /etcを書き込み可能にしたい場合
書き込みパーティションの追加
wksの作成
既存のwksファイルをベースに新しくwksを作成し書き込み可能なパーティションを追加する。
$ bitbake-layers create-layer meta-work $ bitbake-layers add-layer meta-work $ mkdir meta-work/wic
meta-work/wic/sdimg-raspberrypi-overlay.wks
を次の内容で作成する。
part /boot --source bootimg-partition --ondisk mmcblk0 --fstype=vfat --label boot --active --align 4096 --size 20 part / --source rootfs --ondisk mmcblk0 --fstype=ext4 --label root --align 4096 --size 2048 part /data --ondisk mmcblk0 --fstype=ext4 --label data --fixed-size 20
local.confに下記を追加
WKS_FILE="sdimg-raspberrypi-overlay.wks"
マウントポイントの作成
$ recipetool newappend meta-work core-image-base
作成されたmeta-work/recipes-core/images/core-image-base.bbappend
に下記の内容を記述する。
create_data_dir() { mkdir -p ${IMAGE_ROOTFS}/data } ROOTFS_PREPROCESS_COMMAND += "create_data_dir;"
/etc以外の任意の場所を書き込み可能にしたい場合
overlayfs.bbclassを使用する。
overlayfs使用のためのレシピ
レシピ格納用のディレクトリを作成
$ mkdir meta-work/recipes-example/overlay
meta-work/recipes-example/overlay/overlay-dirs.bb
を下記の内容で作成する。
inherit features_check overlayfs REQUIRED_DISTRO_FEATURES = "systemd overlayfs" OVERLAYFS_WRITABLE_PATHS[data] += "/home/root" OVERLAYFS_WRITABLE_PATHS[data] += "/usr/share/my-application" do_install() { install -d ${D}/home/root install -d ${D}/usr/share/my-application } FILES:${PN} += "/home" FILES:${PN} += "/usr"
1つのマウントポイントに対して複数のディレクトリ指定できる。
local.confの設定
local.conf
に下記の内容を追記する。
DISTRO_FEATURES:append = " overlayfs" # This has to be done in your machine configuration: OVERLAYFS_MOUNT_POINT[data] = "/data" OVERLAYFS_QA_SKIP[data] = "mount-configured" IMAGE_INSTALL:append = "overlay-dirs"
OVERLAYFS_MOUNT_POINT
は本来、MACHINE定義のconfファイルで定義するべきらしい。
マウントポイントのQAチェック(mountユニットとfstabを確認している)はdo_rootfsで実行されるが、
今回ので手順では/data
がマウントポイントであることがfstabに反映されるタイミングがdo_image_wicタスク実行後なので、
OVERLAYFS_QA_SKIP
が必要となる。
overlay-dirsパッケージをイメージに追加し、overlayするディレクトリをルートFSに反映する。
データが揮発してもOKな場合
confに下記のように追記して、揮発する領域を指すこともできる。
OVERLAYFS_MOUNT_POINT[var-volatile] = "/var/volatile"
この場合、meta-work/recipes-example/overlay/overlay-dirs.bb
を
下記のようにすると保存したデータが電源をオフする毎に消えるようになる。
inherit features_check overlayfs REQUIRED_DISTRO_FEATURES = "systemd overlayfs" OVERLAYFS_WRITABLE_PATHS[var-volatile] += "/home/root" OVERLAYFS_WRITABLE_PATHS[var-volatile] += "/usr/share/my-application" do_install() { install -d ${D}/home/root install -d ${D}/usr/share/my-application } FILES:${PN} += "/home" FILES:${PN} += "/usr"
このレシピを変更した場合は下記のように一度cleansstateしないとルートFSに反映されないことがある。。
$ bitbake overlay-dirs -c cleansstate $ bitbake core-image-base -c cleansstate $ bitbake core-image-base
/etcを書き込み可能にしたい場合
overlayfs-etc.bbclassを使用する。
overlayfs-etcの使い方
overlayfs-etc.bbclassは直接inheritしてはダメで、イメージレシピの中でIMAGE_FEATURESにoverlayfs-etc
を追加する。
具体的には、core-image-minimal.bbappendなどを作成して下記のようにする。
IMAGE_FEATURES += "overlayfs-etc"
local.confなどでEXTRA_IMAGE_FEATURESに追加することもできない。
local.confの設定
これらは本来、MACHINE定義のconfファイルで定義するべきらしい。
OVERLAYFS_ETC_MOUNT_POINT = "/data" OVERLAYFS_ETC_DEVICE = "/dev/mmcblk0p3" OVERLAYFS_ETC_FSTYPE = "ext4"
OVERLAYFS_ETC_DEVICE
はOVERLAYFS_ETC_MOUNT_POINT
としてマウントされる読み書き可能なパーティションを設定する。
今回の手順では、sdimg-raspberrypi-overlay.wksで定義した第3パーティションの情報を設定すればOKとなる。
ちなみに、OVERLAYFS_ETC_MOUNT_POINTとOVERLAYFS_MOUNT_POINTは同じ場所を指しても問題ない。今回はどちらも/data
を指している。
こちらはoverlayfs.bbclassと異なりtmpfsなどの揮発する領域を指すことはできないようだ。
まとめ
kirkstoneからはoverlayfs.bbclass、overlayfs-etc.bbclassが導入された。 どちらもsystemdに依存するため、sysvinitでは使用できない。
使い方については、マニュアルも言葉足らずだし、実例の紹介などが少ないため若干解りづらい気がした。 しかし一度、理解できると柔軟にいろいろなケースで書き込み領域をオーバーレイすることができるため、便利。
組み込み機器では求められがちなリードオンリーなルートFSとは切っても切れないオーバーレイについては、 かなり利便性は向上したのではないだろうか。