みつきんのメモ

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

Yocto meta-raspberrypi環境の書き込みにbmaptoolを使ってみる

meta-raspberrypiでbitbakeして作成されるイメージがいつの間にかrpi-sdimgからwic.bz2になっている。 イメージを書き込む手順もddEtcherからbmaptoolになっている。

dunfellのブランチを使用して、最近の手順で試しにラズパイ4を動かしてみる。

構築手順

作成するディレクトリツリーは下記のようなイメージ。

.
├── build
├── downloads
└── layers
    ├── meta-raspberrypi
    └── poky

ソース取得

必要なメタデータを一式ダウンロードする。

$ mkdir -p rpi-dunfell/layers
$ cd rpi-dunfell/layers
$ git clone git://git.yoctoproject.org/poky.git -b dunfell
$ git clone git://git.yoctoproject.org/meta-raspberrypi -b dunfell
$ cd ../

環境変数設定

bitbakeの実行に必要な環境変数を設定する。

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

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

レイヤ追加

meta-raspberryをbitbakeの対象に追加する。

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

local.confの修正

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

OSSソースコード格納するdownloadsの位置も変更する。また、INITもsystemdに変更する。

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

書き込み

tmp/deploy/images/raspberrypi4core-image-base-raspberrypi4.wic.bz2が生成されるのでこれをbmaptoolで書き込む。

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

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

bmaptoolコマンドについて

bmaptoolコマンドがインストールされてない場合、Ubuntuではbmaptoolはaptでインストールできる。

$ sudo apt install bmap-tools

bmaptoolで書き込む場合、bitbakeで一緒に生成されるcore-image-base-raspberrypi4.wic.bmapがイメージファイルと同じディレクトリに存在すると、 このブロックマップ情報により書き込みが最適化される。

bitbakeでbmapファイルを生成するにはIMAGE_FSTYPESwic.bmapを設定する。

meta-raspberrypiではデフォルトで設定されている。これは下記のコマンドで確認できる。

$ bitbake core-image-base -e | grep '^IMAGE_FSTYPES='
IMAGE_FSTYPES="tar.bz2 ext3 wic.bz2 wic.bmap"

bmapファイルが存在しない場合はbmaptool copy --nomapオプションで使用しない方法や、 イメージファイルからbmaptool createで生成したりする方法もある。 その場合、bitbakeで生成されたbmapを使用したときほど書き込みに係る時間は短縮されない。

また、wicファイルはddコマンドでも書き込みできるがbunzip2などで伸張する必要があるし、 書き込み時間はbmapを使用しない場合とほぼ同じとなる。

そのため、イメージを他の場所に移動する場合などはbitbakeで生成されたbmapファイルとセットで管理するとよさそう。

時間比較

bitbakeで生成されたbmapを使用するケース。

$ sudo bmaptool copy core-image-base-raspberrypi4.wic.bz2 /dev/sda
bmaptool: info: copying time: 13.7s, copying speed 10.5 MiB/sec

bmapファイルを使用しないケース

$ sudo bmaptool copy --nobmap core-image-base-raspberrypi4.wic.bz2 /dev/sda
bmaptool: info: copying time: 22.4s, copying speed 11.8 MiB/sec

ddコマンドで書き込むケース

$ sudo dd if=./core-image-base-raspberrypi4.wic of=/dev/sda bs=100M
276824064 bytes (277 MB, 264 MiB) copied, 21.9507 s, 12.6 MB/s

これらをまとめると次のようになる。

コマンド 時間(秒) 速度(MiB/s)
bmaptool(bmapあり) 13.7 10.5
bmaptool(bmapなし) 22.4 11.8
dd*1 21.9 12.0*2

bmapなしのケースとddがほぼ同等。bmapありのケースで約半分の時間となっている。

この結果の原因としては、書き込み速度自体はほぼ変わらない(というかddのほうが速度は出ている)が、 ブロックマップ情報が適切に定義されて不要な書き込みをしないためと推測している。

まとめ

最近(dunfell以降かな)のmeta-raspberrypiではイメージの出力形式もwic.bz2になっており、 書き込みにもbmaptoolが推奨されるようになっていた。

rpi-sdimgと比較してもbz2で圧縮されている分、イメージファイルのサイズも小さくなっている。 適切なbmapファイルを使用してbmaptoolで書き込む場合、ddよりも高速に書き込めるということがわかった。

*1:bz2の伸張時間は含まない。

*2:ddの速度表示はMB/sだったのでMiB/sに計算し直している。