みつきんのメモ

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

Yocto Projectでベアメタル

はじめに

久々にベアメタル熱が上がってきた。 メガマニュアルには下記のような記述があり、baremetalのビルドができそう。

TCLIBC
Specifies the GNU standard C library (libc) variant to use during the build process.

You can select “glibc”, “musl”, “newlib”, or “baremetal”.

OpenEmbedded-Coreにはbaremetal-helloworldというレシピが存在する。 この大本となるリポジトリには下記のようにビルド手順が示されており、上記の機能を使用しているようだ。

$ echo "MACHINE = \"qemuarm64\"" >> ./conf/local.conf
$ echo "TCLIBC = \"baremetal\"" >> ./conf/local.conf

このビルド手順はScarthgap以前(具体的にはdunfell or kirkstoneの時代)のものなので、今回はwrynose環境でビルドしてみる。

環境構築

作業ディレクトリ

~/yocto/wrynoseを作業ディレクトリとする。

$ mkdir -p ~/yocto/wrynose
$ cd ~/yocto/wrynose

bitbakeリポジトリの取得

bitbake-setupを実行するためにbitbakeのリポジトリを取得する。

$ git clone https://git.openembedded.org/bitbake -b yocto-6.0

作業環境を構築する

bitbake-setup initを実行して作業環境(=セットアップ)を作成する。

top-dir-nameを「yocto-builds」に変更する。

setup-dir-nameを「poky-wrynose-baremetal」に設定する。

$ ./bitbake/bin/bitbake-setup \
    --setting default top-dir-name "yocto-builds" \
    init --non-interactive poky-wrynose poky distro/poky machine/qemuarm \
    --setup-dir-name poky-wrynose-baremetal

BitBake環境を設定する

init-build-envを実行する。

$ source yocto-builds/poky-wrynose-baremetal/build/init-build-env

local.confの修正

conf/local.confに以下の内容を記述する。

TCLIBC = "baremetal"

ビルド

$ bitbake baremetal-helloworld

動作確認

世界に挨拶した。

$ runqemu nographic nonetwork
runqemu - INFO - Running bitbake -e  ...
runqemu - INFO - Continuing with the following parameters:
KERNEL: [/home/mickey/yocto/wrynose/yocto-builds/poky-wrynose-baremetal/build/tmp/deploy/images/qemuarm/baremetal-helloworld-image-qemuarm.bin]
MACHINE: [qemuarm]
FSTYPE: [bin]
ROOTFS: [/home/mickey/yocto/wrynose/yocto-builds/poky-wrynose-baremetal/build/tmp/deploy/images/qemuarm/baremetal-helloworld-image-qemuarm.bin]
Disabled. Changes on rootfs will be kept after QEMU shutdown.
CONFFILE: [/home/mickey/yocto/wrynose/yocto-builds/poky-wrynose-baremetal/build/tmp/deploy/images/qemuarm/baremetal-helloworld-image-qemuarm-20260801075737.qemuboot.conf]

runqemu - INFO - Running /home/mickey/yocto/wrynose/yocto-builds/poky-wrynose-baremetal/build/tmp/work/x86_64-linux/qemu-helper-native/1.0/recipe-sysroot-native/usr/bin/qemu-system-arm -nic none -object rng-random,filename=/dev/urandom,id=rng0 -device virtio-rng-pci,rng=rng0 -drive id=disk0,file=/home/mickey/yocto/wrynose/yocto-builds/poky-wrynose-baremetal/build/tmp/deploy/images/qemuarm/baremetal-helloworld-image-qemuarm.bin,if=none,format=raw -device virtio-blk-device,drive=disk0 -device qemu-xhci -device usb-tablet -device usb-kbd -nographic  -machine virt,highmem=off -cpu cortex-a15 -smp 4 -m 256 -serial mon:stdio -serial null -nographic -device virtio-gpu-pci -kernel /home/mickey/yocto/wrynose/yocto-builds/poky-wrynose-baremetal/build/tmp/deploy/images/qemuarm/baremetal-helloworld-image-qemuarm.bin -append 'root=/dev/vda rw  mem=256M console=ttyAMA0 console=hvc0 swiotlb=0 '

runqemu - INFO - Host uptime: 603285.94

Hello OpenEmbedded on ARM!

レシピ

このレシピはOpenEmbedded-Coreで提供しているQEMU関連のマシン全てに対応している。

実際にレシピを読むとわかるが、マシンでのオーバーライドがたくさん記述されている。

baremetal-helloworld_git.bb

今回はqemuarmのマシンを設定しているので関連する部分だけ抜粋する

... (snip) ...
 7 SRCREV = "db2bf750eaef7fc0832e13ada8291343bbcc3afe"
 8 PV = "0.1+git"
 9 
10 SRC_URI = "git://github.com/ahcbb6/baremetal-helloqemu.git;protocol=https;branch=master"
11 UPSTREAM_CHECK_COMMITS = "1"
12 
13 # The following variables should be set to accomodate each application
14 BAREMETAL_BINNAME ?= "hello_baremetal_${MACHINE}"
15 IMAGE_LINK_NAME ?= "baremetal-helloworld-image-${MACHINE}"
16 IMAGE_NAME_SUFFIX ?= ""
17 
18 # Baremetal-Image creates the proper wiring, assumes the output is provided in
19 # binary and ELF format, installed on ${base_libdir}/firmware/ , we want a
20 # package to be created since we might have some way of updating the baremetal
21 # firmware from Linux
22 inherit baremetal-image
... (snip) ...
27 # These parameters are app specific for this example
28 # This will be translated automatically to the architecture and
29 # machine that QEMU uses on OE, e.g. -machine virt -cpu cortex-a57
30 # but the examples can also be run on other architectures/machines
31 # such as vexpress-a15 by overriding the setting on the machine.conf
32 COMPATIBLE_MACHINE = "qemuarmv5|qemuarm|qemuarm64|qemuriscv64|qemuriscv32|qemux86|qemux86-64"
33 
... (snip) ...
36 BAREMETAL_QEMUARCH:qemuarm = "arm"
... (snip) ...
43 EXTRA_OEMAKE:append = " QEMUARCH=${BAREMETAL_QEMUARCH} V=1"
... (snip) ...
50 # Install binaries on the proper location for baremetal-image to fetch and deploy
51 do_install(){
52     install -d ${D}/${base_libdir}/firmware
53     install -m 755 ${B}/build/hello_baremetal_${BAREMETAL_QEMUARCH}.bin ${D}/${base_libdir}/firmware/${BAREMETAL_BINNAME}.bin
54     install -m 755 ${B}/build/hello_baremetal_${BAREMETAL_QEMUARCH}.elf ${D}/${base_libdir}/firmware/${BAREMETAL_BINNAME}.elf
55 }
56 
57 FILES:${PN} += " \
58     ${base_libdir}/firmware/${BAREMETAL_BINNAME}.bin \
59     ${base_libdir}/firmware/${BAREMETAL_BINNAME}.elf \
60 "
... (snip) ...

重要なポイントにはしっかりとコメントが記述されている。

最も重要なポイントとしては下記。

  • 13〜16行目の変数の定義
  • 22行目のbaremetal-imageクラスの継承

残りの部分はお約束の部分かアップストリームのソースコードの作りに依存する部分となる。

ただし、baremetal-imageクラスではbinとelfのバイナリが出力されるのを期待している。

baremetal-imageクラス

実装の詳細は省くが、やっていることは下記。

  1. binとelfをDEPLOY_DIR_IMAGEにコピー
  2. binを使ってrunqemuできるようにパラメータを調整
  3. imageクラスのタスク構成に準拠するように各種調整(image.bbclassの継承はしていない)

ベアメタルをやっていく上では1の機能が一番重要。 LinuxのカーネルやルートFSを作らずに、OpenEmbedded-Coreの仕掛けの上でbinとelfをDEPLOY_DIR_IMAGEに出力してくれるのは助かる。

まとめ

baremetal-imageクラスを使えばYocto Project環境でもベアメタルができることがわかった。 ツールチェーンを自前で用意しなくても良いのはかなり楽。 bitbakeでベアメタルのbinとelfが出力されるようになるのは私としてはありがたい。

本来の目的であるベアメタル熱のためにbaremetal-helloworldの実際のプログラムについては今後触れる。

Yocto Project Wrynoseのmeta-zephyrでmicro:bit v2のサンプルを動かす

はじめに

Zephyrでmicro:bit v2のサンプルを動かす

シリーズもの

  1. Yocto Project Wrynoseでmeta-zephyrを試す
  2. Yocto Project Wrynoseのmeta-zephyrでmicro:bit v2を動かす

作業環境

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

BitBake環境の設定

作業場所への移動とBitBakeの環境設定を行う

$ cd ~/yocto/wrynose
$ source ./yocto-builds/zephyr-master/build/init-build-env

マシン定義

作業レイヤの作成

meta-zephyr-workを作成する。

$ bitbake-layers create-layer -p 7 -a ../layers/meta-zephyr-work

マシン定義の作成

micro:bit v2は「bbc_microbit_v2」として定義されている。

Yocto Projectの環境ではマシン名は"_"ではなく"-"で区切るので「bbc-microbit-v2」とする。

$ mkdir -p ../layers/meta-zephyr-work/conf/machine

meta-zephyr-work/conf/machine/bbc-microbit-v2.confを以下の内容で作成する。

#@TYPE: Machine
#@NAME: bbc_microbit_v2

#@DESCRIPTION: Machine configuration for BBC micro:bit v2 Board.

require conf/machine/include/nrf52.inc
ZEPHYR_BOARD = "bbc_microbit_v2"

micro:bit v2ではDAPLinkが使用できるので、pyocdなどの設定は特に行わない。

マシンの切り替え

bitbake-setupの環境ではマシンはOE_FRAGMENTで設定するのでこれをbbc-microbit-v2に切り替える。

$ bitbake-config-build enable-fragment machine/bbc-microbit-v2

変更できたかの確認は下記のようにする。

$ bitbake-config-build list-fragments
... (snip) ...
Enabled built-in fragments:
distro/zephyr   Sets DISTRO = "zephyr"
machine/bbc-microbit-v2 Sets MACHINE = "bbc-microbit-v2"
... (snip) ...

sourdのレシピの作成

$ mkdir -p ../layers/meta-zephyr-work/recipes-kernel/zephyr-kernel
$ touch ../layers/meta-zephyr-work/recipes-kernel/zephyr-kernel/zephyr-microbit-sound.bb

../layers/meta-zephyr-work/recipes-kernel/zephyr-kernel/zephyr-microbit-sound.bbを以下の内容で作成する。

inherit zephyr-sample

ZEPHYR_SRC_DIR = "${ZEPHYR_BASE}//samples/boards/bbc/microbit/sound"

do_configure:prepend:bbc-microbit-v2() {
    bbnote "Injecting custom Kconfig options"
    echo "CONFIG_ENTROPY_GENERATOR=y" >> ${ZEPHYR_SRC_DIR}/prj.conf
}

pongのレシピの作成

$ mkdir -p ../layers/meta-zephyr-work/recipes-kernel/zephyr-kernel
$ touch ../layers/meta-zephyr-work/recipes-kernel/zephyr-kernel/zephyr-microbit-pong.bb

../layers/meta-zephyr-work/recipes-kernel/zephyr-kernel/zephyr-microbit-pong.bbを以下の内容で作成する。

inherit zephyr-sample

ZEPHYR_SRC_DIR = "${ZEPHYR_BASE}//samples/boards/bbc/microbit/pong"

ビルド

作成したレシピをビルドする。これはsoundの例

$ bitbake zephyr-microbit-sound

書き込み

Ubuntu 26.04ではこうなる。

cp ./tmp/deploy/images/bbc-microbit-v2/zephyer-microbit-sound-bbc-microbit-v2.bin /run/media/${USER}/MICROBIT/

まとめ

micro:bit v2のsoundのサンプルは簡単に動かせた。 pongの様なゲームとかも動かしてみると楽しみが増える。

今度はZephyrのソースツリーの外のアプリもトライする。

Yocto Project Wrynose 日本語入力

はじめに

前回 core-image-satoで日本語表示をさせたので、今回は日本語入力させる。

日本語入力のためのレシピはmeta-oeに以下のものがある。

  • uim
  • anthy

今となっては古く感じるがwrynoseになってもドロップせずに残っている。

mozcなどの今どきっぽいものはレシピにないので、とりあえずこれらを使用して日本語入力を実現する。

実現のポイント

uimのレシピ

PKG_CONFIGの設定

これと同じ原因で、下記の設定が必要となっている。

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

これがないと一部のuimのサブパッケージが空で作成される。

pkg_postinst/pkg_prermの実装

これらのscrptletについては実機で実行するための古いイディオムが禁止になっており、 同等のことを行うにはpkg_postinst_ontargetもしくはpkg_prerm_ontargetを使用する必要がある。

多分uimを使用して日本語入力する人が居なすぎて、このあたりがメンテナンスされずにそのまま残っている。

ここまでくるとuimのレシピを直接修正するべきだが、今回はオーバーライドを駆使して以下のようにすることで回避する。

  • pkg_postinst:uim-anthy / pkg_prerm:uim-anthyを空の実装にする
  • pkg_postinst_ontarget:uim-anthy / pkg_prerm_ontarget:uim-anthyを適切に実装する

IMの起動タイミング

もう一つハマりポイントは、IMを起動するための環境変数の設定とプロセスの起動をどのタイミングで行うかということ。

以前は、手作業で~/.profileを書いて実現したが、wrynoseのデフォルトではルートFSがzstdで圧縮されているため、 runqemuするときにsnapshotオプションをつけている。

ファイルシステムの書き換えができない前提で予め組み込んでおく必要がある。

その場合、安直にユーザーのホームディレクトリにファイルを配置してしまうと汎用性がなくなる。

X11のアプリケーションの起動を伴うためXsessionから起動させるのが正しい。なので、/etc/X11/Xsession.dにスクリプトを配置して自動的に処理を実行させる。

このディレクトリ内のファイル名に10some.shのようにする事で起動順序を制御できる。 後ろの方で良いが、90XWindowManager.shの中でexec呼び出しがあり処理が戻ってこなくなるため、89より前に処理を実行する必要がある。

環境構築

作業ディレクトリ

~/yocto/wrynoseを作業ディレクトリとする。

$ mkdir -p ~/yocto/wrynose
$ cd ~/yocto/wrynose

bitbakeリポジトリの取得

bitbake-setupを実行するためにbitbakeのリポジトリを取得する。

$ git clone https://git.openembedded.org/bitbake -b yocto-6.0

作業環境を構築する

bitbake-setup initを実行して作業環境(=セットアップ)を作成する。

top-dir-nameを"yocto-builds"に変更する。

setup-dir-nameを明示的に「poky-wrynose」に設定する。

$ ./bitbake/bin/bitbake-setup \
    --setting default top-dir-name "yocto-builds" \
    init --non-interactive poky-wrynose poky distro/poky machine/qemuarm64 \
    --setup-dir-name poky-wrynose

BitBake環境を設定する

init-build-envを実行する。

$ source yocto-builds/poky-wrynose/build/init-build-env

ログイン設定

rootでパスワードなしログインの設定を有効化する。

$ bitbake-config-build enable-fragment core/yocto/root-login-with-empty-password

meta-oeの取得

日本語フォントのレシピがmeta-oeに含まれているので取得する。

$ bitbake-layers layerindex-fetch meta-oe -f ../layers

作業レイヤの作成

レイヤを作成する。

$ bitbake-layers create-layer  -p 10 -a ../layers/meta-work

uimレシピの修正

uimのアペンドファイルを作成する。

$ recipetool newappend ../layers/meta-work uim

../layers/meta-work/recipes-support/uim/uim_1.9.6.bbappendに下記の内容を追加する。

export PKG_CONFIG = "${RECIPE_SYSROOT_NATIVE}/usr/bin/pkg-config"
                       
pkg_postinst:uim-anthy:forcevariable() {
}

pkg_prerm:uim-anthy:forcevariable() {
}

pkg_postinst_ontarget:uim-anthy() {
    uim-module-manager --register anthy --path ${datadir}/uim
}

pkg_prerm_ontarget:uim-anthy() {
    uim-module-manager --path ${datadir}/uim --unregister anthy
}

IM起動レシピの作成

レシピの配置場所を作成する。

$ mkdir -p ../layers/meta-work/recipes-graphics/x11-common/xprofile-im-ja

../layers/meta-work/recipes-graphics/x11-common/xprofile-im-ja.bbを以下の内容で作成する。

SUMMARY = "X11 profile for Japanese Input"
SRC_URI = "file://init-im.sh"

LICENSE = "CLOSED"

S = "${UNPACKDIR}"

do_install:append() {
    install -d -m 0755 ${D}${sysconfdir}/X11/Xsession.d
    install ${S}/init-im.sh ${D}${sysconfdir}/X11/Xsession.d/88init-im.sh
}

FILES:${PN} = "${sysconfdir}/X11/Xsession.d"

RDEPENDS:${PN} = " \
  uim-common \
  uim-utils \
  uim-xim \
  uim-gtk3 \
  uim-anthy \
  setxkbmap \
"

../layers/meta-work/recipes-graphics/x11-common/xprofile-im-ja/init-im.shを以下の内容で作成する。

#!/bin/sh
export LANG=ja_JP.UTF-8
export LC_ALL=ja_JP.UTF-8
export GTK_IM_MODULE="uim"
export XMODIFIERS="@im=uim"

setxkbmap -layout jp

uim-xim &
uim-toolbar-gtk3-systray &

イメージレシピの作成

local.confにパッケージ追加などの処理を書いてもいいが、今回はイメージレシピを作成する。

レシピの格納場所を作成する。

$ mkdir -p ../layers/meta-work/recipes-sato/images

../layers/meta-work/recipes-sato/images/core-image-sato-ja.bbを以下の内容で作成する。

require recipes-sato/images/core-image-sato.bb

DESCRIPTION = "Japanese Custom image based on core-image-sato"

IMAGE_LINGUAS = "ja-jp"
IMAGE_INSTALL:append = " ttf-sazanami-gothic xprofile-im-ja"

ビルド

作成したイメージレシピをビルドする。

$ bitbake core-image-sato-ja

動作確認

「shift + space」で日本語に切り替えできる。

まとめ

core-image-satoで日本語入力できるようにした。久々にcore-image-satoをさわってみて以下の感想。

  • uimのレシピがほぼメンテされいない
  • ibusはあるけど、anthyに替わるIMEが無い
  • 今となってはcore-image-satoをベースに開発することはなさそう

Yocto Project Wrynose 日本語表示

はじめに

前回 core-image-satoを作ったので、日本語表示させる。

環境構築

作業ディレクトリ

~/yocto/wrynoseを作業ディレクトリとする。

$ mkdir -p ~/yocto/wrynose
$ cd ~/yocto/wrynose

bitbakeリポジトリの取得

bitbake-setupを実行するためにbitbakeのリポジトリを取得する。

$ git clone https://git.openembedded.org/bitbake -b yocto-6.0

作業環境を構築する

bitbake-setup initを実行して作業環境(=セットアップ)を作成する。

top-dir-nameを"yocto-builds"に変更する。

setup-dir-nameを明示的に「poky-wrynose」に設定する。

$ ./bitbake/bin/bitbake-setup \
    --setting default top-dir-name "yocto-builds" \
    init --non-interactive poky-wrynose poky distro/poky machine/qemuarm64 \
    --setup-dir-name poky-wrynose

BitBake環境を設定する

init-build-envを実行する。

$ source yocto-builds/poky-wrynose/build/init-build-env

ログイン設定

rootでパスワードなしログインの設定を有効化する。

$ bitbake-config-build enable-fragment core/yocto/root-login-with-empty-password

meta-oeの取得

日本語フォントのレシピがmeta-oeに含まれているので取得する。

$ bitbake-layers layerindex-fetch meta-oe -f ../layers

ロケールの設定

X11環境で日本語表示を有効化するには、X11を起動するタイミングで下記の環境変数が設定されている必要がある。

export LANG=ja_JP.UTF-8
export LC_ALL=ja_JP.UTF-8

Satoの環境では通常、xserver-nodm-initによってX11が初期化、起動される。

xserver-nodm-initから/etc/profileが実行され、/etc/profile.dに配置された*.shを直接実行(source)するようになっている。

なので、/etc/profile.d/locale.shなどを作ってルートFS上に配置してやれば良い。

配置の方法は様々あるが、今回はX11のprofile設定用にレシピを作成する。

作業レイヤ

以下で作業レイヤを作成する。

bitbake-layers create-layer -p 10 -a ../layers/meta-work

レシピの作成

配置場所とレシピファイルを作成する。

$ mkdir -p ../layers/meta-work/recipes-graphics/x11-common/xprofile-ja
$ touch ../layers/meta-work/recipes-graphics/x11-common/xprofile-ja.bb
$ touch ../layers/meta-work/recipes-graphics/x11-common/xprofile-ja/locale.sh

../layers/meta-work/recipes-graphics/x11-common/xprofile-ja.bbに以下の内容を記述する。

LICENSEは本来きちんと設定するべきだが、簡単のためここでは"CLOSED"にする。

SUMMARY = "X11 profile for Japanese"
SRC_URI = "file://locale.sh"

LICENSE = "CLOSED"

S = "${UNPACKDIR}"

do_install:append() {
    install -d -m 0755 ${D}/${sysconfdir}/profile.d
    install ${S}/locale.sh ${D}/${sysconfdir}/profile.d
}

FILES:${PN} = "${sysconfdir}/profile.d"

../layers/meta-work/recipes-graphics/x11-common/xprofile-ja/locale.shに以下の内容を記述する。

export LANG=ja_JP.UTF-8
export LC_ALL=ja_JP.UTF-8

local.confの設定

local.confに以下の内容を追加する。

IMAGE_LINGUAS = "ja-jp"
IMAGE_INSTALL:append = " ttf-sazanami-gothic xprofile-ja"

ビルド

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

$ bitbake core-image-sato

動作確認

日本語表示可能なものは日本語で表示されている。

まとめ

wrynoseのcore-image-satoの環境で日本語表示を行った。

日本語表示をするためには以下のことをする必要がある。

  • IMAGE_LINGUASの設定
  • 日本語フォントの設定
  • X11初期化時のロケールの設定

ロケールの設定のために今回はレシピを作成したが、 base-filesやxserver-nodm-initなどのレシピにbbappendを作成するなど簡易的に実装する方法もある。

local.confでの実装ではなくイメージレシピを作成する場合などを考えると、 レシピにしておいたほうが取り回しは良いと思う。

Yocto Project リモートのQEMUにVNC

はじめに

BitBake環境がリモートにある場合でcore-image-satoなどのGUI環境にvncで接続する。

動作は重目だが、リモートでデバッグできるようになる。

環境構築

作業ディレクトリ

~/yocto/wrynoseを作業ディレクトリとする。

$ mkdir -p ~/yocto/wrynose
$ cd ~/yocto/wrynose

bitbakeリポジトリの取得

bitbake-setupを実行するためにbitbakeのリポジトリを取得する。

$ git clone https://git.openembedded.org/bitbake -b yocto-6.0

作業環境を構築する

bitbake-setup initを実行して作業環境(=セットアップ)を作成する。

top-dir-nameを"yocto-builds"に変更する。

setup-dir-nameを明示的に「poky-wrynose」に設定する。

$ ./bitbake/bin/bitbake-setup \
    --setting default top-dir-name "yocto-builds" \
    init --non-interactive poky-wrynose poky distro/poky machine/qemuarm64 \
    --setup-dir-name poky-wrynose

BitBake環境を設定する

init-build-envを実行する。

$ source yocto-builds/poky-wrynose/build/init-build-env

ログイン設定

rootでパスワードなしログインの設定を有効化する。

$ bitbake-config-build enable-fragment core/yocto/root-login-with-empty-password

ビルド

bitbakeを実行する。

$ bitbake core-image-sato

動作確認

イメージ形式

最近はIMAGE_FSTYPESのデフォルトが"zstd"形式で圧縮されている。

$ bitbake core-image-minimal -e |  grep '^IMAGE_FSTYPES='
IMAGE_FSTYPES=" tar.zst ext4.zst"

このおかげでrunqemuする時にsnapshotが必要になる。

コンソール起動

core-image-satoでもコンソールで起動できる。

$ runqemu snapshot nographic

VNCサーバでの起動

publicvncでVNCサーバとして起動する。5900番ポートにアクセスできれば接続できる。

$ runqemu snapshot publicvnc 
... (snip) ...
runqemu - INFO - Host uptime: 77316.74

接続

リモートからRemminaで接続した例。

まとめ

リモートからQEMUのGUIにアクセスできると、多少動作が重くても日本語表示など見た目だけ確認したい場合に役に立つ。

Yocto Project Wrynose ラズパイ向けのpoky-tinyをSquashFSでブートする

はじめに

シリーズ物

ext4では8MiBよりも小さいルートFSが作成できないらしい。

今回はSquashFSでルートFSを作成する。

ブートパーティションも必要なものだけにしてどこまで小さくできるか実験する。

環境構築

作業ディレクトリ

~/yocto/wrynoseを作業ディレクトリとする。

$ mkdir -p ~/yocto/wrynose
$ cd ~/yocto/wrynose

bitbakeリポジトリの取得

bitbake-setupを実行するためにbitbakeのリポジトリを取得する。

$ git clone https://git.openembedded.org/bitbake -b yocto-6.0

作業環境を構築する

bitbake-setup initを実行して作業環境(=セットアップ)を作成する。

top-dir-nameを前回の環境に合わせる。

setup-dir-nameを明示的に「poky-tiny-wrynose-rpi」に設定する。

$ ./bitbake/bin/bitbake-setup \
    --setting default top-dir-name "yocto-builds" \
    init --non-interactive poky-wrynose poky distro/poky-tiny machine/qemuarm64 \
    --setup-dir-name poky-tiny-wrynose-rpi

BitBake環境を設定する

init-build-envを実行する。

$ source yocto-builds/poky-tiny-wrynose-rpi/build/init-build-env

meta-raspberrypi

layerindexが復活した。

meta-raspberrypiにwrynoseブランチが切られたので下記のコマンドで取得できる。

$ bitbake-layers layerindex-fetch meta-raspberrypi -f ../layers

マシンの設定

MACHINEをraspberrypi4-64に設定する。

$ bitbake-config-build enable-fragment machine/raspberrypi4-64

ログイン設定

rootでパスワードなしログインの設定を有効化する。

$ bitbake-config-build enable-fragment core/yocto/root-login-with-empty-password

SquashFSでルートFSを作成

作業レイヤの作成

$ bitbake-layers create-layer  -p 10 -a ../layers/meta-work

wksファイルの作成

$ mkdir -p ../layers/meta-work/files/wic
$ touch ../layers/meta-work/files/wic/sdimage-raspberrypi-small.wks

../layers/meta-work/files/wic/sdimage-raspberrypi-small.wksに以下の内容を追加。

part /boot --source bootimg-partition --ondisk mmcblk0 --fstype=vfat --label boot --active --align 4096
part / --source rootfs --ondisk mmcblk0 --fstype=squashfs --align 4096

カーネルコンフィグを修正するために/tmp/embed-squashfs.cfgを以下の内容で作成する。

# CONFIG_EXT4_FS is not set
CONFIG_JBD2=m
CONFIG_SQUASHFS=y

recipetoolでレシピに登録する。

$ recipetool appendsrcfile ../layers/meta-work linux-raspberrypi /tmp/embed-squashfs.cfg

local.confの修正

カーネルの設定とwicイメージの追加。

デバッグシリアルの有効化。

SquashFSのための設定と、ブートパーティションへ必要なものだけ書き込む設定。

PREFERRED_PROVIDER_virtual/kernel:${MACHINE} = "linux-raspberrypi"
IMAGE_FSTYPES:append:${MACHINE} = " wic wic.bmap"

ENABLE_UART = "1"

WKS_FILE = "sdimage-raspberrypi-small.wks"

CMDLINE_ROOT_FSTYPE = "squashfs"

IMAGE_BOOT_FILES = " \
    bootfiles/start4.elf;start4.elf \
    bootfiles/fixup4.dat;fixup4.dat \
    bootfiles/config.txt;config.txt \
    bootfiles/cmdline.txt;cmdline.txt \
    bcm2711-rpi-4-b.dtb \
    Image;kernel8.img \
"

イメージをビルドする

$ bitbake core-image-minimal

動作確認

ちゃんとログインできる。

Poky Tiny 6.0.2 raspberrypi4-64 /dev/ttyS0

raspberrypi4-64 login: root

WARNING: Poky is a reference Yocto Project distribution that should be used for
testing and development purposes only. It is recommended that you create your
own distribution for production use.

login[109]: root login on 'ttyS0'
root@raspberrypi4-64:~#

サイズ

ルートFS

ルートFSは約1MiBまで絞れた。

1012K Jul 11 12:22 core-image-minimal-raspberrypi4-64.rootfs-20260711030824.squashfs

wicイメージのサイズ

ルートFSのサイズの割に大きく見える。

57M Jul 11 12:22 core-image-minimal-raspberrypi4-64.rootfs-20260711030824.wic

wicイメージはfdiskでレイアウトが確認できる。 ブートパーティションが、50MiB近くある。

$ fdisk -l core-image-minimal-raspberrypi4-64.rootfs-20260711030824.wic
ディスク core-image-minimal-raspberrypi4-64.rootfs-20260711030824.wic: 56.99 MiB, 59756544 バイト, 116712 セクタ
単位: セクタ (1 * 512 = 512 バイト)
セクタサイズ (論理 / 物理): 512 バイト / 512 バイト
I/O サイズ (最小 / 推奨): 512 バイト / 512 バイト
ディスクラベルのタイプ: dos
ディスク識別子: 0x076c4a2a

デバイス                                                      起動 開始位置 終了位置 セクタ サイズ Id タイプ
core-image-minimal-raspberrypi4-64.rootfs-20260711030824.wic1 *        8192   107321  99130  48.4M  c W95 FAT32 (LBA)
core-image-minimal-raspberrypi4-64.rootfs-20260711030824.wic2        114688   116711   2024  1012K 83 Linux

ブートパーティションの大半はカーネルが締めている(約25MiB)。

-rwxr-xr-x    1 root     root       55.1K Apr  5  2011 bcm2711-rpi-4-b.dtb
-rwxr-xr-x    1 root     root          97 Apr  5  2011 cmdline.txt
-rwxr-xr-x    1 root     root        2.5K Apr  5  2011 config.txt
-rwxr-xr-x    1 root     root        5.3K Apr  5  2011 fixup4.dat
-rwxr-xr-x    1 root     root       25.0M Apr  5  2011 kernel8.img
-rwxr-xr-x    1 root     root        2.2M Apr  5  2011 start4.elf

まとめ

SquashFSでルートFSが1MiB程度まで小さくなることがわかった。

ブートパーティションから不要なファイルを削除しても約50MiB程度。 カーネルが大半を締めているので不要なコンフィグをオフにしていけばまだ絞れそう。

実用性はともかくとして、ルートFSが1MiB程度ならNORフラッシュとかにも載せられそう。

Yocto Project Wrynoseのpoky-tinyでラズベリー・パイ4を動かす

はじめに

シリーズ物

環境構築

作業ディレクトリ

~/yocto/wrynoseを作業ディレクトリとする。

$ mkdir -p ~/yocto/wrynose
$ cd ~/yocto/wrynose

bitbakeリポジトリの取得

bitbake-setupを実行するためにbitbakeのリポジトリを取得する。

$ git clone https://git.openembedded.org/bitbake -b yocto-6.0

作業環境を構築する

bitbake-setup initを実行して作業環境(=セットアップ)を作成する。

top-dir-nameを前回の環境に合わせる。

setup-dir-nameを明示的に「poky-tiny-wrynose-rpi」に設定する。

$ ./bitbake/bin/bitbake-setup \
    --setting default top-dir-name "yocto-builds" \
    init --non-interactive poky-wrynose poky distro/poky-tiny machine/qemuarm64 \
    --setup-dir-name poky-tiny-wrynose-rpi

BitBake環境を設定する

init-build-envを実行する。

$ source yocto-builds/poky-tiny-wrynose-rpi/build/init-build-env

meta-raspberrypi

執筆時点(2026/06/23)ではlayerindex-fetchが何故か403(Forbidden)になるのでgitで取得する。

$ pushd ../layers
$ git clone http://git.yoctoproject.org/meta-raspberrypi
$ popd

ビルド対象に追加する。

$ bitbake-layers add-layer ../layers/meta-raspberrypi

マシンの設定

MACHINEをraspberrypi4-64に設定する。

$ bitbake-config-build enable-fragment machine/raspberrypi4-64

ログイン設定

rootでパスワードなしログインの設定を有効化する。

$ bitbake-config-build enable-fragment core/yocto/root-login-with-empty-password

local.confの修正

poky-tinyが上書きしてしまうカーネルの設定をラズパイ向けにオーバーライドする。

またpoky-tinyではIMAGE_FSTYPESをcpio.gzに絞ってしまうので、wicイメージを作成できるようにオーバーライドする。

デバッグシリアルを有効化するための設定もしておく。

PREFERRED_PROVIDER_virtual/kernel:${MACHINE} = "linux-raspberrypi"
IMAGE_FSTYPES:append:${MACHINE} = " ext4 wic wic.bmap"

ENABLE_UART = "1"

イメージをビルドする

$ bitbake core-image-minimal

動作確認

ちゃんと起動した。

Poky Tiny 6.0.1 raspberrypi4-64 /dev/ttyS0

raspberrypi4-64 login: root

WARNING: Poky is a reference Yocto Project distribution that should be used for
testing and development purposes only. It is recommended that you create your
own distribution for production use.

login[138]: root login on 'ttyS0'
root@raspberrypi4-64:~#

不要なサービスはかなり絞ってあるけど、LANケーブルを挿して以下のコマンドを実行するとちゃんと通信もできる。

root@raspberrypi4-64:~# udhcpc
udhcpc: started, v1.37.0
[  153.964509] bcmgenet fd580000.ethernet: configuring instance for external RGMII (RX delay)
[  153.973775] bcmgenet fd580000.ethernet eth0: Link is Down
udhcpc: broadcasting discover
udhcpc: broadcasting discover
[  158.079980] bcmgenet fd580000.ethernet eth0: Link is Up - 1Gbps/Full - flow control rx/tx
udhcpc: broadcasting discover
udhcpc: broadcasting select for 192.168.0.24, server 192.168.0.1
udhcpc: lease of 192.168.0.24 obtained from 192.168.0.1, lease time 86400
/etc/udhcpc.d/50default: Adding DNS 192.168.0.1
root@raspberrypi4-64:~# ip a
1: lo: <LOOPBACK> mtu 65536 qdisc noop state DOWN qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP qlen 1000
    link/ether xx:xx:xx:xx:xx:xx brd ff:ff:ff:ff:ff:ff
    inet 192.168.0.24/24 brd 192.168.0.255 scope global eth0
       valid_lft forever preferred_lft forever

まとめ

今回はpoky-tinyを実機で起動した。

とりあえず動いたし、pokyと比較して起動時間は速い。

通信もやろうと思えばできる。