みつきんのメモ

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

YoctoProject DEBIX Model Aを動かす

はじめに

DEBIX Model Aを動かすではbitbakeで吐き出したイメージを公式の手順を少しアレンジしてDEBIX Model Aを動かした。

今回はbitbake一発でイメージを出力できるようにする。

公式のカーネル、u-bootのリポジトリをそのまま使用するレイヤを作成するため、YoctoProjectのバージョンはhardknottとする。

ピンヘッダ

デバッグシリアル用のUARTは40ピンのピンヘッダに引き出されているが、このピンヘッダは2mmピッチなので注意が必要(ラズパイなどは2.54mm)。 筆者は2mmピッチから線を引き出せるジャンパワイヤを使用している。

環境構築

作業ディレクト

$ mkdir -p ~/yocto/debix-hardknott
$ cd ~/yocto/debix-hardknott

ダウンロード

repoツールで環境をダウンロードする。

$ repo init -u https://github.com/nxp-imx/imx-manifest -b imx-linux-hardknott -m imx-5.10.72-2.2.0.xml
$ repo sync

初期セットアップ

imx-yocto-bsp特有の初期セットアップ

$ DISTRO=fsl-imx-wayland MACHINE=imx8mp-lpddr4-evk source imx-setup-release.sh -b build

EULAが表示されるので最後まで読んでyを入力する。

2回目以降

別の端末を開いて、すでに作成されてビルドディレクトリを使用する場合は下記を実行する。

$ source setup-environment build

これらはimx-yocto-bspの独特なお作法となる。

meta-debixの作成

レイヤの作成

下記のコマンドを実行してmeta-debixのレイヤを作成すrう

$ bitbake-layers create-layer meta-debix -p 10
$ rm -rf ./meta-debix/recipes-example
$ mv ./meta-debix ../sources
$ bitbake-layers add-layer ../sources/meta-debix

MACHINEの定義

今回はimx8mp-lpddr4-evkの定義をベースにdebix-aというマシンを作成する。

$ mkdir ../sources/meta-debix/conf/machine

meta-debix/conf/machine/debix-a.confを下記の内容で作成する。

MACHINEOVERRIDES =. "imx8mp-lpddr4-evk:"
require conf/machine/imx8mp-lpddr4-evk.conf

local.confの修正

MACHINE定義を追加したので、local.confに下記を追加する。

MACHINE = "debix-a"

u-bootのレシピ作成

u-bootのリポジトリを差し替えるためにbbappendを作成する。

$ recipetool newappend -e ../sources/meta-debix virtual/bootloader

下記の内容を記述する。

UBOOT_SRC_debix-a ?= "git://github.com/debix-tech/uboot.git;protocol=https"
SRCREV_debix-a = "1a87b972fac74699482e2dce2023b66358d8c4f5"

カーネルのレシピ作成

カーネルリポジトリを差し替えるためにbbappendを作成する。

$ recipetool newappend -e ../sources/meta-debix virtual/kernel

bbappendに下記の内容を記載する。

KERNEL_SRC_debix-a ?= "git://github.com/debix-tech/linux;protocol=https"
SRCBRANCH_debix-a = "debix"
SRCREV_debix-a = "f924d76e63c153f58206425d31f88c5771caeb80"

dtbでエラー

下記のようなエラーが発生する。

| ERROR: Input tree has errors, aborting (use -f to force output)
| make[2]: *** [scripts/Makefile.lib:326: arch/arm64/boot/dts/freescale/imx8mp-evk-usdhc1-m2.dtb] Error 2

debixのカーネルでは関係の無いデバイスツリーはビルドしないように修正されている。 リファレンスボード向けのデバイスツリーの設定はKERNEL_DEVICETREEから削除しておく必要がある。

meta-debix/conf/machine/debix-a.confに次の内容を追記する。

KERNEL_DEVICETREE_remove_debix-a = " \
  freescale/imx8mp-evk-dsp.dtb \
  freescale/imx8mp-evk-ecspi-slave.dtb \
  freescale/imx8mp-evk-ndm.dtb \
  freescale/imx8mp-evk-usdhc1-m2.dtb \
  freescale/imx8mp-evk-rm67199.dtb \
  freescale/imx8mp-ab2.dtb \
  freescale/imx8mp-evk-basler.dtb \
  freescale/imx8mp-evk-basler-ov2775.dtb \
  freescale/imx8mp-evk-basler-ov5640.dtb \
  freescale/imx8mp-evk-dual-basler.dtb \
  freescale/imx8mp-evk-dual-ov2775.dtb \
  freescale/imx8mp-evk-ecspi-slave.dtb \
  freescale/imx8mp-evk-flexcan2.dtb \
  freescale/imx8mp-evk-hifiberry-dacplus.dtb \
  freescale/imx8mp-evk-inmate.dtb \
  freescale/imx8mp-evk-iqaudio-dacplus.dtb \
  freescale/imx8mp-evk-iqaudio-dacpro.dtb \
  freescale/imx8mp-evk-it6263-lvds-dual-channel.dtb \
  freescale/imx8mp-evk-jdi-wuxga-lvds-panel.dtb \
  freescale/imx8mp-evk-ndm.dtb \
  freescale/imx8mp-evk-ov2775.dtb \
  freescale/imx8mp-evk-ov2775-ov5640.dtb \
  freescale/imx8mp-evk-pcie-ep.dtb \
  freescale/imx8mp-evk-rm67191.dtb \
  freescale/imx8mp-evk-rm67199.dtb \
  freescale/imx8mp-evk-root.dtb \
  freescale/imx8mp-evk-rpmsg.dtb \
  freescale/imx8mp-evk-sof-wm8960.dtb \
  freescale/imx8mp-evk-spdif-lb.dtb \
  freescale/imx8mp-evk-usdhc1-m2.dtb \
"

modules_installで謎のエラー

下記のようなエラーが発生する。

nux/linux-imx/5.10.72+gitAUTOINC+f924d76e63-r0/image/lib/firmware modules_install
| tar: .extra.tar: Cannot open: No such file or directory
| tar: Error is not recoverable: exiting now

ログを見る限りmodule_installを実行した際になにかしらが発生しているらしい。 .extra.tarが見つからないというエラーのようだ。.extra.tarなんて聞いたことがないファイル名なので、 Google先生に聞いてみたが何も引っかからない。

最終的には、debixのカーネルメンテナが仕込んだ罠であることがわかった。

# Target to install modules
PHONY += modules_install
modules_install: _modinst_ _modinst_post

PHONY += _modinst_
_modinst_:
   @rm -rf $(MODLIB)/kernel
   @rm -f $(MODLIB)/source
   @mkdir -p $(MODLIB)/kernel
   @ln -s $(abspath $(srctree)) $(MODLIB)/source
   @if [ ! $(objtree) -ef  $(MODLIB)/build ]; then \
      rm -f $(MODLIB)/build ; \
      ln -s $(CURDIR) $(MODLIB)/build ; \
  fi
   @sed 's:^:kernel/:' modules.order > $(MODLIB)/modules.order
   @cp -f modules.builtin $(MODLIB)/
   @cp -f $(objtree)/modules.builtin.modinfo $(MODLIB)/
   @tar xpf .extra.tar       //★コレ
   @cp -rf extra $(MODLIB)/
  $(Q)$(MAKE) -f $(srctree)/scripts/Makefile.modinst

.extra.tarには、ビルド済みのカーネルモジュールが入っていて、modules_installのタイミングで他のカーネルモジュールと一緒に 忍び込ませてしまおうというものであるようだ。

とりあえず、カーネルのレシピとしてはこの謎ファイルは入れないようにする。

./tmp/work-shared/debix-a/kernel-source/Makefileを下記のように修正する。

diff --git a/Makefile b/Makefile
index 5f90097f7..48211c850 100755
--- a/Makefile
+++ b/Makefile
@@ -1445,8 +1445,6 @@ _modinst_:
    @sed 's:^:kernel/:' modules.order > $(MODLIB)/modules.order
    @cp -f modules.builtin $(MODLIB)/
    @cp -f $(objtree)/modules.builtin.modinfo $(MODLIB)/
-  @tar xpf .extra.tar
-  @cp -rf extra $(MODLIB)/
    $(Q)$(MAKE) -f $(srctree)/scripts/Makefile.modinst
 
 # This depmod is only for convenience to give the initial
-- 
2.25.1

パッチを下記のように作成する。

$ pushd ./tmp/work-shared/debix-a/kernel-source
$ git add -u
$ git commit -m 'linux-imx: fix tar option'
$ git format-patch -o /tmp HEAD^
$ popd

/tmp/0001-linux-imx-fix-tar-option.patchが生成されるので、レシピに取り込む。

$ recipetool appendsrcfile ../sources/meta-debix virtual/kernel /tmp/0001-linux-imx-fix-tar-option.patch

ツールで修正されたレシピを一部手動で修正し下記のようにする。

KERNEL_SRC_debix-a ?= "git://github.com/debix-tech/linux;protocol=https"
SRCBRANCH_debix-a = "debix"
SRCREV_debix-a = "f924d76e63c153f58206425d31f88c5771caeb80"

SRC_URI_append_debix-a = " file://0001-linux-imx-fix-tar-option.patch"
FILESEXTRAPATHS_prepend := "${THISDIR}/${PN}:"

カーネルモジュールのレシピを作成

先程罠として発動した.extra.tarの内容をインストールするためのレシピを作成する。

meta-debix/recipes-kernel/linux/linux-debix-modules_5.10.bbを下記の内容で作成する。

SUMMARY = "Extra kernel modules"
DESCRIPTION = "Extra kernel modules for DEBIX Model A"
LICENSE = "CLOSED"

SRC_URI = "git://github.com/debix-tech/linux;protocol=https;branch=debix"
SRCREV = "f924d76e63c153f58206425d31f88c5771caeb80"

S = "${WORKDIR}"

do_unpack:append() {
    bb.build.exec_func('shell_do_unpack_extra', d)
}

shell_do_unpack_extra() {
    tar xf ${WORKDIR}/git/.extra.tar -C ${WORKDIR}
}

inherit module-base

do_compile[noexec] = "1"

do_install() {
    cd ${S}/extra

    install -d ${D}${nonarch_base_libdir}/modules/${KERNEL_VERSION}
    tar --no-same-owner --exclude='./patches' --exclude='./.pc' -cpf - . \
        | tar --no-same-owner -xpf - -C ${D}${nonarch_base_libdir}/modules/${KERNEL_VERSION}
}

FILES_${PN} = "/lib/modules"

ライセンスはGPLv2あたりが妥当だと思うのだが、バイナリ提供であるため手元にソースコードがない。 仕方なくCLOSEDで凌ぐことにする。

最終的なlocal.conf

最終的なlocal.confは下記のようになる。

MACHINE = "debix-a"
IMAGE_INSTALL_append = " linux-debix-modules"

ビルド

$ bitbake core-image-minimal

動作確認

NXP i.MX Release Distro 5.10-hardknott debix-a ttymxc1

debix-a login: root
root@debix-a:~# uname -a
Linux debix-a 5.10.72-lts-5.10.y+g6ffd523c7 #1 SMP PREEMPT Tue Jan 10 10:28:10 UTC 2023 aarch64 GNU/Linux
root@debix-a:~# lsmod
Module                  Size  Used by
vvcam_dwe              28672  0
vvcam_isp              65536  0
imx219                 28672  0

追加したドライバも組み込まれている。

まとめ

DEBIX Model Aを動かすで行った手順をbitbake一発で行えるようにレイヤを作成した。

現時点では、DEBIXの公式BSPに合わせて下記のような構成になっている。

  • LinuxはDEBIXのもの
  • u-bootはDEBIXのもの
  • imx-yocto-bspはhardknott(imx-5.10.72-2.2.0)

1年前くらいにこのレイヤを作っていればありがたみもあったかもしれない。 とはいえ、imx-yocto-bspで提供する他のイメージなども簡単に作れるようになっているので便利ではあるはず。 KERNEL_DEVICETREEの設定を調整すれば、オプションボード用の環境も比較的容易に作れるはず。

一応GitHubにおいた。