みつきんのメモ

組み込みエンジニアです。Interface誌で「Yocto Projectではじめる 組み込みLinux開発入門」連載中

meta-st-stm32mpでの「正しい」wicイメージの作り方

はじめに

YoctoProject STM32MP157F-DK2を試すで下記のようなエラーに遭遇した。

| wic.filemap.error: cannot open image file '/home/mickey/yocto/stm32mp15-kirkstone/build/tmp/deploy/images/stm32mp1/st-image-bootfs-poky-stm32mp1.ext4': [errno 2] no such file or directory: '/home/mickey/yocto/stm32mp15-kirkstone/build/tmp/deploy/images/stm32mp1/st-image-bootfs-poky-stm32mp1.ext4'
| warning: exit code 1 from a shell command.
error: task (/home/mickey/yocto/stm32mp15-kirkstone/poky/meta-st-stm32mp/recipes-st/images/st-image-userfs.bb:do_image_wic) failed with exit code '1'

その解決方法として、各パーティション向けのイメージで下記のフラグを指定した。

do_image_wic[noexec] = "1"

この方法でプルリクエストを作成したが下記のような返事があり、却下された。

Hello, The right way to add wic image is to use this variable: meta-st-stm32mp/conf/machine/include/st-machine-common-stm32mp.inc:WKS_IMAGE_FSTYPES ?= ""

By the way, we think ST implementation is not robust and we will add some additional checks to avoid this issue. So we don't think your patch is the right way to solve (but is doing the job). Anyway, thanks a lot to have pointed on this weakness.

正しい方法も教えてくれた。

それによると、WKS_IMAGE_FSTYPESを使用することが正解らしい。この変数はmeta-st-stm32mp/conf/machine/include/st-machine-common-stm32mp.incで定義されている。つまりmeta-st-stm32mp独自の変数となるため、YoctoProjectとしての一般的な方法では無い。

WKS_IMAGE_FSTYPEのメカニズムについて調査してみる。

実装の調査

WKS_IMAGE_FSTYPESの参照箇所

WKS_IMAGE_FSTYPESが使用されている箇所をgrepしてみる。

$ grep -r 'WKS_IMAGE_FSTYPES' .
./meta-st-stm32mp/recipes-st/images/st-image-partitions.inc:IMAGE_FSTYPES:remove = "${WKS_IMAGE_FSTYPES}"
./meta-st-stm32mp/conf/machine/stm32mp13-disco.conf:#WKS_IMAGE_FSTYPES += "wic wic.bz2 wic.bmap"
./meta-st-stm32mp/conf/machine/stm32mp15-disco.conf:#WKS_IMAGE_FSTYPES += "wic wic.bz2 wic.bmap"
./meta-st-stm32mp/conf/machine/stm32mp15-eval.conf:#WKS_IMAGE_FSTYPES += "wic wic.bz2 wic.bmap"
./meta-st-stm32mp/conf/machine/include/st-machine-common-stm32mp.inc:WKS_IMAGE_FSTYPES ?= ""
./meta-st-stm32mp/conf/machine/include/st-machine-common-stm32mp.inc:IMAGE_FSTYPES ?= "${WKS_IMAGE_FSTYPES} tar.xz"

注目するべきは下記の2つのファイル

  • st-machine-common-stm32mp.inc
  • st-image-partitions.inc

st-machine-common-stm32mp.inc

st-machine-common-stm32mp.incの参照箇所は以下の通り。

$ grep -r 'st-machine-common-stm32mp.inc' .
./meta-st-stm32mp/conf/machine/stm32mp13-disco.conf:include conf/machine/include/st-machine-common-stm32mp.inc
./meta-st-stm32mp/conf/machine/stm32mp1.conf:include conf/machine/include/st-machine-common-stm32mp.inc
./meta-st-stm32mp/conf/machine/stm32mp15-disco.conf:include conf/machine/include/st-machine-common-stm32mp.inc
./meta-st-stm32mp/conf/machine/stm32mp15-eval.conf:include conf/machine/include/st-machine-common-stm32mp.inc

MACHINE定義の中から参照される。

その中でWKS_IMAGE_FSTYPESは次のように使用されている。

# Default FSTYPES requested
WKS_IMAGE_FSTYPES ?= ""
IMAGE_FSTYPES ?= "${WKS_IMAGE_FSTYPES} tar.xz"

WKS_IMAGE_FSTYPESに"wic"関連のタイプを追加することでIMAGE_FSTYPESにそれらが追加されwicイメージが出力されるようになる。

st-image-partitions.inc

YoctoProject STM32MP157F-DK2を試すでは、次の3つのレシピにbbappendを作成した。

  • st-image-userfs.bb
  • st-image-bootfs.bb
  • st-image-vendorfs.bb

これらはcore-imageをinheritしており、イメージファイルを出力するためのタスクが実装されている。当然IMAGE_FSTYPESも参照する。

st-image-partitions.incはこれら3つのレシピ全てからincludeされている。つまりこのファイルを修正するとこれら3つのレシピに影響が出る。

WKS_IMAGE_FSTYPESはst-image-partitions.incの中で次のように使用されている。

# Remove WIC image generation for the partition image
IMAGE_FSTYPES:remove = "${WKS_IMAGE_FSTYPES}"

上記3つのイメージレシピのIMAGE_FSTYPESからWKS_IMAGE_FSTYPESで定義したwic関連のタイプを削除している。 このようにすることで、循環参照を避けwicイメージを出力している。

WKS_IMAGE_FSTYPESの役割

ここまでで、WKS_IMAGE_FSTYPESは次の2つの役割を持っていることがわかる。

  1. wicイメージを出力させるためのトリガ
  2. 循環参照を避けるためのフィルタ

この実装について

メンテナのコメント

プルリクエストでメンテナであるBernardPuelさんは次のようにコメントしている。

The right way to add wic image is to use this variable: meta-st-stm32mp/conf/machine/include/st-machine-common-stm32mp.inc:WKS_IMAGE_FSTYPES ?= ""

By the way, we think ST implementation is not robust and we will add some additional checks to avoid this issue.

「現状の実装としてはWKS_IMAGE_FSTYPESを使用することが正しい解決方法だが、この実装もロバスト(堅牢)ではない。 今回のような問題を避けるためにチェックを追加するつもりだ」とのこと。

So we don't think your patch is the right way to solve (but is doing the job).

「あなたのパッチも正しい解決方法ではないと考えている」らしい。

現実装の問題点

WKS_IMAGE_FSTYPESを使った実装の問題点はいくつかある。

  1. WKS_IMAGE_FSTYPESが独自の変数であること
    1. マニュアルなどから見つけづらい
    2. YoctoProjectの一般的な方法ではない(IMAGE_FSTYPESだけで解決できない)
  2. WKS_IMAGE_FSTYPESの実装が煩雑であること
    1. 1つの変数に2つの役割(トリガ・フィルタ)を持たせている
    2. コードに対して機能が直感的に理解できない

自分の実装にこだわるつもりは無いが、WKS_IMAGE_FSTYPESはできれば撤廃してほしい。

まとめ

  • 現状はWKS_IMAGE_FSTYPESを使用することが正解
  • メンテナも現状のままでは問題があることは認識している
  • WKS_IMAGE_FSTYPESは撤廃してほしい(チェックを追加するって言ってるので撤廃されない可能性が高い気がする)

(おまけ)使用方法

作業環境

$ mkdir -p ~/yocto/stm32mp15-kirkstone
$ cd ~/yocto/stm32mp15-kirkstone

pokyの取得

$ git clone -b kirkstone git://git.yoctoproject.org/poky.git

環境変数の設定

$ source poky/oe-init-build-env

meta-openembeddedの取得

$ bitbake-layers layerindex-fetch meta-python

meta-st-stm32mpの取得

$ pushd ../poky
$ git clone https://github.com/STMicroelectronics/meta-st-stm32mp.git -b kirkstone
$ popd
$ bitbake-layers add-layer ../poky/meta-st-stm32mp

local.confの修正

MACHINE ?= "stm32mp1"

WKS_IMAGE_FSTYPES:append = " wic.bz2 wic.bmap"
WKS_FILE = "sdcard-stm32mp157f-dk2-optee-1GB.wks.in"

ビルド

$ bitbake core-image-minimal