みつきんのメモ

組み込みエンジニアです。Interface誌で「My オリジナルLinuxの作り方」連載中

Yocto Zephyrアプリケーションのコンフィグを変更する

はじめに

YoctoでビルドするZephyrアプリケーションのコンフィグを設定する方法を調べた。

micro:bitの5x5 LEDを有効化する。

最終的にはmeta-armの修正が必要となった。

作業環境はYocto Zephyrに独自のアプリケーションを追加してみるを使用する。

環境変数の読み込み

最初にこれを実行し、bitbake関連のツールを使用できるようにしておく。

$ source poky/oe-init-build-env build

do_menuconfigタスク

ZephyrはLinuxカーネルのようにKconfigによってコンフィグを変更したりできる。

Yoctoでは、このような機能を持つコンポーネントのレシピの場合do_menuconfigタスクを実装している場合が多く、 それが利用でいないか確認してみた。

$ bitbake my-app -c listtasks | grep menuconfig
do_menuconfig       Runs 'make menuconfig' for the kernel

見つかったので実行してみる。

$ bitbake my-app -c menuconfig

残念ながら使用できない。

make: *** No rule to make target 'menuconfig'.  Stop.
Command failed.
Press any key to continue... 

コンフィグの変更

Zephyrアプリケーションのコンフィグを変更するにはprj.confに記述する。

Yocto Zephyrに独自のアプリケーションを追加してみるで作成した時には下記のように空の設定を記述していた。

# nothing here

micro:bitの5x5 LEDを有効化するためにはCONFIG_MICROBIT_DISPLAYを有効化する。

CONFIG_MICROBIT_DISPLAY=y

メニューコンフィグ

実際にこの設定が反映されているか確認したい。

本来であればメニューコンフィグを実行するのが手っ取り早い。do_menuconfigタスクは使えないが、実のところZephyrのメニューコンフィグを実行する手段はある。

下記のようにdo_configureタスクを実行したあと、do_devshellタスクを実行する。

$ bitbake my-app -c configure
$ bitbake my-app -c devshell

すると、開発用シェルが${S}で設定されているディレクトリに移動された状態で開く。

ビルドディレクトリにはbuild.ninjaが生成されているので、下記のようにするとZephyrのメニューコンフィグを実行することができる。

$ cd ../build
$ ninja menuconfig

f:id:mickey_happygolucky:20210828094011p:plain
メニューコンフィグ

MICROBIT_DISPLAY=n

/を押したあとでキーワードを入力すると、コンフィグを検索することができる。

MICROBIT_と入力すると下記のような画面になる。

f:id:mickey_happygolucky:20210828094033p:plain
MICROBIT_DISPLAY(=n)

MICROBIT_DISPLAY=nとなっており、prj.confの設定が反映されていない。

?で詳細を表示してこのコンフィグの依存関係を表示すると下記のようになっている。

Direct dependencies (=n):
     BOARD_BBC_MICROBIT(undefined/n)
  && PRINTK(=y)
  && GPIO(=y)
  && DISPLAY(=n)

BOARD_BBC_MICROBITDISPLAYの設定がnになっていることがわかる。

BOARDの設定を見るとBOARD_BBC_MICROBITはボード設定に依存しているようだ。 BOARD(=qemu_cortex_m0)はZephyrがターゲットボードを決定するための基本的な設定なのだろう。

f:id:mickey_happygolucky:20210828094020p:plain
BOARD(=qemu_cortex_m0)

BOARD(=qemu_cortex_m0)BOARD_QEMU_CORTEX_M0(=y)は対応しているように見える。つまりBOARD(=bbc_microbit)と設定すればBOARD_BBC_MICROBIT(=y)にできるのではないか。

BOARDの設定

meta-arm/conf/machine/microbit-v1.confを調べると、下記の様な記述が見つかる。

# Zephyr RTOS settings
ZEPHYR_BOARD = "qemu_cortex_m0"
ZEPHYR_INHERIT_CLASSES += "zephyr-qemuboot"
ARCH_qemu-cortex-m0 = "arm"

ZEPHYR_BOARDに設定された値がZephyrのCONFIG_BOARDに設定されているようだ。

ZEPHYR_BOARDの値を変更すれば良さそうだが、できればmeta-armを直接変更したくない。local.confで下記のようにすることで設定を上書きできないだろうか。

ZEPHYR_BOARD = "bbc_microbit"

結論から言うとこれはできない。

microbit-v1.confでZEPHYR_BOARDを設定する時に=を使って代入しているため、変数をあとから上書きすることができないからだ。

下記のように?=を使用して代入していればlocal.confなどであとから変更することができるようになる。

ZEPHYR_BOARD ?= "qemu_cortex_m0"

レイヤやMACHINEの定義をする場合、RAMのベースアドレスのように絶対に上書きされたくないような物以外はできるだけ?=を使うようにしてほしいが、 microbit-v1.confはmicro:bit専用の設定であるので、下記のように修正するのが本来正しい気もする。

- ZEPHYR_BOARD = "qemu_cortex_m0"
+ ZEPHYR_BOARD = "bbc_microbit"

最終的なコンフィグ

meta-arm/conf/machine/microbit-v1.confZEPHYR_BOARDbbc_microbitに設定したあと、meta-zephyr-app/recipes-example/my-app/files/my-app/prj.confを下記のように変更する。

CONFIG_DISPLAY=y
CONFIG_MICROBIT_DISPLAY=y

bitbake my-app -c configureでdo_configureタスクを実行したあとに、devshellでninja menuconfigを実行して、コンフィグの依存関係を確認すると下記のようになっている。

Direct dependencies (=y):
     BOARD_BBC_MICROBIT(=y)
  && PRINTK(=y)
  && GPIO(=y)
  && DISPLAY(=y)

これでCONFIG_MICROBIT_DISPLAYは有効化できた。

プログラムの修正

VSCode + PlatformIO で micro:bit + Zephyr RTOS 開発がちょうどZephyrで5x5 LEDを使用する方法を紹介している。

meta-zephyr-app/recipes-example/my-app/files/my-app/src/main.cを下記のように変更する。

#include <zephyr.h>
#include <display/mb_display.h>

void main(void)
{
    struct mb_image patterns[] = {
        MB_IMAGE(
            {0, 0, 0, 0, 0},
            {1, 1, 0, 1, 1},
            {0, 0, 0, 0, 0},
            {0, 0, 0, 0, 0},
            {0, 1, 1, 1, 0},
        ),
    };
    struct mb_display *dpy = mb_display_get();
    mb_display_image(dpy, MB_DISPLAY_MODE_DEFAULT, SYS_FOREVER_MS, patterns, 1);
}

レシピの修正

5x5 LEDは実機に書き込まないと確認できないし、毎回objcopyでbinary形式に変換するのも面倒なので、 do_deployタスクに処理を追加する。

include recipes-kernel/zephyr-kernel/zephyr-sample.inc

SRC_URI += "file://my-app"

ZEPHYR_SRC_DIR = "${S}/../my-app"

do_deploy_append () {
    local src=${B}/zephyr/${ZEPHYR_MAKE_OUTPUT}
    src=${src%.*}.bin
    install -D ${src} ${DEPLOYDIR}/${PN}.bin
}

ビルド

下記のようにビルドを実行する。

$ bitbake my-app

すると、tmp/deploy/images/microbit-v1my-app.binも配置されるようになった。

これをmicro:bitの実機に書き込んで動作を確認してみる。

$ cd tmp/deploy/images/microbit-v1/
$ cp ./my-app.bin /media/mickey/MICROBIT/

f:id:mickey_happygolucky:20210828094041j:plain
実行結果

まとめ

YoctoでビルドするZephyrアプリケーションのコンフィグを変更して5x5 LEDを使用してみた。

下記のような問題があったが力技でなんとか回避した。

  1. do_menuconfigタスクが使えない
  2. ZephyrのBOARDコンフィグの変更のためにmeta-armを直接修正する必要がある。

ちょっと標準と外れたことをしようとすると、急にハードルが上がってしまうのがこの手の便利ツールのツライところ。

ただ、その中でもYoctoは比較的自由度が高いため、いろいろ手を尽くして回避することができる。 meta-arm提供のconfファイルで=で代入しているため、変更したいところがlocal.confで上書きできないのは、ちょっと気に入らない。

Yocto Zephyrのアプリケーションをqemu + gdbでデバッグ

はじめに

Yocto ProjectでビルドしたZephyrのアプリケーション(elf)をqemugdbデバッグしてみる。

環境

下記で作成した環境をベースに作業する

gdb-multiarch

使用するgdbUbuntu 20.04でaptで導入可能なgdb-multiarch

$ sudo apt install gdb-multiarch

runqemuについて

bitbakeでZephyrアプリケーションをビルドすると、下記のコマンドでqemuを使用してアプリケーションを実行することができる。

$ runqemu

bitbake同様に下記を実行して環境変数を設定しておく必要がある。

$ source poky/oe-init-build-env build

runqemuqemuを実行するためのラッパスクリプトで、実行するelfのパスや環境変数、必要なオプションなどを自動的にqemuに渡してくれるようになっている。

下記のようにすると追加で任意にパラメータをqemuに渡すことができる。

$ runqemu qemuparams='-serial mon:stdio'

runqemuの詳しい使い方は下記のように調べることができる。

$ runqemu --help

Usage: you can run this script with any valid combination
of the following environment variables (in any order):
  KERNEL - the kernel image file to use
  BIOS - the bios image file to use
  ROOTFS - the rootfs image file or nfsroot directory to use
  DEVICE_TREE - the device tree blob to use
  MACHINE - the machine name (optional, autodetected from KERNEL filename if unspecified)
  Simplified QEMU command-line options can be passed with:
    nographic - disable video console
    novga - Disable VGA emulation completely
    sdl - choose the SDL UI frontend
    gtk - choose the Gtk UI frontend
    gl - enable virgl-based GL acceleration (also needs gtk or sdl options)
    gl-es - enable virgl-based GL acceleration, using OpenGL ES (also needs gtk or sdl options)
    egl-headless - enable headless EGL output; use vnc (via publicvnc option) or spice to see it
    serial - enable a serial console on /dev/ttyS0
    serialstdio - enable a serial console on the console (regardless of graphics mode)
    slirp - enable user networking, no root privileges is required
    snapshot - don't write changes to back to images
    kvm - enable KVM when running x86/x86_64 (VT-capable CPU required)
    kvm-vhost - enable KVM with vhost when running x86/x86_64 (VT-capable CPU required)
    publicvnc - enable a VNC server open to all hosts
    audio - enable audio
    [*/]ovmf* - OVMF firmware file or base name for booting with UEFI
  tcpserial=<port> - specify tcp serial port number
  qemuparams=<xyz> - specify custom parameters to QEMU
  bootparams=<xyz> - specify custom kernel parameters during boot
  help, -h, --help: print this text
  -d, --debug: Enable debug output
  -q, --quiet: Hide most output except error messages

Examples:
  runqemu
  runqemu qemuarm
  runqemu tmp/deploy/images/qemuarm
  runqemu tmp/deploy/images/qemux86/<qemuboot.conf>
  runqemu qemux86-64 core-image-sato ext4
  runqemu qemux86-64 wic-image-minimal wic
  runqemu path/to/bzImage-qemux86.bin path/to/nfsrootdir/ serial
  runqemu qemux86 iso/hddimg/wic.vmdk/wic.vhd/wic.vhdx/wic.qcow2/wic.vdi/ramfs/cpio.gz...
  runqemu qemux86 qemuparams="-m 256"
  runqemu qemux86 bootparams="psplash=false"
  runqemu path/to/<image>-<machine>.wic
  runqemu path/to/<image>-<machine>.wic.vmdk
  runqemu path/to/<image>-<machine>.wic.vhdx
  runqemu path/to/<image>-<machine>.wic.vhd

qemugdb serverとして実行する

qemuqemu上で実行中のelfをデバッグするために、gdb serverのプロトコル喋れるようになっている。 (厳密には多分いろいろ違うと思うけど、とりあえず。)

runqemuに下記のオプションをつけて実行すると、elfの先頭でブレーク状態に、localhostの1234ポートで接続できるようになる。

$ runqemu qemuparams="-S -s"
runqemu - INFO - Running bitbake -e ...
runqemu - INFO - Continuing with the following parameters:
KERNEL: [/home/mickey/work/yocto/x86-hardknott/mb-hardknott/build/tmp/deploy/images/microbit-v1/my-app.elf]
MACHINE: [microbit-v1]
FSTYPE: [elf]
ROOTFS: [/home/mickey/work/yocto/x86-hardknott/mb-hardknott/build/tmp/deploy/images/microbit-v1/my-app-image-microbit-v1.elf]
CONFFILE: [/home/mickey/work/yocto/x86-hardknott/mb-hardknott/build/tmp/deploy/images/microbit-v1/my-app-image-microbit-v1.qemuboot.conf]

runqemu - INFO - Running /home/mickey/work/yocto/x86-hardknott/mb-hardknott/build/tmp/work/x86_64-linux/qemu-helper-native/1.0-r1/recipe-sysroot-native/usr/bin/qemu-system-arm    -nographic -vga none  -machine microbit -cpu cortex-m0 -m 256  -s -S -serial mon:vc -serial null  -kernel /home/mickey/work/yocto/x86-hardknott/mb-hardknott/build/tmp/deploy/images/microbit-v1/my-app.elf -append '  mem=256M  '

この状態で、別の端末を開き下記のように実行する

$ cd tmp/deploy/images/microbit-v1/
$ gdb-multiarch my-app.elf

するとgdbのプロンプトが表示されるので下記のように入力する。

(gdb) target remote :1234

これでqemuに接続される。

下記のようにしてmain関数にブレークを貼る。

(gdb) b main

実行してみる。

(gdb) c
Continuing.

Breakpoint 1, main ()
    at /home/mickey/work/yocto/x86-hardknott/mb-hardknott/build/tmp/work/cortexm0-poky-eabi/my-app/2.5.0+gitAUTOINC+fe7c2efca8_c3bd2094f9-r0/my-app/src/main.c:10
10      printk("Hello My Application World! %s\n", CONFIG_BOARD);

きちんとmain関数でブレークすることが確認できた。

まとめ

YoctoでビルドしたZephyrアプリケーションのelfをqemu + gdbデバッグできることを確認した。

meta-armでmicrobit-v1のマシン定義をした人が丁寧にqemu対応のための設定も作り込んでくれているため、 micro:bit向けのelfをqemu向けにリビルドすることなくqemu + gdbデバッグができるようになっている。

BSP次第だが、Yoctoではこういうこともできるのがおもしろい。

(おまけ) micro:bitのrunqemuのための設定

meta-arm/conf/machine/microbit-v1.confの下記の部分。

runqemuで呼び出されるqemu-systemや、それに渡されるオプションを定義している。

# For runqemu
QB_SYSTEM_NAME = "qemu-system-arm"
QB_MACHINE = "-machine microbit"
QB_CPU = "-cpu cortex-m0"
QB_OPT_APPEND = "-nographic -vga none"
QB_RNG = ""

Yocto Zephyrに独自のアプリケーションを追加してみる

はじめに

Yocto ProjectでビルドするZephyrに独自のアプリケーションを追加してみる。

環境構築

この環境をベースに作業する。

環境変数設定

bitbake関連のツールを使用するために環境変数の読み込みは行う。

$ source poky/oe-init-build-env build

レイヤの作成

ビルド対象への追加も行う。

$ bitbake-layers create-layer meta-zephyr-app
$ rm -rf ./meta-zephyr-app/recipes-example/example
$ mv meta-zephyr-app ../poky
$ bitbake-layers add-layer ../poky/meta-zephyr-app

自動生成されるexampleのレシピはディレクトリごと削除する。

ソースコードの作成

下記のようなディレクトリツリーを作成する。

my-app
├── CMakeLists.txt
├── prj.conf
└── src
    └── main.c

CMakeLists.txt

Zephyrのhello_worldを参考に作成。ライセンスもApache-2.0とした。

# SPDX-License-Identifier: Apache-2.0

cmake_minimum_required(VERSION 3.13.1)

find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE})
project(my-app)

target_sources(app PRIVATE src/main.c)

prj.conf

下記の一行だけ。

# nothing here

echoとかで適当に作成してよい。

$ echo '# nothing here' > prj.conf

src/main.c

プログラム本体。

これもhello_world.cを参考に作成(というか丸パクリ)した。

/*
 * SPDX-License-Identifier: Apache-2.0
 */

#include <zephyr.h>
#include <sys/printk.h>

void main(void)
{
    printk("Hello My Application World! %s\n", CONFIG_BOARD);
}

レシピの作成

既存のOSSなどWeb上にあるリポジトリソースコードアーカイブからレシピを作成する場合はrecipetoolが便利だが、 ローカルのソースツリーからレシピを作る機能はないため、手動で作成する必要がある。

my-app_0.1.bb

レシピはmeta-zephyr-app/recipes-example/my-appに配置されるようにする。

buildディレクトリで作業する場合下記のようにディレクトリを作成する。

$ mkdir -p ../poky/meta-zephyr-app/recipes/example/my-app

そして、その配下にmy-app_0.1.bbを下記の内容で作成する。

include recipes-kernel/zephyr-kernel/zephyr-sample.inc

SRC_URI += "file://my-app"

ZEPHYR_SRC_DIR = "${S}/../my-app"

自分のレイヤ以外のレイヤに存在するincファイルをincludeする場合、レイヤ直下からの相対パスを記述する必要がある。

下記のようにファイル名だけ記述した場合、includeされずにその行は無視されるので注意が必要となる。

include zephyr-sample.inc

ソースコードの配置

先ほど作成したmy-app以下のソースツリーをmeta-zephyr-app/recipes-example/my-app/filesに配置する。

my-appディレクトリがbuildディレクトリに作成していた場合下記のようにして移動する。

$ mkdir -p ../poky/meta-zephyr-app/recipes/example/my-app/files
$ mv ./my-app ../poky/meta-zephyr-app/recipes/example/my-app/files

最終的にmeta-zephyr-appは下記のようなツリーになる。

meta-zephyr-app/
├── COPYING.MIT
├── README
├── conf
│   └── layer.conf
└── recipes-example
    └── my-app
        ├── files
        │   └── my-app
        │       ├── CMakeLists.txt
        │       ├── prj.conf
        │       └── src
        │           └── main.c
        └── my-app_0.1.bb

ビルド

bitbakeを実行する。

$ bitbake my-app

recipes-kernel/zephyr-kernel/zephyr-sample.incが正しくインクルードできていれば、pokyではなくzephyrがビルドされる。

qemuで実行

$ runqemu qemux86 qemuparams="-serial mon:stdio"
(... snip ...)

*** Booting Zephyr OS build zephyr-v2.5.0  ***
Hello My Application World! qemu_cortex_m0

まとめ

意外と少ない手順でZephyrのアプリケーションを追加することができた。

YoctoでLinux以外のOSだったり、Cortext-M向けのバイナリをビルドするということにピンと来ていなかったが、意外と便利に使えるのかもしれない。

Yocto BBC micro:bit V1向けのZephyrを試してみる

はじめに

YoctoでZephyrをビルドできるっぽいことは知っていたが、試したことがなかったのでやってみる。

使用するバージョンはhardknott

構築手順

ソース取得

下記のコマンドでソースを取得する。

$ mkdir -p mb-hardknott && cd mb-hardknott
$ git clone git://git.yoctoproject.org/poky.git -b hardknott

環境変数設定

$ source poky/oe-init-build-env build

自動的にビルドディレクトリに移動される。 これで、bitbake関連のツールが使用可能になる。

レイヤ追加

下記のコマンドでビルド対象にmeta-armmeta-zephyrを追加する。

$ bitbake-layers layerindex-fetch meta-arm meta-zephyr

複数のレイヤを一度に指定することもできる。

レイヤ 目的
meta-arm MACHINEでmicrobit-v1を使用するため
meta-zephyr Zephyrをビルドするため

local.confの修正

MACHINEをmicrobit-v1に設定する。

MACHINE = "microbit-v1"
DL_DIR ?= "${TOPDIR}/../downloads"

ビルド

hello worldをビルドしてみる。

$ bitbake zephyr-helloworld

build/tmp/deploy/images/microbit-v1以下にビルド結果のelfが配置される。

  • zephyr-helloworld-image-microbit-v1.elf
  • zephyr-helloworld-image-microbit-v1.qemuboot.conf
  • zephyr-helloworld-microbit-v1-20210826075435.qemuboot.conf
  • zephyr-helloworld.elf

プログラム本体はzephyr-helloworld.elf

Linuxをビルド

ためしにcore-image-baseをビルドしようとしてみる。

$ bitbake-layers show-layers 
NOTE: Starting bitbake server...
layer                 path                                      priority
==========================================================================
meta                  /home/mickey/work/yocto/x86-hardknott/mb-hardknott/poky/meta  5
meta-poky             /home/mickey/work/yocto/x86-hardknott/mb-hardknott/poky/meta-poky  5
meta-yocto-bsp        /home/mickey/work/yocto/x86-hardknott/mb-hardknott/poky/meta-yocto-bsp  5
meta-arm-toolchain    /home/mickey/work/yocto/x86-hardknott/mb-hardknott/poky/meta-arm/meta-arm-toolchain  5
meta-oe               /home/mickey/work/yocto/x86-hardknott/mb-hardknott/poky/meta-openembedded/meta-oe  6
meta-python           /home/mickey/work/yocto/x86-hardknott/mb-hardknott/poky/meta-openembedded/meta-python  7
meta-arm              /home/mickey/work/yocto/x86-hardknott/mb-hardknott/poky/meta-arm/meta-arm  5
meta-zephyr           /home/mickey/work/yocto/x86-hardknott/mb-hardknott/poky/meta-zephyr  6
mickey@yocto-build:~/work/yocto/x86-hardknott/mb-hardknott/build$ vim ./conf/local.conf 
mickey@yocto-build:~/work/yocto/x86-hardknott/mb-hardknott/build$ bitbake core-image-base
Loading cache: 100% |                                                                | ETA:  --:--:--
Loaded 0 entries from dependency cache.
Parsing recipes: 100% |###############################################################| Time: 0:00:34
Parsing of 2123 .bb files complete (0 cached, 2123 parsed). 3398 targets, 180 skipped, 0 masked, 0 errors.
NOTE: Resolving any missing task queue dependencies
ERROR: Nothing PROVIDES 'virtual/kernel'
linux-yocto PROVIDES virtual/kernel but was skipped: incompatible with machine microbit-v1 (not in COMPATIBLE_MACHINE)
linux-dummy PROVIDES virtual/kernel but was skipped: incompatible with host arm-poky-eabi (not in COMPATIBLE_HOST)
linux-yocto-rt PROVIDES virtual/kernel but was skipped: incompatible with machine microbit-v1 (not in COMPATIBLE_MACHINE)
linux-yocto-tiny PROVIDES virtual/kernel but was skipped: incompatible with machine microbit-v1 (not in COMPATIBLE_MACHINE)
linux-arm64-ack PROVIDES virtual/kernel but was skipped: incompatible with machine microbit-v1 (not in COMPATIBLE_MACHINE)
linux-yocto-dev PROVIDES virtual/kernel but was skipped: incompatible with machine microbit-v1 (not in COMPATIBLE_MACHINE)
linux-yocto PROVIDES virtual/kernel but was skipped: incompatible with machine microbit-v1 (not in COMPATIBLE_MACHINE)
linux-yocto-tiny PROVIDES virtual/kernel but was skipped: incompatible with machine microbit-v1 (not in COMPATIBLE_MACHINE)
linux-yocto-rt PROVIDES virtual/kernel but was skipped: incompatible with machine microbit-v1 (not in COMPATIBLE_MACHINE)
ERROR: Required build target 'core-image-base' has no buildable providers.
Missing or unbuildable dependency chain was: ['core-image-base', 'virtual/kernel']

Summary: There were 2 ERROR messages shown, returning a non-zero exit code.

非対応のマシンということでちゃんとエラーになった。

エミュレータ(qemu)で実行

下記のようにするとqemuでプログラムを実行することができる。

$ runqemu
(... snip ...)

*** Booting Zephyr OS build zephyr-v2.5.0  ***
Hello World! qemu_cortex_m0

ssh越しなどで、うまく文字列が表示されない場合は下記のようにオプションを渡して、シリアルの出力先を標準出力などに変えてやると、うまく行くことがある。

$ runqemu qemux86 qemuparams="-serial mon:stdio"

実機に書き込む

micro:bitの実機にプログラムを書き込む場合は、elfからbinary形式に変換する必要がある。

$ cd tmp/deploy/images/microbit-v1
$ arm-none-eabi-objcopy zephyr-helloworld.elf zephyr-helloworld.bin -O binary

micro:bitUbuntu 20.04のマシンににUSBで接続すると、/media/mickey/MICROBIT/として見えるようになる。

変換したbinary形式のファイルを下記のようにmicro:bitにコピーすると自動的リセットがかかり、新しいプログラムが読み込まれる。

cp ./zephyr-helloworld.bin /media/mickey/MICROBIT/

micro:bitのUSB-UARTは/dev/ttyACM0として見えているので、minicomなどで開く。

minicom -D /dev/ttyACM0

この状態でmicro:bitのリセットボタンを押すと下記のように出力される。

*�*** Booting Zephyr OS build zephyr-v2.5.0  ***
Hello World! qemu_cortex_m0

リセット直後の出力にゴミが入るが、プログラムは正しく動いているようだ。

バイナリファイルについて

実際のところ、bitbakeの結果としてzephyr.binも出来上がっている。 しかし、zephyr-hellworld.bbから読み込まれるzephyr-sample.incで定義されているdo_deployタスクが 下記のようにelfのみをコピーするようになっているので、binは放置されているようだ。

do_deploy () {
    install -D ${B}/zephyr/${ZEPHYR_MAKE_OUTPUT} ${DEPLOYDIR}/${PN}.elf
}

まとめ

Yocto Projectを使用してZephyrのmicro:bit向けバイナリをビルドすることができた。 生成されたバイナリはqemuでも実機でも動作することが確認できた。

実際Zephyrを直接ビルドするよりも、bitbakeのほうが時間かかる。 bitbakeでツールチェインやzephyrのカーネルなど、すべて構築されるのでそこはメリットと言えるかもしれない。

emacs markdown-modeで表を作成する

はじめに

筆者はemacsmarkdownを書く時にはmarkdown-modeのパッケージをインストールして、gfm-modeを使用する。

.emacs/init.elは多分こんな感じ。

;; Markdown mode
(use-package markdown-mode
  :ensure t
  :init
  (add-to-list 'auto-mode-alist '("\\.md$" . gfm-mode)))

表を作る基本

下記のような表を作りたいとする。

番号 項目
1 いちばん
2 にばん

markdownとしては下記のように記述する。

| 番号 | 項目     |
|------|----------|
| 1    | いちばん |
| 2    | にばん   |

これをいちいち手入力するのは結構面倒くさい。

下記のようなテキストを手入力して

|||
|-|

C-iすると表のように整形してくれることに気づいた

|   |   |
|---|---|

そして手入力で

| 番号  |   |
|---|---|

とやったあとでC-iすると、下記のように自動で整形してくれる。

| 番号 |   |
|------|---|

しばらくはこれで表を入力していた。

一括で値を設定したい

まとまったデータをコピペしてきて表にしたい場合、上記のやり方でも結構面倒くさい。

例えば下記のようなまとまったデータがある場合。CSVのデータとか。

番号,項目
1,いちばん
2,にばん
3,さんばん

これをset-markで選択状態にしてC-c C-c |と入力すると下記のようにしてくれる。

| 番号 | 項目     |
| 1    | いちばん |
| 2    | にばん   |
| 3    | さんばん |

その後に2行目に|-|を追加して

| 番号 | 項目     |
|-|
| 1    | いちばん |
| 2    | にばん   |
| 3    | さんばん |

C-iするとこのようになる。

| 番号 | 項目     |
|------|----------|
| 1    | いちばん |
| 2    | にばん   |
| 3    | さんばん |

つまり、markdown-modeで表を作る時はまずはコンマ区切りのデータを並べる。 C-c C-c |で表の形にして、ヘッダと値の分離は|-|+C-iで行う。

まとめ

この作り方を知らない頃はTables Generatorを使用していた。

ただ、これだとデータをオンラインでサーバに送るような気がしていて、仕事で使うのはちょっと心配だった。 ひょっとしたらJavaScriptでブラウザ上で完結していてサーバにデータを送るようなことはしないのかもしれないが。

まとまったデータをCSVにすること自体は割とどのようにでもできるので、 markdown-modeで表を作る時にこのやり方を知っているとかなり便利。

Yocto Project 3.3(Hardknott)で日本語入力

はじめに

Yocto Project 3.3(Hardknott)でラズベリーパイ4を動かすの環境をベースに、Hardknottで日本語入力環境を作成してみる。

かなり古いがyoctoで日本語入力も参考にする。

作業環境の準備

meta-oeをビルド環境に設定する。

$ cd rpi-hardknott
$ source poky/oe-init-build-env build
$ bitbake-layers layerindex-fetch meta-oe

local.confの修正

Yocto Project 3.3(Hardknott)でラズベリーパイ4を動かすで変更したconf/local.confの内容に下記を追加する。

IMAGE_INSTALL_append = " uim-xim uim-utils uim-common uim-gtk2.0 uim-gtk3 uim-anthy"
IMAGE_INSTALL_append = " ttf-vlgothic ttf-sazanami-gothic"
IMAGE_INSTALL_append = " setxkbmap"

IMAGE_LINGUAS = "ja-jp ja-jp.euc-jp"
GLIBC_GENERATE_LOCALES = "ja_JP.UTF-8 ja_JP.EUC-JP"

ビルド

下記のようにcore-image-satoをビルドする。

$ bitbake core-image-sato

ビルドには数時間かかる。

rootfs作成でエラー

最後の最後、core-image-satoのdo_rootfsの処理で下記のエラーが発生する。

Last metadata expiration check: 0:00:01 ago on Mon 05 Jul 2021 03:35:45 PM UTC.
No match for argument: uim-gtk2.0
No match for argument: uim-gtk3
No match for argument: uim-xim
Error: Unable to find a match: uim-gtk2.0 uim-gtk3 uim-xim

uimのレシピで作成されるはずの下記のパッケージが存在しないと言っている。

uimレシピのパッケージ生成状況の確認

まずは下記のコマンドを実行し、uimレシピのdevshellを起動する。

$ bitbake uim -c devshell

自動的にuimのソースディレクトリに移動されるので、次のようにしてパッケージがどのように生成されたかを確認する。

まずはuim-gtk2.0

# tree ../packages-split/uim-gtk2.0/
../packages-split/uim-gtk2.0/

0 directories, 0 files

続いてuim-gtk3

# tree ../packages-split/uim-gtk3/
../packages-split/uim-gtk3/

0 directories, 0 files

最後にgtk-xim

# tree ../packages-split/uim-xim/
../packages-split/uim-xim/

0 directories, 0 files

確かに全てのパッケージが空で生成されている。

config.logの確認

lessでconfig.logを開く。

# less ../build/config.log

gtkで検索してみる。

... (snip) ...
configure:30647: checking for gtk+-2.0 >= 2.2.0 gdk-x11-2.0
configure:30706: result: no
configure:30718: checking for gtk+-2.0 >= 2.4.0 gdk-x11-2.0
configure:30777: result: no
... (snip) ...
configure:30998: checking for gtk+-3.0
configure:31057: result: no

pkg-configでライブラリが見つかっていないように見える。

pkg-configの確認

devshell上でpkg-configを実行してみる。

gtk+-2.0

# pkg-config --libs gtk+-2.0
-lgtk-x11-2.0 -lgdk-x11-2.0 -lpangocairo-1.0 -latk-1.0 -lcairo -lgdk_pixbuf-2.0 -lgio-2.0 -lpangoft2-1.0 -lpango-1.0 -lgobject-2.0 -lglib-2.0 -lharfbuzz -lfontconfig -lfreetype

gtk+-3.0

# pkg-config --libs gtk+-3.0
-lgtk-3 -lgdk-3 -lpangocairo-1.0 -lpango-1.0 -lharfbuzz -latk-1.0 -lcairo-gobject -lcairo -lgdk_pixbuf-2.0 -lgio-2.0 -lgobject-2.0 -lglib-2.0

どちらも見つかる。

本格的に何かがおかしい。

ログを強化する

devshellを抜けて、uimのレシピのdo_configureタスクを実行し直す。

$ bitbake uim -c configure -vvv -f

強化されたログを確認する

devshellに入り直し、log.do_configureを確認する。

# less ../temp/log.do_configure

../uim-1.8.8/configureで検索すると下記のようなログが見つかる。

+ CONFIG_SHELL=/bin/bash ../uim-1.8.8/configure --build=x86_64-linux --host=aarch64-poky-linux --target=aarch64-poky-linux --prefix=/usr --exec_prefix=/usr --bindir=/usr/bin --sbindir=/usr/sbin --libexecdir=/usr/libexec --datadir=/usr/share --sysconfdir=/etc --sharedstatedir=/com --localstatedir=/var --libdir=/usr/lib --includedir=/usr/include --oldincludedir=/usr/include --infodir=/usr/share/info --mandir=/usr/share/man --disable-dependency-tracking --with-libtool-sysroot=/home/mickey/work/yocto/rpi-hardknott/build/tmp/work/cortexa72-poky-linux/uim/1.8.8-r0/recipe-sysroot --disable-emacs --with-libedit=/home/mickey/work/yocto/rpi-hardknott/build/tmp/work/cortexa72-poky-linux/uim/1.8.8-r0/recipe-sysroot/usr --without-scim --without-m17nlib --without-prime --without-canna --without-mana --without-eb --disable-static --enable-nls

これが実際に実行されているconfigureのコマンドラインだと推測される。

情報を増やすためにdevshell上で下記のように実行してみる。ポイントはCONFIG_SHELLに設定するbashの引数に-xを設定することと、標準出力と標準エラー出力の内容をファイルに保存すること。

# cd ../build
# CONFIG_SHELL='/bin/bash -x' ../uim-1.8.8/configure --build=x86_64-linux --host=aarch64-poky-linux --target=aarch64-poky-linux --prefix=/usr --exec_prefix=/usr --bindir=/usr/bin --sbindir=/usr/sbin --libexecdir=/usr/libexec --datadir=/usr/share --sysconfdir=/etc --sharedstatedir=/com --localstatedir=/var --libdir=/usr/lib --includedir=/usr/include --oldincludedir=/usr/include --infodir=/usr/share/info --mandir=/usr/share/man --disable-dependency-tracking --with-libtool-sysroot=/home/mickey/work/yocto/rpi-hardknott/build/tmp/work/cortexa72-poky-linux/uim/1.8.8-r0/recipe-sysroot --disable-emacs --with-libedit=/home/mickey/work/yocto/rpi-hardknott/build/tmp/work/cortexa72-poky-linux/uim/1.8.8-r0/recipe-sysroot/usr --without-scim --without-m17nlib --without-prime --without-canna --without-mana --without-eb --disable-static --enable-nls > configure.txt 2>&1

いろいろ調べた結果下記のコマンドで得られた情報が有効だった。ログの感じからpkg-configコマンドでライブラリを調べているっぽい部分のtestによる比較が、空との比較になっているようだ。

# grep -i 'checking.*gtk' -A10 configure.txt
+ printf '%s\n' 'configure:30623: checking for gtk+-2.0 >= 2.2.0 gdk-x11-2.0'
+ printf %s 'checking for gtk+-2.0 >= 2.2.0 gdk-x11-2.0... '
checking for gtk+-2.0 >= 2.2.0 gdk-x11-2.0... + test -n ''
+ test -n ''
+ pkg_failed=untried
+ test -n ''
+ test -n ''
+ pkg_failed=untried
+ test untried = yes
+ test untried = untried
+ printf '%s\n' 'configure:30682: result: no'
+ printf '%s\n' no
no
... (snip) ...

configureスクリプトの30623行以降の判定分を確認してみる。

{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for gtk+-2.0 >= 2.2.0 gdk-x11-2.0" >&5
printf %s "checking for gtk+-2.0 >= 2.2.0 gdk-x11-2.0... " >&6; }

if test -n "$GTK2_CFLAGS"; then
    pkg_cv_GTK2_CFLAGS="$GTK2_CFLAGS"
 elif test -n "$PKG_CONFIG"; then
    if test -n "$PKG_CONFIG" && \
    { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"gtk+-2.0 >= 2.2.0 gdk-x11-2.0\""; } >&5
  ($PKG_CONFIG --exists --print-errors "gtk+-2.0 >= 2.2.0 gdk-x11-2.0") 2>&5
  ac_status=$?
  printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
  test $ac_status = 0; }; then
  pkg_cv_GTK2_CFLAGS=`$PKG_CONFIG --cflags "gtk+-2.0 >= 2.2.0 gdk-x11-2.0" 2>/dev/null`
                      test "x$?" != "x0" && pkg_failed=yes
else
  pkg_failed=yes
fi
 else
    pkg_failed=untried
fi

下記の変数の内容が空になっていると思われる。

  • GTK2_CFLAGS
  • PKG_CONFIG

PKG_CONFIGはpkg-configコマンドのパスが格納されている必要があるので、これはおかしい。

念の為、devshellでpkg-configのパスを確認する。

# which pkg-config
/home/mickey/work/yocto/rpi-hardknott/build/tmp/work/cortexa72-poky-linux/uim/1.8.8-r0/recipe-sysroot-native/usr/bin/pkg-config

ちゃんとrecipes-sysroot-native以下のコマンドを呼び出している。

どうやら、configureスクリプトのpkg-config検出に問題があるっぽい。

PKG_CONFIGを設定してみる

PKG_CONFIGは環境変数によっても制御できるようなので、手動で設定してみる。

# export PKG_CONFIG=`which pkg-config`
# CONFIG_SHELL='/bin/bash -x' ../uim-1.8.8/configure --build=x86_64-linux --host=aarch64-poky-linux --target=aarch64-poky-linux --prefix=/usr --exec_prefix=/usr --bindir=/usr/bin --sbindir=/usr/sbin --libexecdir=/usr/libexec --datadir=/usr/share --sysconfdir=/etc --sharedstatedir=/com --localstatedir=/var --libdir=/usr/lib --includedir=/usr/include --oldincludedir=/usr/include --infodir=/usr/share/info --mandir=/usr/share/man --disable-dependency-tracking --with-libtool-sysroot=/home/mickey/work/yocto/rpi-hardknott/build/tmp/work/cortexa72-poky-linux/uim/1.8.8-r0/recipe-sysroot --disable-emacs --with-libedit=/home/mickey/work/yocto/rpi-hardknott/build/tmp/work/cortexa72-poky-linux/uim/1.8.8-r0/recipe-sysroot/usr --without-scim --without-m17nlib --without-prime --without-canna --without-mana --without-eb --disable-static --enable-nls > configure.txt 2>&1

実行結果を確認する。

+ printf '%s\n' 'configure:30623: checking for gtk+-2.0 >= 2.2.0 gdk-x11-2.0'
+ printf %s 'checking for gtk+-2.0 >= 2.2.0 gdk-x11-2.0... '
checking for gtk+-2.0 >= 2.2.0 gdk-x11-2.0... + test -n ''
+ test -n /home/mickey/work/yocto/rpi-hardknott/build/tmp/work/cortexa72-poky-linux/uim/1.8.8-r0/recipe-sysroot-native/usr/bin/pkg-config
+ test -n /home/mickey/work/yocto/rpi-hardknott/build/tmp/work/cortexa72-poky-linux/uim/1.8.8-r0/recipe-sysroot-native/usr/bin/pkg-config
+ printf '%s\n' 'configure:30630: $PKG_CONFIG --exists --print-errors "gtk+-2.0 >= 2.2.0 gdk-x11-2.0"'
+ ac_status=0
+ printf '%s\n' 'configure:30633: $? = 0'
+ test 0 = 0
++ /home/mickey/work/yocto/rpi-hardknott/build/tmp/work/cortexa72-poky-linux/uim/1.8.8-r0/recipe-sysroot-native/usr/bin/pkg-config --cflags 
'gtk+-2.0 >= 2.2.0 gdk-x11-2.0'
+ pkg_cv_GTK2_CFLAGS='-pthread -I/home/mickey/work/yocto/rpi-hardknott/build/tmp/work/cortexa72-poky-linux/uim/1.8.8-r0/recipe-sysroot/usr/i
nclude/gtk-2.0 -I/home/mickey/work/yocto/rpi-hardknott/build/tmp/work/cortexa72-poky-linux/uim/1.8.8-r0/recipe-sysroot/usr/include/atk-1.0 -
I/home/mickey/work/yocto/rpi-hardknott/build/tmp/work/cortexa72-poky-linux/uim/1.8.8-r0/recipe-sysroot/usr/include/gtk-2.0 -I/home/mickey/wo
rk/yocto/rpi-hardknott/build/tmp/work/cortexa72-poky-linux/uim/1.8.8-r0/recipe-sysroot/usr/lib/gtk-2.0/include -I/home/mickey/work/yocto/rpi
-hardknott/build/tmp/work/cortexa72-poky-linux/uim/1.8.8-r0/recipe-sysroot/usr/include/pango-1.0 -I/home/mickey/work/yocto/rpi-hardknott/bui
ld/tmp/work/cortexa72-poky-linux/uim/1.8.8-r0/recipe-sysroot/usr/include/harfbuzz -I/home/mickey/work/yocto/rpi-hardknott/build/tmp/work/cor
texa72-poky-linux/uim/1.8.8-r0/recipe-sysroot/usr/include/pango-1.0 -I/home/mickey/work/yocto/rpi-hardknott/build/tmp/work/cortexa72-poky-li
nux/uim/1.8.8-r0/recipe-sysroot/usr/include/fribidi -I/home/mickey/work/yocto/rpi-hardknott/build/tmp/work/cortexa72-poky-linux/uim/1.8.8-r0
/recipe-sysroot/usr/include/harfbuzz -I/home/mickey/work/yocto/rpi-hardknott/build/tmp/work/cortexa72-poky-linux/uim/1.8.8-r0/recipe-sysroot
/usr/include/cairo -I/home/mickey/work/yocto/rpi-hardknott/build/tmp/work/cortexa72-poky-linux/uim/1.8.8-r0/recipe-sysroot/usr/include/pixma
n-1 -I/home/mickey/work/yocto/rpi-hardknott/build/tmp/work/cortexa72-poky-linux/uim/1.8.8-r0/recipe-sysroot/usr/include/uuid -I/home/mickey/
work/yocto/rpi-hardknott/build/tmp/work/cortexa72-poky-linux/uim/1.8.8-r0/recipe-sysroot/usr/include/freetype2 -I/home/mickey/work/yocto/rpi
-hardknott/build/tmp/work/cortexa72-poky-linux/uim/1.8.8-r0/recipe-sysroot/usr/include/libdrm -I/home/mickey/work/yocto/rpi-hardknott/build/
tmp/work/cortexa72-poky-linux/uim/1.8.8-r0/recipe-sysroot/usr/include/libpng16 -I/home/mickey/work/yocto/rpi-hardknott/build/tmp/work/cortex
a72-poky-linux/uim/1.8.8-r0/recipe-sysroot/usr/include/gdk-pixbuf-2.0 -I/home/mickey/work/yocto/rpi-hardknott/build/tmp/work/cortexa72-poky-
linux/uim/1.8.8-r0/recipe-sysroot/usr/include/libmount -I/home/mickey/work/yocto/rpi-hardknott/build/tmp/work/cortexa72-poky-linux/uim/1.8.8
-r0/recipe-sysroot/usr/include/blkid -I/home/mickey/work/yocto/rpi-hardknott/build/tmp/work/cortexa72-poky-linux/uim/1.8.8-r0/recipe-sysroot
/usr/include/glib-2.0 -I/home/mickey/work/yocto/rpi-hardknott/build/tmp/work/cortexa72-poky-linux/uim/1.8.8-r0/recipe-sysroot/usr/lib/glib-2
.0/include'
+ test x0 '!=' x0
+ test -n ''

これまで空だった変数に値が設定され、pkg-configコマンドが実行されているように見える。

# tail config.log
#define GNOME3LOCALEDIR "/usr/share/locale"
#define XLIB_DIR "/usr/share"
#define UIM_PIXMAPSDIR "/usr/share/uim/pixmaps"
#define USE_GTK2 1
#define USE_GTK3 1
#define HAVE_FORKPTY 1
#define UIM_USE_NOTIFY_PLUGINS 1
#define UIM_USE_ERROR_GUARD 1

configure: exit 0

gtk2とgtk3は認識されたっぽい。

修正方法

bbappendを作成する

uimのdo_configureの時点でPKG_CONFIG環境変数が設定されるようにするためにbbappendを作成する。

$ bitbake-layers create-layer meta-local
$ mv ./meta-local ../poky/
$ bitbake-layers add-layer ../poky/meta-local/
$ recipetool newappend -e ../poky/meta-local uim

-eをつけてrecipetool newappendを実行すると、作成されたbbappendファイルがエディタで開かれた状態になるので、下記の内容を追加する。

do_configure_prepend() {
    export PKG_CONFIG="${RECIPE_SYSROOT_NATIVE}/usr/bin/pkg-config"
}

ビルド

$ bitbake uim -f 

パッケージ生成結果の確認

$ bitbake uim -c devshell

devshell上で下記のコマンドを実行する。

# tree uim-gtk* uim-xim
uim-gtk2.0
└── usr
    ├── bin
    │   ├── uim-im-switcher-gtk
    │   ├── uim-input-pad-ja
    │   ├── uim-pref-gtk
    │   ├── uim-toolbar-gtk
    │   └── uim-toolbar-gtk-systray
    └── lib
        └── gtk-2.0
            └── 2.10.0
                └── immodules
                    └── im-uim.so
uim-gtk2.0.shlibdeps [error opening dir]
uim-gtk3
└── usr
    ├── bin
    │   ├── uim-im-switcher-gtk3
    │   ├── uim-input-pad-ja-gtk3
    │   ├── uim-pref-gtk3
    │   ├── uim-toolbar-gtk3
    │   └── uim-toolbar-gtk3-systray
    └── lib
        └── gtk-3.0
            └── 3.0.0
                └── immodules
                    └── im-uim.so
uim-gtk3.shlibdeps [error opening dir]
uim-xim
└── usr
    ├── bin
    │   └── uim-xim
    ├── libexec
    │   ├── uim-candwin-gtk
    │   ├── uim-candwin-gtk3
    │   ├── uim-candwin-horizontal-gtk
    │   ├── uim-candwin-horizontal-gtk3
    │   ├── uim-candwin-tbl-gtk
    │   └── uim-candwin-tbl-gtk3
    └── share
        └── man
            └── man1
                └── uim-xim.1

18 directories, 20 files

必要なファイルが作成されていることがわかる。

日本語入力環境をビルド

core-image-satoをビルドしてみる。

$ bitbake core-image-sato

動作確認

ラズパイを起動し、rootでログインしたあと~/.profileを下記の内容で作成しrebootする。

export LC_ALL=ja_JP.UTF-8
export GTK_IM_MODULE="uim"
export XMODIFIERS="@im=uim-anthy"
uim-xim &
uim-toolbar-gtk-systray &
setxkbmap -layout jp

再起動後、キーボードも日本語配列になり、 「shift+スペース」で日本語入力ができるようになる。

f:id:mickey_happygolucky:20210706090553p:plain
日本語入力の例

まとめ

しばらく放置していたらuimのレシピがまた使えなくなっていた。

おそらくuimのバージョンが上がったことに原因がある。

本来はconfigureスクリプトがなぜpkg-configコマンドを検出しないかを調査し、修正する必要があるが、今回は環境変数PKG_CONFIGを設定することで対処した。

若干修正が必要だが、hardknottでも日本語入力環境を作成することができることがわかった。

Yocto Project 3.3(Hardknott)でラズベリーパイ4を動かす

はじめに

Yocto Project 3.3がリリースされていた。

リリースされた事自体は知っていたが、meta-raspberrypiをビルドする際に、bitbake-layers layerindex-fetchがうまく動かなかったので、しばらく様子を見ていた。

具体的には下記のようなこと。

  • OpenEmbedded Layer Indexとの接続に使用される証明書がエラーになった
  • OpenEmbedded Layer Indexのhardknottブランチにmeta-raspberrypiが登録されていなかった

5/26時点で、これらの問題が解消されたことを確認した。

構築手順

ソース取得

下記のコマンドでソースを取得する。

$ mkdir -p rpi-hardknott
$ cd rpi-hardknott
$ git clone git://git.yoctoproject.org/poky.git -b hardknott

環境変数設定

$ source poky/oe-init-build-env build

自動的にビルドディレクトリに移動される。 これで、bitbake関連のツールが使用可能になる。

レイヤ追加

下記のコマンドでビルド対象にmeta-raspberrypiを追加する。

$ bitbake-layers layerindex-fetch meta-raspberrypi

local.confの修正

MACHINEをraspberrypi4-64に設定し、UARTを有効化する。

MACHINE = "raspberrypi4-64"
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 = ""

# connman
IMAGE_INSTALL_append = " connman \
                 connman-client \
"

ビルド

core-image-baseをビルドする。

$ bitbake core-image-base

書き込み

bmaptoolで書き込む。

$ sudo bmaptool copy core-image-base-raspberrypi4.wic.bz2 /dev/sdX

/dev/sdXは環境に応じて適宜読み替える。

起動

OSを書き込んだマイクロSDカードをラズベリーパイ4に挿入し起動する。

rootでログインしたあと下記のコマンドで環境を確認する。

# cat /etc/os-release
ID=poky
NAME="Poky (Yocto Project Reference Distro)"
VERSION="3.3.1 (hardknott)"
VERSION_ID=3.3.1
PRETTY_NAME="Poky (Yocto Project Reference Distro) 3.3.1 (hardknott)"
# uname -a
Linux raspberrypi4-64 5.10.31-v8 #1 SMP PREEMPT Fri Apr 23 15:16:49 UTC 2021 aarch64 GNU/Linux

hardknottが起動したことが確認できた。

まとめ

3.3がリリースされていた。

リリース直後はbitbake-layers layerindex-fetchがうまく動作しないことがあるということがわかった。

ユーザーが使用する機能としては便利になった反面、正しく動作する環境を提供するコストは高くなったのかもしれない。

開発者の皆さんに感謝。