新千葉 ガーベージ・コレクション

FPGA マガジンやインターフェースで書けなかったこと等をちょぼちょぼ書いてます。@ryos36

Yocto での deploy の順番

Yocto のタスクの順番。
たとえば deploy

addtask deploy before do_build after do_compile

となっている。rootfs も

addtask rootfs before do_build

となっている。自分の recipe の中でこれと矛盾する記述を書くと bitbake 時にエラーとなる。

addtask deploy after do_build <=矛盾した記述

ERROR: Task /home/ryos/Yocto/meta-sby-zynq/recipes-bsp/zynq-boot-bin/zynq-boot-bin_1.0.bb (do_deploy) has circular dependency on /home/ryos/Yocto/meta-sby-zynq/recipes-bsp/zynq-boot-bin/zynq-boot-bin_1.0.bb (do_build)

さて、ここで問題になるのが SDCARD を作る順番。なぜか、fsl の SD カードはイメージを作る延長でやっている。DEPENEDS に(指定の方法はいくつかあるみたいだが、、、、)

IMAGE_DEPENDS_sdcard = "parted-native dosfstools-native mtools-native \
                        virtual/kernel ${IMAGE_BOOTLOADER} linux-xlnx"

や RDEPENDS に書くなどとにかく、依存関係を書いておき、IMAGE_CMD_sdcard を記述しておき、そのうえで IMAGE_CLASSES += "自分のクラス" と IMAGE_FSTYPES = "tar.gz ext4 sdcard" と書けば、自分のクラスにある IMAGE_CMD_sdcard が実行される。

しかし、ここでちょっと疑問。IMAGE_CMD_sdcard 関数で BB_CURRENTTASK が何になっているかを調べると、rootfs であることがわかった。fsl で sdcard を作るときは、たとえば core-image-minimal の rootfs の延長で作られる。依存関係が u-boot と linux にあるいとはいえ、単純に rootfs を実行するとエラーになることがある。

zynq と fsl がこの blog ではごちゃごちゃだが、、、、構わず情報だけを上げるとエラーは次のようになる。

|   mcopy -i /opt/Yocto/rootfs_builder/build/tmp/work/imx6qsabresd-poky-linux-gnueabi/core-image-minimal/1.0-r0/boot.img -s /opt/Yocto/rootfs_builder/build/tmp/deploy/images/imx6qsabresd/uImage-imx6qsabresd.bin ::/uImage
| ERROR: Function failed: do_rootfs (log file is located at /opt/Yocto/rootfs_builder/build/tmp/work/imx6qsabresd-poky-linux-gnueabi/core-image-minimal/1.0-r0/temp/log.do_rootfs.22289)
ERROR: Task 6 (/opt/Yocto/rootfs_builder/sources/poky/meta/recipes-core/images/core-image-minimal.bb, do_rootfs) failed with exit code '1'

これは bitbake core-image-minimal -c rootfs した結果。uImage がないと言われている。つまり core-image-minimal の rootfs の延長で呼ばれる sdcard を作る関数では、deploy ディレクトリに uImage そして uboot.bin があることが前提になっている。

一方、linux の recipe では build すると uImage が deploy のディレクトリにできる。u-boot も build でできる。本当は core-image-minimal の rootfs は linux と u-boot の build に依存しているのだが、その記述をする方法が Yocto にはある(後述)。

bitbake core-image-minimal とすると、依存関係上 u-boot と linux が先に呼ばれて、u-boot と linux がbuild まで実行される。それで、偶然(?) core-image-minimal は rootfs がうまくいく。

したがって、個別に実行すると、依存関係が破たんしてエラーになる。たとえば、いったん u-boot と linux を clean する。これで deploy 先のディレクトリからオブジェクトが消える。さらに bitbake core-image-minimal -c rootfs すれば、bitbake は依存関係上 u-boot と linux の rootfs までは実行するが、rootfs は build より前のタスクなので、build までしない。その結果、linux と u-boot のコンパイルはなされるが、残念ながら deploy のディレクトリに何も置かれない。そして、core-image-minimal の rootfs でエラーとなる。

どうも、特定の依存関係を

do_build[depends] += "virtual/kernel:do_deploy"

のように設定できるらしい。
だからこの場合は

do_rootfs[depends] += "linux-xlnx:do_build"
do_rootfs[depends] += "u-boot-xlnx:do_build"

としないといけないみたいな気がする。
EXTRA_IMAGEDEPENDS かも。

やっぱりそうでした。この2つを追加したところうまくいき始めた。つまり fsl の sdcard の記述の問題だな。でも意味的には rootfs のところで image を作るのはおかしいので、fsl の sdcard 作成の設計の問題ともいえる。
do_build はいらないかも。

bitbake いろいろ出来すぎて全体を把握することは難しいぞ。きっとそういうつかいかたをするんじゃなくて、えいやー!できた!とやるんだろうな。恐ろしい。

あといろいろやってわかったこと

xxo_deploy_append () {

見たな関数を書くと Yocto は使ってもいないのに反応してしまう。したがって _append _prepend みたいな関数名は事実上予約語になる。
あと、いまのところどうやっても、os.environ['BUILDDIR']; がとれない。
やりたいことは BUILDDIR の下のローカルなディレクトリがあったらそこからファイルをコピーしたいということだが、、、URL_SRC にファイルを書いておくと自動的に WORKDIR におかれれるので、それを利用する方がいいらしい。そのサーチパスは FILESEXTRAPATHS_append で指定すればよく、

FILESEXTRAPATHS_append = "${@os.environ["BUILDDIR"] + \"/mydir\"}"

みたいなことをしたいところだけど、なぜか今はできないので(できていいはずなのだが、、、PATHはとれたので)、直接 FILESEXTRAPATHS_append に書いておくのだろう。

でもって、あとでわかったことだけど、こういう時はBUILDDIR ではなくTOPDIR を使えばよい。