はじめに
Linuxカーネル5.0がリリースされたのでmeta-raspberrypiの環境で試そうと思ったら、いろいろと罠があって4日も経ってしまった。
RPiのカーネルはこっちで管理されているが、まだ5.0-rc8なのでバニラカーネルを試すことにした。
meta-raspberrypiのカーネルとはバージョンが変わったのでbbappendではなくレシピを新設する。ただし、meta-raspberrypi自体は汚したくないのでmeta-rpi-lk5を新規に作成する。
bbappendはレシピの拡張なのでレイヤをまたいでいても元のレシピの環境変数は引き継がれるため、incファイルなどが元のレイヤにある場合でも正常に処理できるが、 新規に作成するレシピではそれらは引き継がれないため別のレイヤのincを読み込む場合、実行時の環境変数などを考慮する必要がある。
また、今回は無理矢理でも動かす事が目的なので、本格的に使用したい場合はRPi用のカーネルのカーネルがリリースされるまで待つことをおすすめする。
環境構築
いつものやつ。
ソース取得
$ mkdir -p rpi-thud/layers $ cd rpi-thud/layers $ git clone git://git.yoctoproject.org/poky.git -b thud $ git clone git://git.yoctoproject.org/meta-raspberrypi -b thud $ git clone git://git.openembedded.org/meta-openembedded -b thud
環境変数設定
$ source layers/poky/oe-init-build-env build_lk5
自動的にビルドディレクトリに移動される。 これで、bitbake関連のツールが使用可能になる。
レイヤ追加
$ bitbake-layers add-layer ../layers/meta-openembedded/meta-oe $ bitbake-layers add-layer ../layers/meta-openembedded/meta-python $ bitbake-layers add-layer ../layers/meta-openembedded/meta-multimedia $ bitbake-layers add-layer ../layers/meta-openembedded/meta-networking $ bitbake-layers add-layer ../layers/meta-raspberrypi
local.confの修正
MACHINEの行を修正する。
MACHINE = "raspberrypi3" DL_DIR ?= "${TOPDIR}/../downloads" # enable uart ENABLE_UART = "1" # systemd DISTRO_FEATURES_append = " systemd pam" VIRTUAL-RUNTIME_init_manager = "systemd" DISTRO_FEATURES_BACKFILL_CONSIDERED = "sysvinit" VIRTUAL-RUNTIME_initscripts = ""
meta-rpi-lk5の作成
まずはmeta-rpi-lk5
を作成し、meta-raspberrypiからカーネルのレシピをlinux-raspberrypi_5.0.bb
としてコピーする。
$ bitbake-layers create-layer meta-rpi-lk5 $ mv ./meta-rpi-lk5 ../layers/ $ mkdir -p ../layers/meta-rpi-lk5/recipes-kernel/linux $ bitbake-layers add-layer ../layers/meta-rpi-lk5 $ cp ../layers/meta-raspberrypi/recipes-kernel/linux/linux-raspberrypi_4.14.bb ../layers/meta-rpi-lk5/recipes-kernel/linux/linux-raspberrypi_5.0.bb
その後、SRC_URI
をバニラカーネルに設定し、バージョンなども5.0向けに設定する。
LINUX_VERSION ?= "5.0.0" SRCREV = "1c163f4c7b3f621efff9b28a47abb36f7378d783" SRC_URI = " \ git://github.com/torvalds/linux.git;protocol=https \ " require recipes-kernel/linux/linux-raspberrypi.inc LIC_FILES_CHKSUM = "file://COPYING;md5=bbea815ee2795b2f4230826c0c6b8814"
レシピのカーネルバージョン
local.conf
で参照するカーネルのバージョンを明示的に設定する。
PREFERRED_VERSION_linux-raspberrypi = "5.0%"
これで5.0を参照しようとする。
incのパス
別のレイヤにあるincファイル
を参照する場合は、レイヤのディレクトリをトップとした相対パスで指定する必要がある。
この場合ではmeta-rpi-lk5
のレシピからmeta-raspberrypi
にあるincファイルを参照したい。
bitbake実行時はレイヤのトップまでは解決されているので、recipes-kernel/linux/linux-raspberrypi.inc
のように指定する。
filesの参照パス
SRC_URI = "files://"
で参照するパスは、実行時のFILESPATH
によって解決される。
これはディレクトリ構成に影響されるところなので、レシピではなくlocal.conf
で対応する。
FILESPATH_append = ":${TOPDIR}/../layers/meta-raspberrypi/recipes-kernel/linux/files"
defconfigのダウンロード
バニラカーネルではraspberrypi3向けのdefconfigが無い1ので、raspberrypiのカーネルから持ってくる。
SRC_URI = " \ git://github.com/torvalds/linux.git;protocol=https \ https://raw.githubusercontent.com/raspberrypi/linux/rpi-5.0.y/arch/arm/configs/bcm2709_defconfig \ " do_kernel_checkout_append() { cp ${WORKDIR}/bcm2709_defconfig ${S}/arch/arm/configs/ }
カスタマイズコードの反映
raspberrypi向けのカスタマイズコードをバニラカーネルに反映する。
とりあえず、ここにLK5に向けて作業中のリポジトリがある(がまだベースが最新ではない)ので、これを引っ張ってきてパッチを作成する。
yocto側のカーネルソースの展開
$ bitbake virtual/kernel -c clean $ bitbake virtual/kernel -c kernel_checkout
RPiのカーネルの取得
$ mkdir TEMP $ cd TEMP $ git clone https://github.com/raspberrypi/linux.git -b rpi-5.0.y $ cd linux
rsyncで追加分のみ処理したい(更新は除外したい)ので、転送先のファイルのmtimeを更新する。
$ find ../../tmp/work-shared/raspberrypi3/kernel-source/ | xargs touch
rsyncでコピー
$ rsync -rvu ./ ../../tmp/work-shared/raspberrypi3/kernel-source/ --exclude='.git*'
.git関連は除外しておく。
ラズパイ関連のキーワードとしてBCM2835
が記述されているファイルをgrepで引っ掛けて上書きコピーをする。
xargsは-I
を使うと後続のコマンドに引数を渡すことができる。ここでは-IXXX
としているので、xargsに渡る引数をXXX
として参照できるようになる。
$ grep -r 'BCM2835' --exclude-dir='.git' . | cut -d':' -f1 | uniq | xargs -IXXX cp -f XXX ../../tmp/work-shared/raspberrypi3/kernel-source/XXX
grepから漏れてて、ビルドに必要なファイルを個別に上書きコピーする。
$ cp ./include/soc/bcm2835/raspberrypi-firmware.h ../../tmp/work-shared/raspberrypi3/kernel-source/include/soc/bcm2835 $ cp ./drivers/staging/vc04_services/bcm2835-camera/bcm2835-camera.h ../../tmp/work-shared/raspberrypi3/kernel-source/drivers/staging/vc04_services/bcm2835-camera
ここから一度コミットしてgit format-patch
でパッチを作成
$ cd ../.. $ pushd . $ cd tmp/work-shared/raspberrypi3/kernel-source/ $ git checkout -b test $ git add . $ git reset HEAD arch/arm/configs/bcm2709_defconfig $ git commit -m "Add files for RPi" $ git format-patch HEAD^ $ mv 0001-Add-files-for-RPi.patch ~/ $ popd
bcm2709_defconfig
はSRC_URIで取得するのでパッチからは外す。
レシピにパッチを組み込む
$ mkdir ../layers/meta-rpi-lk5/recipes-kernel/linux/files $ mv ~/0001-Add-files-for-RPi.patch ../layers/meta-rpi-lk5/recipes-kernel/linux/files/
linux-raspberrypi_5.0.bb
のSRC_URIを次のようにした。
SRC_URI = " \ git://github.com/torvalds/linux.git;protocol=https \ https://raw.githubusercontent.com/raspberrypi/linux/rpi-5.0.y/arch/arm/configs/bcm2709_defconfig \ file://0001-Add-files-for-RPi.patch \ "
カーネルのリビルド
カーネルのリビルドは次のコマンドで行なう。
$ bitbake virtual/kernel -c cleansstate $ bitbake virtual/kernel
mmcの認識
SDをなぜかmmcblk1
と認識するようなので、local.conf
で対応する。
CMDLINE = "dwc_otg.lpm_enable=0 console=serial0,115200 root=/dev/mmcblk1p2 rootfstype=ext4 rootwait"
イメージの作成
今回はあえて最小構成としてcore-image-minimal
を作成する。
$ bitbake core-image-minimal
動作確認
無事に動いた。
Poky (Yocto Project Reference Distro) 2.6.1 raspberrypi3 ttyS0 raspberrypi3 login: root root@raspberrypi3:~# uname -a Linux raspberrypi3 5.0.0 #1 SMP Fri Mar 8 05:46:52 UTC 2019 armv7l GNU/Linux
最終的なカーネルのレシピ
linux-raspberrypi_5.0.bb
LINUX_VERSION ?= "5.0.0" SRCREV = "1c163f4c7b3f621efff9b28a47abb36f7378d783" SRC_URI = " \ git://github.com/torvalds/linux.git;protocol=https \ https://raw.githubusercontent.com/raspberrypi/linux/rpi-5.0.y/arch/arm/configs/bcm2709_defconfig \ file://0001-Add-files-for-RPi.patch \ " SRC_URI[md5sum] = "706ffdea63fa9d8525e27d89aa167a31" SRC_URI[sha256sum] = "42b90e26bb976f29d1fecc669517d16d11d0a8ba58c9040c9e70565a2216f26b" require recipes-kernel/linux/linux-raspberrypi.inc LIC_FILES_CHKSUM = "file://COPYING;md5=bbea815ee2795b2f4230826c0c6b8814" do_kernel_checkout_append() { cp ${WORKDIR}/bcm2709_defconfig ${S}/arch/arm/configs/ }
最終的なlocal.conf
自動生成されたlocal.conf
に次の内容を追加する。
MACHINE = "raspberrypi3" DL_DIR ?= "${TOPDIR}/../downloads" # enable uart ENABLE_UART = "1" # systemd DISTRO_FEATURES_append = " systemd pam" VIRTUAL-RUNTIME_init_manager = "systemd" DISTRO_FEATURES_BACKFILL_CONSIDERED = "sysvinit" VIRTUAL-RUNTIME_initscripts = "" IMAGE_INSTALL_append = " connman connman-client" PREFERRED_VERSION_linux-raspberrypi = "5.0%" FILESPATH_append = ":${TOPDIR}/../layers/meta-raspberrypi/recipes-kernel/linux/files" #IMAGE_FSTYPES="tar.bz2 ext4 rpi-sdimg" CMDLINE = "dwc_otg.lpm_enable=0 console=serial0,115200 root=/dev/mmcblk1p2 rootfstype=ext4 rootwait" KERNEL_DEVICETREE_remove = " \ overlays/at86rf233.dtbo \ overlays/dwc2.dtbo \ overlays/gpio-key.dtbo \ overlays/hifiberry-amp.dtbo \ overlays/hifiberry-dac.dtbo \ overlays/hifiberry-dacplus.dtbo \ overlays/hifiberry-digi.dtbo \ overlays/i2c-rtc.dtbo \ overlays/iqaudio-dac.dtbo \ overlays/iqaudio-dacplus.dtbo \ overlays/lirc-rpi.dtbo \ overlays/pi3-disable-bt.dtbo \ overlays/pi3-miniuart-bt.dtbo \ overlays/pitft22.dtbo \ overlays/pitft28-resistive.dtbo \ overlays/pitft35-resistive.dtbo \ overlays/pps-gpio.dtbo \ overlays/rpi-ft5406.dtbo \ overlays/rpi-poe.dtbo \ overlays/vc4-kms-v3d.dtbo \ overlays/w1-gpio-pullup.dtbo \ overlays/w1-gpio.dtbo \ "
まとめ
キャッシュ周りやデバイスツリー周りなど、注意が必要。
今回は無理矢理でも動かすことがテーマだったので、ほぼRPiカーネル側の修正をバニラに持っていくという力技で対応した。 もうここまで来るとバニラカーネルではない。
[おまけ] overlays以下のデバイスツリーがビルドエラー
次のようにoverlaysのデバイスツリーのビルドで失敗する。
| make[2]: *** No rule to make target 'overlays/at86rf233.dtbo'. Stop.
Makefileなども見直したが結局うまく行かず。最終的にはoverlaysを諦めた。
そのためにlocal.conf
に次の行を追加した。
KERNEL_DEVICETREE_remove = " \ overlays/at86rf233.dtbo \ overlays/dwc2.dtbo \ overlays/gpio-key.dtbo \ overlays/hifiberry-amp.dtbo \ overlays/hifiberry-dac.dtbo \ overlays/hifiberry-dacplus.dtbo \ overlays/hifiberry-digi.dtbo \ overlays/i2c-rtc.dtbo \ overlays/iqaudio-dac.dtbo \ overlays/iqaudio-dacplus.dtbo \ overlays/lirc-rpi.dtbo \ overlays/pi3-disable-bt.dtbo \ overlays/pi3-miniuart-bt.dtbo \ overlays/pitft22.dtbo \ overlays/pitft28-resistive.dtbo \ overlays/pitft35-resistive.dtbo \ overlays/pps-gpio.dtbo \ overlays/rpi-ft5406.dtbo \ overlays/rpi-poe.dtbo \ overlays/vc4-kms-v3d.dtbo \ overlays/w1-gpio-pullup.dtbo \ overlays/w1-gpio.dtbo \ "
OF_OVERLAYの調査
OV_OVERLAYが有効になっていないことに気づいたので掘り下げた。
RPiのカーネルではOF_CONFIGFSによりselectされる。これはbcm2709_defconfigでも設定されている。しかし、バニラカーネルではOF_CONFIGSの機能が実装されていないため結果的にOF_OVERLAYも有効にならない。
OF_CONFIGFSが実装されないのは次のような理由らしい。
I think most of us have given up on making it work in the kernel, just too many race conditions.
結局、OF_OVERLAYを有効化しても問題は解決しなかった。
Makefileでルールの解決に失敗するのは
./scripts/Makefile.lib
と./scripts/Makefile.dtbinst
が関係していると思ったのだが、これらをyocto側に持っていっても解決できなかった。
-
無いわけではないが、使えないっぽいというか試行錯誤の上断念した。↩