2014年12月30日

[Yocto] Intel E3815でのOpenSSL AES-NI対応機能の性能評価

組込みLinuxでシステムを構築していると、どんなシステムにも必ず入れることになる利用頻度の高いパッケージが存在します。そういうパッケージの一つにOpenSSLというものがあります。OpenSSLとはオープンソースで開発されるSSL/TLSプロトコルを実装したソフトウェアで、通信端末機器には必ずと言って良いほど使われています。Webブラウザで「https:」で始まるURLを入力したときに使われるのがSSL/TLSプロトコルです。企業内のセキュアな電子メール送受信でも本プロトコルが利用されます。OpenSSLはほぼすべてのUnix系OSで採用されていて、Mac OS Xでも使われており、Windows版も存在します。このように広く普及しているため、その脆弱性が問題になることも多いソフトウェアです。

組込みLinuxでもOpenSSLを利用することが非常に多く、インターネット通信機能を持つシステムでは必須のソフトウェアの一つとなっています。Yocto Linuxでも、ほとんどのイメージにOpenSSLが組み込まれています。

SSL/TLSプロトコルには共通鍵暗号という処理が含まれています。同プロトコルの暗号化アルゴリズムとして複数の推薦方式が存在しますが、その中で現在もっとも広く利用されているのはAES(Advanced Encryption Standard)です。AESはアメリカ商務省標準技術局(NIST)によって制定された米国政府認定の標準暗号方式で、現時代のスーパーコンピュータを用いても完全解読に数十億年かかると言われるほど強固な暗号方式です。このように複雑なアルゴリズムなので、鍵データの暗号処理には多くのCPUパワーが必要になってしまいます。このAES暗号処理を支援するために、IntelやAMDのx86系プロセッサの一部にはAES-NI(Advanced Encryption Standard New Instructions)という拡張命令が搭載されてます。x86系プロセッサに暗号処理支援機能が搭載されたのは、VIAのPadLockというものが最初です。IntelではWestmere(実質的にはSandy Bridge)以降、AMDはBulldozer以降のプロセッサにAES-NIが搭載されています。AES-NIの詳しい情報については下のリンクページを参照してください。

 インテル(R) AES New Instructions およびインテル(R) データ・プロテクション・テクノロジー
 Intel(R) Advanced Encryption Standard Instructions (AES-NI) | Intel(R) Developer Zone
 AES-NI - Wikipedia

AES-NIを内蔵したプロセッサが登場したのは2010年頃からでまだ比較的新しい機能ですが、この機能を利用すると暗号処理の速度が大きく向上するので、ソフトウェア側のAES-NI対応が積極的に進められています。OpenSSLでもバージョン1.0.0からこの機能を利用するコードが正式に追加されています。

Intel E38xxシリーズのプロセッサにもこのAES-NI機能が内蔵されており、Yocto LinuxのOpenSSLのレシピでは、デフォルトのビルド・コンフィグレーションでAES-NI対応機能が有効になっています。そこで、このOpenSSLのAES-NI対応機能の性能評価をやってみました。ターゲットとして使ったのはDE3815TYKHEです。Yocto Linuxのイメージは、前記事でビルドしたPoky + Valley Island BSP Daisy 1.6.2版のcore-image-satoを使いました。

最初に、DE3815TYKHEに搭載されているE3815プロセッサがAES-NIに対応していることを確認しました。
# cat /proc/cpuinfo | grep aes
flags : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx rdtscp
lm constant_tsc arch_perfmon pebs bts rep_good nopl xtopology nonstop_tsc aperfmperf pni pclmulqdq dtes64 monitor ds_cpl vmx est tm2 ssse3 cx16 xtpr pdcm
sse4_1 sse4_2 movbe popcnt tsc_deadline_timer aes rdrand lahf_lm 3dnowprefetch arat epb dtherm tpr_shadow vnmi flexpriority ept vpid tsc_adjust smep erms

次にOpenSSLの暗号処理の速度計測をやってみました。下のコマンドを実行すると、AES-NIを利用しない場合のAES暗号処理の実行速度が計測されます。
# openssl speed aes-256-cbc
Doing aes-256-cbc for 3s on 16 size blocks: 3428104 aes-256-cbc's in 2.98s
Doing aes-256-cbc for 3s on 64 size blocks: 941294 aes-256-cbc's in 2.99s
Doing aes-256-cbc for 3s on 256 size blocks: 243703 aes-256-cbc's in 2.99s
Doing aes-256-cbc for 3s on 1024 size blocks: 158741 aes-256-cbc's in 2.99s
Doing aes-256-cbc for 3s on 8192 size blocks: 20013 aes-256-cbc's in 2.99s
OpenSSL 1.0.1j 15 Oct 2014
built on: Mon Dec 29 20:18:13 JST 2014
options:bn(64,64) rc4(16x,int) des(idx,cisc,16,int) aes(partial) idea(int) blowfish(idx)
compiler: x86_64-poky-linux-gcc -m64 -march=corei7 -mtune=corei7 -mfpmath=sse -msse4.2 --sysroot=/home/yuhri/Yocto/poky-daisy-11.0.2/de3815tybe/tmp/sysroots/
de3815tybe-64 -fPIC -DOPENSSL_PIC -DOPENSSL_THREADS -D_REENTRANT -DDSO_DLFCN -DHAVE_DLFCN_H -DL_ENDIAN -DTERMIO -O2 -pipe -g -feliminate-unused-debug-types
-Wall -Wa,--noexecstack -DHAVE_CRYPTODEV -DUSE_CRYPTODEV_DIGESTS -DOPENSSL_IA32_SSE2 -DOPENSSL_BN_ASM_MONT -DOPENSSL_BN_ASM_MONT5 -DOPENSSL_BN_ASM_GF2m
-DSHA1_ASM -DSHA256_ASM -DSHA512_ASM -DMD5_ASM -DAES_ASM -DVPAES_ASM -DBSAES_ASM -DWHIRLPOOL_ASM -DGHASH_ASM
The 'numbers' are in 1000s of bytes per second processed.
type 16 bytes 64 bytes 256 bytes 1024 bytes 8192 bytes
aes-256 cbc 18405.93k 20148.10k 20865.54k 54364.81k 54831.60k

続いて、AES-NIを利用する場合のAES暗号処理の実行速度を計測してみました。
# openssl speed -evp aes-256-cbc
Doing aes-256-cbc for 3s on 16 size blocks: 20268390 aes-256-cbc's in 2.98s
Doing aes-256-cbc for 3s on 64 size blocks: 6844410 aes-256-cbc's in 2.99s
Doing aes-256-cbc for 3s on 256 size blocks: 2006895 aes-256-cbc's in 2.99s
Doing aes-256-cbc for 3s on 1024 size blocks: 524359 aes-256-cbc's in 2.99s
Doing aes-256-cbc for 3s on 8192 size blocks: 66350 aes-256-cbc's in 2.99s
OpenSSL 1.0.1j 15 Oct 2014
built on: Mon Dec 29 20:18:13 JST 2014
options:bn(64,64) rc4(16x,int) des(idx,cisc,16,int) aes(partial) idea(int) blowfish(idx)
compiler: x86_64-poky-linux-gcc -m64 -march=corei7 -mtune=corei7 -mfpmath=sse -msse4.2 --sysroot=/home/yuhri/Yocto/poky-daisy-11.0.2/de3815tybe/tmp/sysroots/
de3815tybe-64 -fPIC -DOPENSSL_PIC -DOPENSSL_THREADS -D_REENTRANT -DDSO_DLFCN -DHAVE_DLFCN_H -DL_ENDIAN -DTERMIO -O2 -pipe -g -feliminate-unused-debug-types
-Wall -Wa,--noexecstack -DHAVE_CRYPTODEV -DUSE_CRYPTODEV_DIGESTS -DOPENSSL_IA32_SSE2 -DOPENSSL_BN_ASM_MONT -DOPENSSL_BN_ASM_MONT5 -DOPENSSL_BN_ASM_GF2m
-DSHA1_ASM -DSHA256_ASM -DSHA512_ASM -DMD5_ASM -DAES_ASM -DVPAES_ASM -DBSAES_ASM -DWHIRLPOOL_ASM -DGHASH_ASM
The 'numbers' are in 1000s of bytes per second processed.
type 16 bytes 64 bytes 256 bytes 1024 bytes 8192 bytes
aes-256 cbc 108823.57k 146502.42k 171827.80k 179579.80k 181785.69k

openssl speed」コマンドに「-evp」というオプションを付加すると、ハードウェア側の暗号処理支援機能が使われます。

上の2つの計測値を比較すると、AES-NI利用の有無によって処理速度に3〜8倍の差が出ています(数値が大きい方が高速です)。この結果から、AES-NIの性能がいかに優れているかということが判ります。

SSE(Streaming SIMD Extensions)もそうですが、x86系プロセッサではソフトウェア側の負荷が高い処理を支援する拡張機能が積極的に搭載されます。Intelのプロセッサの設計技術と製造技術が並外れて高いからですが、こういう対応はARM系よりx86系プロセッサの方が断然早いです。組込み機器でx86系プロセッサを採用するメリットはこういう点にも現れると言えるでしょう。

【参考ページ】

 AES-NIという加速装置のお話 - geniee’s tech blog
 見せてもらおうか、IntelのAES-NIの性能とやらを 〜OpenSSLでベンチしてみた〜 - ..たれろぐ..
posted by とみやん at 11:15| Comment(0) | TrackBack(0) | Embedded Linux > Yocto Project

2014年12月29日

[Yocto] Poky Daisy 1.6.2: Intel E38xx BSPのDE3815TYKHEでの動作確認

前記事に書いたとおり、Intel E38xx用のYocto Linuxビルド環境をDaisy 1.6.1からDaisy 1.6.2にバージョンアップしました。Poky(Yocto Project Core)のDaisy 1.6.2版がリリースされたのが2014/12/05で、Valley Island(Intel E38xx)BSPのDaisy 1.6.2版はそれから少し遅れて2014/12/19にリリースにされています。PokyとBSPの両方が揃ったので、年内にDaisy 1.6.2版へのバージョンアップをやってしまいたかったからです。

Valley Island BSPの配布パッケージにはビルド済みのcore-image-satoイメージのhddimgファイルが収納されているので、手っ取り早くこのファイルからLive USBを作成して、それを使ってターゲットで動作確認をやることもできます。すでにそちらは行ってみたのですが、改めてIntel E38xx用のYocto Linux Daisy 1.6.2版ビルド環境を構築して、一からcore-image-satoイメージをビルドして、この自分でクリーン・ビルドしたイメージを使ってDE3815TYKHEでYocto Linuxを動かしてみました。

Daisy 1.6.1版で同じ作業をやっており、その作業記録は09/2410/13の記事に掲載済みですが、改めてDaisy 1.6.2版でのIntel E38xx用Yocto Linuxビルド環境の構築とDE3815TYKHEでの動作確認作業の記録を残します。

まずは、Daisy 1.6.2公式リリース版のパッケージファイルのダウンロードとその展開から始めました。
% cd ~/Yocto
% wget http://downloads.yoctoproject.org/releases/yocto/yocto-1.6.2/poky-daisy-11.0.2.tar.bz2
% tar -jxvf poky-daisy-11.0.2.tar.bz2
% wget http://downloads.yoctoproject.org/releases/yocto/yocto-1.6.2/machines/valleyisland/valleyisland-1.0-daisy-1.6.2.tar.bz2
% tar -jxvf valleyisland-1.0-daisy-1.6.2.tar.bz2
% mv valleyisland-1.0-daisy-1.6.2/meta-intel poky-daisy-11.0.2
$ rmdir valleyisland-1.0-daisy-1.6.2

また、ついでにOpenEmbedded Gitリポジトリからmeta-openembeddedツリーのパッケージレシピ群を取得しておきました。
% cd poky-daisy-11.0.2
% git clone git://git.openembedded.org/meta-openembedded -b daisy

これでIntel E38xx用のビルド環境は完成ですが、DE3815TYKHEをターゲットとしてYocto Linuxをビルドするので、DE3815TYKHE用のBSPを追加しました。同BSPの作成手順は10/25の記事に書いたとおりですが、Valley Island BSP Daisy 1.6.2版はRealtek RTL8111用ドライバが有効になっているので、同ドライバをカーネルへ組み込むための変更は加えていません。一応DE3815TYKHE BSP Daisy 1.6.2版のターゲット定義ファイルとカーネルレシピの内容を以下に掲載しておきます。
#@TYPE: Machine
#@NAME: Intel DE3815TYBE (Thin Canyon) board which is embedded in NUC Kit DE3815TYKHE

#@WEBTITLE: Intel Atom E38xx Processor (DE3815TYBE) 32-bit with Open Source Frame Buffer Graphics

#@DESCRIPTION: Machine configuration for DE3815TYBE 32-bit systems, without Intel-proprietary graphics bits

PREFERRED_PROVIDER_virtual/kernel ?= "linux-yocto"
PREFERRED_VERSION_linux-yocto ?= "3.10%"

require conf/machine/include/intel-core2-32-common.inc
require conf/machine/include/intel-common-pkgarch.inc
require conf/machine/include/meta-intel.inc

MACHINE_FEATURES += "pcbios efi"
MACHINE_FEATURES += "wifi"

MACHINE_EXTRA_RRECOMMENDS += "linux-firmware"

XSERVER ?= "${XSERVER_X86_BASE} \
${XSERVER_X86_EXT} \
${XSERVER_X86_FBDEV} \
${XSERVER_X86_I965} \
"

APPEND += "acpi_enforce_resources=lax video=efifb:off vga=0x318"

#@TYPE: Machine
#@NAME: Intel DE3815TYBE (Thin Canyon) board which is embedded in NUC Kit DE3815TYKHE

#@WEBTITLE: Intel Atom E38xx Processor (DE3815TYBE) 64-bit with Open Source Frame Buffer Graphics

#@DESCRIPTION: Machine configuration for DE3815TYBE 64-bit systems, without Intel-proprietary graphics bits

PREFERRED_PROVIDER_virtual/kernel ?= "linux-yocto"
PREFERRED_VERSION_linux-yocto ?= "3.10%"

require conf/machine/include/intel-corei7-64-common.inc
require conf/machine/include/intel-common-pkgarch.inc
require conf/machine/include/meta-intel.inc

MACHINE_FEATURES += "pcbios efi"
MACHINE_FEATURES += "wifi"

MACHINE_EXTRA_RRECOMMENDS += "linux-firmware"

XSERVER ?= "${XSERVER_X86_BASE} \
${XSERVER_X86_EXT} \
${XSERVER_X86_FBDEV} \
${XSERVER_X86_I965} \
"

APPEND += "acpi_enforce_resources=lax video=efifb:off vga=0x318"

FILESEXTRAPATHS_prepend := "${THISDIR}/${PN}:"

#############################
# MACHINE = de3815tybe-32 #
#############################
COMPATIBLE_MACHINE_de3815tybe-32 = "de3815tybe-32"
KMACHINE_de3815tybe-32 = "valleyisland-32"
KBRANCH_de3815tybe-32 = "standard/base"
KERNEL_FEATURES_de3815tybe-32 = " features/valleyisland-io/valleyisland-io.scc \
features/valleyisland-io/valleyisland-io-pci.scc \
features/wifi/wifi-all.scc"

LINUX_VERSION_de3815tybe-32 = "3.10.59"
SRCREV_machine_de3815tybe-32 = "747e1cbd12b15db8bc2ae86e2359c1b113f120d6"
SRCREV_meta_de3815tybe-32 = "8f05306a8e6f5ee422d50c3317acce0cf9e6aada"
SRCREV_valleyisland-io_de3815tybe-32 = "0992d01f5f382f6da60004ef87f67ebd3ca13732"

SRC_URI_de3815tybe-32 = "git://git.yoctoproject.org/linux-yocto-3.10.git;protocol=git;nocheckout=1;branch=${KBRANCH},${KMETA},valleyisland-io-3.0;name=machine,meta,valleyisland-io"

#############################
# MACHINE = de3815tybe-64 #
#############################
COMPATIBLE_MACHINE_de3815tybe-64 = "de3815tybe-64"
KMACHINE_de3815tybe-64 = "valleyisland"
KBRANCH_de3815tybe-64 = "standard/base"
KERNEL_FEATURES_de3815tybe-64 = " features/valleyisland-io/valleyisland-io.scc \
features/valleyisland-io/valleyisland-io-pci.scc \
features/wifi/wifi-all.scc"

LINUX_VERSION_de3815tybe-64 = "3.10.59"
SRCREV_machine_de3815tybe-64 = "747e1cbd12b15db8bc2ae86e2359c1b113f120d6"
SRCREV_meta_de3815tybe-64 = "8f05306a8e6f5ee422d50c3317acce0cf9e6aada"
SRCREV_valleyisland-io_de3815tybe-64 = "0992d01f5f382f6da60004ef87f67ebd3ca13732"

SRC_URI_de3815tybe-64 = "git://git.yoctoproject.org/linux-yocto-3.10.git;protocol=git;nocheckout=1;branch=${KBRANCH},${KMETA},valleyisland-io-3.0;name=machine,meta,valleyisland-io"

module_autoload_i2c-dev = "i2c-dev"

上ではWi-Fi端末機能と無線LANドライバが有効になっていますが、これはDE3815TYKHEに無線LANカードを取り付け済みだからです。ターゲットに無線LANカードが搭載されていない場合は、ハイライト表示の部分は削除しても構いません。このままビルドしたイメージを無線LANカード未搭載のターゲットで動かしても、特に問題は発生しないと思います。

DE3815TYKHE用のYocto Linuxビルド環境が整ったので、さっそくcore-image-satoイメージをビルドしてみました。まずは、oe-init-build-envスクリプトを使ってビルド作業ディレクトリを作成しました。
% cd ~/Yocto
% cd poky-daisy-11.0.2
% . ./oe-init-build-env de3815tybe

そして、oe-init-build-envスクリプトによって生成されたbblayers.conflocal.confを以下のように編集しました。
--- conf/bblayers.conf.000	2014-12-29 17:45:51.120393760 +0900
+++ conf/bblayers.conf 2014-12-29 18:04:41.401863776 +0900
@@ -9,6 +9,9 @@
/home/yuhri/Yocto/poky-daisy-11.0.2/meta \
/home/yuhri/Yocto/poky-daisy-11.0.2/meta-yocto \
/home/yuhri/Yocto/poky-daisy-11.0.2/meta-yocto-bsp \
+ /home/yuhri/Yocto/poky-daisy-11.0.2/meta-intel \
+ /home/yuhri/Yocto/poky-daisy-11.0.2/meta-intel/meta-tlk \
+ /home/yuhri/Yocto/poky-daisy-11.0.2/meta-de3815tybe \
"
BBLAYERS_NON_REMOVABLE ?= " \
/home/yuhri/Yocto/poky-daisy-11.0.2/meta \

--- conf/local.conf.000	2014-12-29 17:45:51.120393760 +0900
+++ conf/local.conf 2014-12-29 17:53:41.423015554 +0900
@@ -17,18 +17,18 @@
# These two options control how much parallelism BitBake should use. The first
# option determines how many tasks bitbake should run in parallel:
#
-#BB_NUMBER_THREADS ?= "4"
+BB_NUMBER_THREADS ?= "12"
#
# Default to setting automatically based on cpu count
-BB_NUMBER_THREADS ?= "${@oe.utils.cpu_count()}"
+#BB_NUMBER_THREADS ?= "${@oe.utils.cpu_count()}"
#
# The second option controls how many processes make should run in parallel when
# running compile tasks:
#
-#PARALLEL_MAKE ?= "-j 4"
+PARALLEL_MAKE ?= "-j 12"
#
# Default to setting automatically based on cpu count
-PARALLEL_MAKE ?= "-j ${@oe.utils.cpu_count()}"
+#PARALLEL_MAKE ?= "-j ${@oe.utils.cpu_count()}"
#
# For a quad-core machine, BB_NUMBER_THREADS = "4", PARALLEL_MAKE = "-j 4" would
# be appropriate for example.
@@ -55,7 +55,8 @@
#MACHINE ?= "edgerouter"
#
# This sets the default machine to be qemux86 if no other machine is selected:
-MACHINE ??= "qemux86"
+MACHINE ?= "de3815tybe-64"
+MACHINE ??= "valleyisland-64"

これでDE3815TYKHE用にYocto Linuxをビルドするための条件がすべて整ったので、bitbakeコマンドを使ってcore-image-satoイメージのビルドを行いました。
% bitbake core-image-sato -c fetchall
% bitbake core-image-sato

最初の全ソースのダウンロードに30分(インターネット回線はWiMAX 2+モバイルルータ)、続くcore-image-satoイメージのクリーン・ビルドに3時間35分かかりました(Intel Core i7 2.7GHz プロセッサコア数4、メモリ4GB、ストレージThuderbolt RAID 0 HDDという構成のVMware仮想マシンの場合)。

ビルドが完了するまで、食事をしたりニコニコ動画でアニメを鑑賞しながら過ごしました。core-image-satoイメージのビルドはとにかく時間がかかります。特にストレージがSSDかHDDかでビルド時間に1.5〜2倍の差が生まれます。それと、local.conf内のBB_NUMBER_THREADSとPARALLEL_MAKEの値はすごく重要です。この2つ変数の設定値によってもビルド時間に2〜5倍の差が出ます。また、Yocto Linxはやたらとディスク容量を食います。一ターゲットあたり30〜50GB位のディスク容量が必要になります。複数のターゲットのビルドをやると、すぐにディスク消費量が100GBを超えてしまいます。Yocto Linxの開発では、高性能なPCと大容量のSSDは必須だと思った方が良いです(もし会社で低性能なPCしか与えられられなかったら、毎日終電近くまで残業して休日出勤までしなければならないような地獄の日々を過ごす羽目になるでしょう。会社の仕事でYocto Linxの開発を始めるときは、大容量SSDを内蔵した高性能なPCを用意するように会社側に要求するべきです。この条件を満たさなければ仕事はしないと宣言した方が良いです。仕事に適したPCを社員に提供することは会社側の義務なんですから)。ビルド時間がかかることに関しては、退勤前や就寝前に始めるか他の事でもやりながらひたすら待つしかありません。

ビルドが終わったので(ソース・ダウンロードを始めたのが夕方6時頃で、ビルドが終わったのは夜10時頃でした。やっぱりSSD内蔵のPCを使うか、終夜稼働ビルドでもやらないとダメですね)、core-image-satoのイメージファイルが生成されていることを確認した後、Live USBメディアを作成しました。
% ls tmp/deploy/images/de3815tybe-64 
bootx64.efi
bzImage
bzImage--3.10.59+git0+8f05306a8e_747e1cbd12-r0-de3815tybe-64-20141229094113.bin
bzImage-de3815tybe-64.bin
core-image-minimal-initramfs-de3815tybe-64-20141229094113.rootfs.cpio.gz
core-image-minimal-initramfs-de3815tybe-64-20141229094113.rootfs.manifest
core-image-minimal-initramfs-de3815tybe-64.cpio.gz
core-image-minimal-initramfs-de3815tybe-64.manifest
core-image-sato-de3815tybe-64-20141229094113.hddimg
core-image-sato-de3815tybe-64-20141229094113.iso
core-image-sato-de3815tybe-64-20141229094113.rootfs.ext3
core-image-sato-de3815tybe-64-20141229094113.rootfs.manifest
core-image-sato-de3815tybe-64.ext3
core-image-sato-de3815tybe-64.hddimg
core-image-sato-de3815tybe-64.iso
core-image-sato-de3815tybe-64.manifest
modules--3.10.59+git0+8f05306a8e_747e1cbd12-r0-de3815tybe-64-20141229094113.tgz
modules-de3815tybe-64.tgz
README_-_DO_NOT_DELETE_FILES_IN_THIS_DIRECTORY.txt

% umount /dev/sdc
% sudo dd if=tmp/deploy/images/de3815tybe-64/core-image-sato-de3815tybe-64.hddimg of=/dev/sdc
% sync

DE3815TYKHEでYocto Linuxが動作している様子は10/13の記事に掲載済みで、Sato Mobile Destopの画面や機能は特に変わっていないので、本記事では省略します。

ちなみに、Valley Island BSP Daisy 1.6.2版に収納されているhddimgファイルでは確認済みでしたが、今回クリーン・ビルドした core-image-satoイメージでも、DE3815TYKHEでeth0インターフェースはちゃんと生成されていました。やはり同版では、カーネルへr8169ドライバが組み込まれているようです。

【2014/12/30 追記】

Valley Island BSP Daisy 1.6.2版の大きな変更点は次の3つのようです(括弧内はDaisy 1.6.1版)。
  1. Gitリポジトリのカーネルソース・ブランチがvalleyisland-io-3.0へ変更された。(valleyisland-io-2.0)
  2. カーネルのバージョンが3.10.59へ更新された。(3.10.43)
  3. リファレンスターゲットとして、MinnowBoard MAXが追加された。

3の変更は大きいと思いますが、MinnowBoard MAXの入手性が悪すぎるのであまり嬉しくないですね。ググっても、MinnowBoard MAXの動作確認情報のヒット数は少ないです。上のMinnowBoard MAXのページに販売代理店のリンクが載っていますが、いずれも在庫0で入庫予定期間も2ヶ月以上になっています。メーカーのCircuitCoに本ボードの製造数を増やせない事情が何かあるのでしょう。もしかすると、IntelからのE3815やE3825 CPUの供給量がかなり少ないのかもしれません。ググってみても、E38xx搭載ボードの種類や情報が全体的に少ないからです。多くのタブレットで採用されているZ37xxの製造の方をIntelが優先しているんじゃないかと想像しています。すごく欲しいボードなのですが、私はもうMinnowBoard MAXの入手は諦めています。

どこかのメーカーがE38xx搭載ボードを私へ提供してくれると嬉しいのですが。国内の販売代理店でも構いません。無償または安価にボードを提供してくれたら、顧客向けにLinux移植のサポートとコンサルティングをやりますよ(つまり、FAEとして営業や技術活動に協力します)。本記事を読んでいるメーカーの中の人がいたら、ぜひ会社の担当者へ伝えください。
posted by とみやん at 18:37| Comment(0) | TrackBack(0) | Embedded Linux > Yocto Project

2014年12月28日

[Yocto] Poky Daisy 1.6.1: lttng-modulesコンパイルエラーの解決方法

Yocto Projectの公式サイトで、Poky(Yocto Project Core)とValley Island(Intel E38xx)BSPの両方のDaisy 1.6.2版がリリースされたので、Yocto Linuxのビルド環境をこの組み合わせにバージョンアップしました。いままで私が使っていたのはいずれものDaisy 1.6.1版でした。なお、どちらも最新版はDizzy 1.7ですが、当面の間はDaisy 1.6.2をメインに使っていきます。そのうちDizzy 1.7の方も試すつもりですが、こちらはサブのビルド環境になるでしょう。

Daisy 1.6.2にバージョンアップしてしまったので、いまさらになりますが、Poky + Valley Island BSP Daisy 1.6.1のYocto Linux環境に関する一つのTips情報があるので、記事として残しておきます。この組み合わせで、lttng-modulesというパッケージをビルドしようとすると、以下のようなコンパイルエラーが発生します。
% bitbake lttng-modules
.... ....
.... ....
ERROR: Logfile of failure stored in: /home/yuhri/Yocto/poky-daisy-11.0.1/valleyisland/tmp/work/valleyisland_64-poky-linux/lttng-modules/2.4.0-r0/temp/log.do_compile.3530
Log data follows:
| DEBUG: Executing shell function do_compile
| NOTE: make -j 12 -e MAKEFLAGS= KERNEL_PATH=/home/yuhri/Yocto/poky-daisy-11.0.1/valleyisland/tmp/sysroots/valleyisland-64/usr/src/kernel KERNEL_SRC=/home/yuhri/Yocto/poky-daisy-11.0.1/valleyisland/tmp/sysroots/valleyisland-64/usr/src/kernel KERNEL_VERSION=3.10.43-ltsi-yocto-standard CC=x86_64-poky-linux-gcc LD=x86_64-poky-linux-ld.bfd AR=x86_64-poky-linux-ar
| make -C /home/yuhri/Yocto/poky-daisy-11.0.1/valleyisland/tmp/sysroots/valleyisland-64/usr/src/kernel M=/home/yuhri/Yocto/poky-daisy-11.0.1/valleyisland/tmp/work/valleyisland_64-poky-linux/lttng-modules/2.4.0-r0/git modules
| make[1]: Entering directory `/home/yuhri/Yocto/poky-daisy-11.0.1/valleyisland/tmp/sysroots/valleyisland-64/usr/src/kernel'
| CC [M] /home/yuhri/Yocto/poky-daisy-11.0.1/valleyisland/tmp/work/valleyisland_64-poky-linux/lttng-modules/2.4.0-r0/git/lttng-ring-buffer-client-discard.o
| CC [M] /home/yuhri/Yocto/poky-daisy-11.0.1/valleyisland/tmp/work/valleyisland_64-poky-linux/lttng-modules/2.4.0-r0/git/lttng-ring-buffer-client-overwrite.o
| CC [M] /home/yuhri/Yocto/poky-daisy-11.0.1/valleyisland/tmp/work/valleyisland_64-poky-linux/lttng-modules/2.4.0-r0/git/lttng-ring-buffer-metadata-client.o
| CC [M] /home/yuhri/Yocto/poky-daisy-11.0.1/valleyisland/tmp/work/valleyisland_64-poky-linux/lttng-modules/2.4.0-r0/git/lttng-ring-buffer-client-mmap-discard.o
.... ....
.... ....
.... ....
.... ....
.... ....
.... ....
| CC [M] /home/yuhri/Yocto/poky-daisy-11.0.1/valleyisland/tmp/work/valleyisland_64-poky-linux/lttng-modules/2.4.0-r0/git/probes/lttng-probe-signal.o
| CC [M] /home/yuhri/Yocto/poky-daisy-11.0.1/valleyisland/tmp/work/valleyisland_64-poky-linux/lttng-modules/2.4.0-r0/git/probes/lttng-probe-block.o
| In file included from /home/yuhri/Yocto/poky-daisy-11.0.1/valleyisland/tmp/work/valleyisland_64-poky-linux/lttng-modules/2.4.0-r0/git/probes/../instrumentation/events/lttng-module/../../../probes/define_trace.h:148:0,
| from /home/yuhri/Yocto/poky-daisy-11.0.1/valleyisland/tmp/work/valleyisland_64-poky-linux/lttng-modules/2.4.0-r0/git/probes/../instrumentation/events/lttng-module/block.h:932,
| from /home/yuhri/Yocto/poky-daisy-11.0.1/valleyisland/tmp/work/valleyisland_64-poky-linux/lttng-modules/2.4.0-r0/git/probes/lttng-probe-block.c:41:
| /home/yuhri/Yocto/poky-daisy-11.0.1/valleyisland/tmp/work/valleyisland_64-poky-linux/lttng-modules/2.4.0-r0/git/probes/../instrumentation/events/lttng-module/../../../probes/lttng-events.h:151:6: error: conflicting types for 'trace_block_rq_complete'
| void trace_##_name(_proto);
| ^
| /home/yuhri/Yocto/poky-daisy-11.0.1/valleyisland/tmp/work/valleyisland_64-poky-linux/lttng-modules/2.4.0-r0/git/probes/../instrumentation/events/lttng-module/../../../probes/lttng-events.h:117:2: note: in expansion of macro 'DEFINE_EVENT_MAP'
| DEFINE_EVENT_MAP(template, name, name, PARAMS(proto), PARAMS(args))
| ^
| /home/yuhri/Yocto/poky-daisy-11.0.1/valleyisland/tmp/work/valleyisland_64-poky-linux/lttng-modules/2.4.0-r0/git/probes/../instrumentation/events/lttng-module/../../../probes/../instrumentation/events/lttng-module/block.h:235:1: note: in expansion of macro 'DEFINE_EVENT'
| DEFINE_EVENT(block_rq_with_error, block_rq_complete,
| ^
| In file included from include/linux/module.h:18:0,
| from /home/yuhri/Yocto/poky-daisy-11.0.1/valleyisland/tmp/work/valleyisland_64-poky-linux/lttng-modules/2.4.0-r0/git/probes/lttng-probe-block.c:23:
| include/linux/tracepoint.h:168:21: note: previous definition of 'trace_block_rq_complete' was here
| static inline void trace_##name(proto) \
| ^
| include/linux/tracepoint.h:265:3: note: in expansion of macro '__DECLARE_TRACE'
| __DECLARE_TRACE(name, PARAMS(proto), PARAMS(args), 1, \
| ^
| include/linux/tracepoint.h:395:2: note: in expansion of macro 'DECLARE_TRACE'
| DECLARE_TRACE(name, PARAMS(proto), PARAMS(args))
| ^
| include/trace/events/block.h:143:1: note: in expansion of macro 'TRACE_EVENT'
| TRACE_EVENT(block_rq_complete,
| ^
| make[3]: *** [/home/yuhri/Yocto/poky-daisy-11.0.1/valleyisland/tmp/work/valleyisland_64-poky-linux/lttng-modules/2.4.0-r0/git/probes/lttng-probe-block.o] Error 1
| make[2]: *** [/home/yuhri/Yocto/poky-daisy-11.0.1/valleyisland/tmp/work/valleyisland_64-poky-linux/lttng-modules/2.4.0-r0/git/probes] Error 2
| make[1]: *** [_module_/home/yuhri/Yocto/poky-daisy-11.0.1/valleyisland/tmp/work/valleyisland_64-poky-linux/lttng-modules/2.4.0-r0/git] Error 2
| make[1]: Leaving directory `/home/yuhri/Yocto/poky-daisy-11.0.1/valleyisland/tmp/sysroots/valleyisland-64/usr/src/kernel'
| make: *** [default] Error 2
| ERROR: oe_runmake failed
| WARNING: exit code 1 from a shell command.
| ERROR: Function failed: do_compile (log file is located at /home/yuhri/Yocto/poky-daisy-11.0.1/valleyisland/tmp/work/valleyisland_64-poky-linux/lttng-modules/2.4.0-r0/temp/log.do_compile.3530)
ERROR: Task 7 (/home/yuhri/Yocto/poky-daisy-11.0.1/meta/recipes-kernel/lttng/lttng-modules_2.4.0.bb, do_compile) failed with exit code '1'
NOTE: Tasks Summary: Attempted 419 tasks of which 412 didn't need to be rerun and 1 failed.
No currently running tasks (419 of 425)

Summary: 1 task failed:
/home/yuhri/Yocto/poky-daisy-11.0.1/meta/recipes-kernel/lttng/lttng-modules_2.4.0.bb, do_compile
Summary: There was 1 ERROR message shown, returning a non-zero exit code.

上のエラーログ出力の中のいくつかのキーワードを組みわあせて検索すると、Yocto Project Gitリポジトリの下のコミット情報ページがヒットします。

 https://git.yoctoproject.org/cgit/cgit.cgi/poky/commit/?id=2934b25a37b6d1d09b6c6853959530be414931cb

ASShot-141228_0004-YoctoProject_Git-poky-2934b25a37b6d1d09b6c6853959530be414931cb-1002x1219
このコミットのコメントに記されているエラーメッセージは、上記のエラーログの一部と一致しています。

上記のコミットの更新内容を使えば、このlttng-modulesのコンパイルエラーを解決できるんじゃないかと考えて、それを実行してみました。具体的には、以下のような操作によって、既存のmeta/recipes-kernel/lttngディレクトリを上記のコミットの圧縮ファイルに収納されているlttngディレクトリと入れ替えました。
% cd ~/Downloads
% wget https://git.yoctoproject.org/cgit/cgit.cgi/poky/snapshot/poky-2934b25a37b6d1d09b6c6853959530be414931cb.tar.bz2
% tar -jxvf poky-2934b25a37b6d1d09b6c6853959530be414931cb.tar.bz2
% cd poky-2934b25a37b6d1d09b6c6853959530be414931cb
% mkdir ~/Yocto/poky-daisy-11.0.1/_orig_
% mv ~/Yocto/poky-daisy-11.0.1/meta/recipes-kernel/lttng ~/Yocto/poky-daisy-11.0.1/_orig_
% cp -rp meta/recipes-kernel/lttng ~/Yocto/poky-daisy-11.0.1/meta/recipes-kernel

上の操作を行った後、再度lttng-modulesのビルドを試みると、見事にビルドに成功しました。ちなみに、meta/recipes-kernel/lttng/を上記のコミットの更新内容と入れ替えると、lttng-modulesのバージョンは2.4.0から2.4.1に変わります。

どうやら、このlttng-modules_2.4.0のコンパイルエラーは特定のバージョンのカーネルとの組み合わせで起きるエラーのようです。上記のコミットのコメントには "The 3.15, and 3.14.5+ kernels introduced a change to trace_block_rq_complete, which triggers the following build error: " と記されていますが、Valley Island BSP Daisy 1.6.1のデフォルトのカーネル・バージョンは3.10.43です。多分このlttng-modules_2.4.0のコンパイルエラーは3.10.xでも起きるものなのでしょう。なお、QEMU x86 BSPとの組わあせでlttng-modules_2.4.0をビルドしたときは、このコンパイルエラーは起きません。Poky Daisy 1.6.1に収納されているQEMU x86 BSPのデフォルトのカーネル・バージョンは3.14.0です。

また、Yocto Linuxの*-sdkイメージ(core-image-sato-sdkなど)をビルドすると、その処理の過程でlttng-modulesもビルドされます。そのため、lttng-modulesの本コンパイルエラーに遭遇します(core-image-sato-sdkのビルドは高性能なPCでも3時間以上かかりますが、lttng-modulesのコンパイルエラーはその後半以降の終わりに近い所で起きます)。

いずれにしても、Valley Island以外のBSPでもカーネルのバージョンによって本コンパイルエラーに遭遇する可能性があるので、Poky Daisy 1.6.1のlttngは上記のコミットの更新内容と入れ替えておくことをお勧めします。
posted by とみやん at 15:03| Comment(0) | TrackBack(0) | Embedded Linux > Yocto Project

2014年12月14日

[Yocto] DE3815TYKHEのWi-Fiアクセスポイント化

9月からYocto Linuxの記事ばかり立て続けに投稿してきましたが(と言っても、月1〜2本のペースでしたが)、組込みLinuxに特化しすぎていて、記事の内容がちょっと偏りすぎているとなぁと思いながら書いてきました。組込みLinuxを仕事にしているエンジニアか同分野に深い興味を持っている人にしか役に立たない記事ばかりだったかもしれません。本業でやっているYocto Linux関連の仕事があまりに忙しすぎて、これ以外の研究テーマに時間を避けなくなっていることが悩みでした。この仕事のおかげで組込みLinuxのスペシャリストには成れましたが、組込み分野の最新トレンドとはかけ離れすぎていることは自覚しています。アクセス解析の情報でも、Yocto Linuxの記事のアクセス数や訪問者数は少ないです。こういう専門性の高い記事を検索する人はやはり少ないのでしょうね。Arduino, mbed, Raspberry Piなどのボードを使って、お手軽に電子工作をやったり、スマホ連携アプリを作ったりするのがいまの流行りであることは知っています。ググれば、こういうページがたくさんヒットしますし、書店で見かける専門誌でもこういう内容を特集しているものが増えています。ブログサイトの訪問者の大多数は検索エンジン経由なので、記事の中に流行りのボードの名前が含まれていれば、一気にアクセス数が伸びたりするんだと思います。組込み系の記事を書くにしてももう少しライトな内容にすべきかなぁと思って、いま色々なネタを仕込み中です。本業の仕事もやっと一段落してきたので、来年から記事の傾向を少し変えていくつもりです。

さて、前記事では、Yocto LinuxにWi-Fi端末機能を追加する方法について解説しました。無線LANカードを組み込んだDE3815TYKHEをターゲット機として使いましたが、こういう機器をWi-Fi(無線LAN)アクセスポイントとして使いたいという需要もあるんじゃないかと思います。組込みLinuxでWi-Fiアクセスポイントを構築する場合、hostapdというソフトウェアを使います。Yocto Linuxにもhostapdのパッケージレシピが存在しているので、このレシピを利用すれば、結構簡単にWi-Fiアクセスポイントを構築することができます。ただし、前記事のWi-Fi端末システムよりはずっと難易度は高くなります。Yocto Linuxのパッケージレシピやイメージレシピをカスタマイズしなければならないからです。これらの解説も兼ねて、Yocto LinuxでWi-Fiアクセスポイント・システムを構築する方法について紹介しましょう。

先にWi-Fiアクセスポイント・システムの要となるhostapdに関する情報ですが、hostapdのレシピはYocto ProjectのGitリポジトリではなく、下のOpenEmbeddedのGitリポジトリの方で管理されています。

 OpenEmbedded Git Repository Browser
 OpenEmbedded Metadata Index - layers

OpenEmbeddedというのは、Yocto Projectの源流になった組込みLinuxディストリビューションです。OpenEmbeddedはシャープのZaurus SLシリーズ(俗称「リナザウルス」)向けLinuxのビルド・フレームワークとして出発したオープンソースプロジェクトでした。発足時のターゲットはZaurusだけがでしたが、その後ARMプロセッサ搭載ハードウェアを中心として多様なターゲットに移植されて、Angstrom DistributionFamiliar LinuxなどOpenEmbeddedから派生した組込みLinuxディストリビューションが生まれています。Yocto ProjectのbitbakeコマンドやレシピなどはOpenEmbeddedによって生み出された資産を継承したものです。Yocto Linux関連のディープな技術情報を調べたい場合は、「OpenEmbedded」というキーワードを付加して検索すると、目的に適ったページが見つかることが多いです。

上のOpenEmbedded Gitリポジトリには、Yocto Projectの配布パッケージに収納されているものと同じ内容のパッケージレシピ群も存在します。同リポジトリの「openembedded-core」というツリーがそれです。Yocto Projectの公式サイトで配布されているPoky(Yocto Project Core)パッケージには、このopenembedded-coreツリーのパッケージレシピだけが格納されています。Yocto Linuxのレシピを眺めていて、「何だか、パッケージの数が少ないなぁ」と思った方がいるんじゃないでしょうか。それは、組込みLinuxでの利用頻度の高い主要なパッケージだけがopenembedded-coreツリーに収集されているからです。マイナーな分野向けパッケージは「meta-openembedded」ツリーの方に収集されています。

OpenEmbeddedのmeta-openembeddedリポジトリのパッケージレシピ群は、以下のコマンドによって取得することができます。
$ cd ~/Yocto
$ cd poky-daisy-11.0.1
$ git clone git://git.openembedded.org/meta-openembedded -b daisy

-b」オプションでブランチを指定しているので、上のコマンドによって取得できるのは、Yocto Linuxの前リリースDaisyのパッケージレシピ群です。最新リリースDizzyのパッケージレシピ群を取得したい場合は、このオプションを「-b dizzy」に変えてください。meta-openembeddedリポジトリの格納先ディレリトは何処に作成してもでも構いませんが、私の場合は、ブランチと一致するPoky格納先ディレクトリの直下に作成しています。上のコマンドを実行すると、poky-daisy-11.0.1ディレクトリの中にmeta-openembeddedというディレクトリが作成されます。ちなみに、Yocto Linuxの全レシピをGitリポジトリから取得してPokyを構成したい場合は、以下のコマンドによってそれができます。
$ cd ~/Yocto
$ git clone git://git.yoctoproject.org/poky.git -b daisy poky-daisy
$ cd poky-daisy
$ git clone git://git.yoctoproject.org/meta-intel.git -b daisy
$ git clone git://git.openembedded.org/meta-openembedded -b daisy

上では、BSPはYocto Project Gitリポジトリの「meta-intel」ツリーから取得していますが、このリポジトリ・ツリーにはIntel x86系プロセッサ搭載ターゲット用のすべての種類のBSPレシピが管理されています。meta-intelリポジトリ・ツリーからBSPレシピを取得すれば、x86系プロセッサを搭載したほとんどの種類のターゲットへYocto Linuxを移植することができます。なお、x86系プロセッサ以外のBSPは他のリポジトリ・ツリーで管理されているので、それらを取得したい場合は、Yocto Project Gitリポジトリから探してください。Yocto ProjectやOpenEmbeddedで管理されているもの以外にもBSPは存在しています。OpenEmbeddedから派生したプロジェクトのアーカイブページやGitリポジトリにもBSPが収集されているので、これらのサイトを探すと見つかったりします。

上で紹介したmeta-openembeddedリポジトリには非常に多く種類のパッケージレシピが収集されており、組込みLinuxで利用されるソフトウェアのほとんどがこの中に存在しています。Yocto Linuxの配布パッケージに収納されているopenembedded-coreリポジトリのパッケージレシピ群だけではマイナーな用途向けのシステムを構築するのは難しいでしょう。その場合は、上記のmeta-openembeddedリポジトリから取得したパッケージレシピ群を追加すると、目的に合ったシステムを構築できることが多いです。この2つは常に一緒に利用することをお勧めします。

■ DE3815TYKHE BSPへのWi-Fi AP用ターゲットの追加


meta-openembeddedリポジトリからパッケージレシピを取得したら、その中に含まれているhostapdのレシピを使って、Yocto Linuxへhostapdを組み込むことができます。Wi-Fi AP用システムに追加すべきWi-Fi関連パッケージは次の5つです。
  • linux-firmware-*
  • connman
  • wireless-tools
  • hostapd-daemon
  • busybox-udhcpd

これらのパッケージをシステム構成イメージへ組み込めば、Wi-Fi AP用のシステムを構築できます。

DE3815TYKHEをWi-Fi APとして使用するにあたって、同BSPへWi-Fi AP用の新しいターゲット定義を追加することにしました。組込みLinuxではWi-Fi端末のようなクライアント側の機器がターゲットとなるこが多いので、既存のターゲット定義を汎用として残したかったからです。Wi-Fi APのシステム構成は特殊なので、専用のターゲット定義を追加した方が良いと判断しました。Wi-Fi AP専用ターゲットの名前は、安直ですが「de3815tybe-ap」にしました。この「de3815tybe-ap」のターゲット定義ファイルの内容とカーネルレシピの変更内容を以下に示します。
#@TYPE: Machine
#@NAME: Intel DE3815TYBE (Thin Canyon) board which is embedded in NUC Kit DE3815TYKHE

#@WEBTITLE: Intel Atom E38xx Processor (DE3815TYBE) 64-bit with Open Source Frame Buffer Graphics

#@DESCRIPTION: Machine configuration for DE3815TYBE 64-bit systems, without Intel-proprietary graphics bits

PREFERRED_PROVIDER_virtual/kernel ?= "linux-yocto"
PREFERRED_VERSION_linux-yocto ?= "3.10%"

require conf/machine/include/intel-corei7-64-common.inc
require conf/machine/include/intel-common-pkgarch.inc
require conf/machine/include/meta-intel.inc

MACHINE_FEATURES += "pcbios efi"
MACHINE_FEATURES += "wifi"

MACHINE_EXTRA_RRECOMMENDS += "linux-firmware"

XSERVER ?= "${XSERVER_X86_BASE} \
${XSERVER_X86_EXT} \
${XSERVER_X86_FBDEV} \
${XSERVER_X86_I965} \
"

APPEND += "acpi_enforce_resources=lax video=efifb:off vga=0x318"

FILESEXTRAPATHS_prepend := "${THISDIR}/${PN}:"

#############################
# MACHINE = de3815tybe-32 #
#############################
COMPATIBLE_MACHINE_de3815tybe-32 = "de3815tybe-32"
KMACHINE_de3815tybe-32 = "valleyisland-32"
KBRANCH_de3815tybe-32 = "standard/base"
KERNEL_FEATURES_de3815tybe-32 = " features/valleyisland-io/valleyisland-io \
features/valleyisland-io/valleyisland-io-pci.scc \
features/wifi/wifi-all.scc"

LINUX_VERSION_de3815tybe-32 = "3.10.43"
SRCREV_machine_de3815tybe-32 = "aa677a2d02677ec92d59a8c36d001cf2f5cf3260"
SRCREV_meta_de3815tybe-32 = "199943142f7e0a283240246ee6c02f4376b315f0"
SRCREV_valleyisland-io_de3815tybe-32 = "27bc40c174bb4ca160eafd6ccf3da9e774c9a8c7"

SRC_URI_de3815tybe-32 = "git://git.yoctoproject.org/linux-yocto-3.10.git;protocol=git;nocheckout=1;branch=${KBRANCH},${KMETA},valleyisland-io-2.0;name=machine,meta,valleyisland-io"

SRC_URI_de3815tybe-32 += "file://add_driver-net_ethernet_r8169.cfg"

#############################
# MACHINE = de3815tybe-64 #
#############################
COMPATIBLE_MACHINE_de3815tybe-64 = "de3815tybe-64"
KMACHINE_de3815tybe-64 = "valleyisland"
KBRANCH_de3815tybe-64 = "standard/base"
KERNEL_FEATURES_de3815tybe-64 = " features/valleyisland-io/valleyisland-io \
features/valleyisland-io/valleyisland-io-pci.scc \
features/wifi/wifi-all.scc"

LINUX_VERSION_de3815tybe-64 = "3.10.43"
SRCREV_machine_de3815tybe-64 = "aa677a2d02677ec92d59a8c36d001cf2f5cf3260"
SRCREV_meta_de3815tybe-64 = "199943142f7e0a283240246ee6c02f4376b315f0"
SRCREV_valleyisland-io_de3815tybe-64 = "27bc40c174bb4ca160eafd6ccf3da9e774c9a8c7"

SRC_URI_de3815tybe-64 = "git://git.yoctoproject.org/linux-yocto-3.10.git;protocol=git;nocheckout=1;branch=${KBRANCH},${KMETA},valleyisland-io-2.0;name=machine,meta,valleyisland-io"

SRC_URI_de3815tybe-64 += "file://add_driver-net_ethernet_r8169.cfg"

#############################
# MACHINE = de3815tybe-ap #
#############################
COMPATIBLE_MACHINE_de3815tybe-ap = "de3815tybe-ap"
KMACHINE_de3815tybe-ap = "valleyisland"
KBRANCH_de3815tybe-ap = "standard/base"
KERNEL_FEATURES_de3815tybe-ap = " features/valleyisland-io/valleyisland-io \
features/valleyisland-io/valleyisland-io-pci.scc \
features/wifi/wifi-all.scc \
features/hostapd/hostapd.scc"

LINUX_VERSION_de3815tybe-ap = "3.10.43"
SRCREV_machine_de3815tybe-ap = "aa677a2d02677ec92d59a8c36d001cf2f5cf3260"
SRCREV_meta_de3815tybe-ap = "199943142f7e0a283240246ee6c02f4376b315f0"
SRCREV_valleyisland-io_de3815tybe-ap = "27bc40c174bb4ca160eafd6ccf3da9e774c9a8c7"

SRC_URI_de3815tybe-ap = "git://git.yoctoproject.org/linux-yocto-3.10.git;protocol=git;nocheckout=1;branch=${KBRANCH},${KMETA},valleyisland-io-2.0;name=machine,meta,valleyisland-io"

SRC_URI_de3815tybe-ap += "file://add_driver-net_ethernet_r8169.cfg"

module_autoload_i2c-dev = "i2c-dev"

de3815tybe-ap.confconf/machine/de3815tybe-64.confをコピーしただけです。linux-yocto_3.10.bbappendの方は、同ファイル内の「de3815tybe-64」の部分をコピペして、変数名とターゲット名を変更し、さらにWi-Fi AP固有の設定を追加しています。「KERNEL_FEATURES_de3815tybe-ap = " ... features/hostapd/hostapd.scc"」という箇所がそれです。このfeatures/hostapd/hostapd.sccというファイルには、カーネルのソースツリーに存在するWi-Fi AP固有の機能を有効にするコンフィグレーション設定が含まれています。これは無線LANドライバと連携して動作するので、前記事で追加したfeatures/wifi/wifi-all.sccは残してあります。Wi-Fi AP用ターゲット「de3815tybe-ap」を追加した後のDE3815TYKHE BSPのファイル構成を以下に示します。

  meta-de3815tybe
|
|-- conf
| |-- machine
| | |-- de3815tybe-32.conf
| | |-- de3815tybe-64.conf
| | `-- de3815tybe-ap.conf
| `-- layer.conf
|-- recipes-bsp
| `-- formfactor
| |-- formfactor
| | |-- de3815tybe-32
| | | `-- machconfig
| | |-- de3815tybe-64
| | | `-- machconfig
| | `-- de3815tybe-ap
| | `-- machconfig
| `-- formfactor_0.0.bbappend
`-- recipes-kernel
`-- linux
|-- linux-yocto
| `-- add_driver-net_ethernet_r8169.cfg
`-- linux-yocto_3.10.bbappend


■ カスタム・レイヤの作成


DE3815TYKHE BSPへのWi-Fi AP用ターゲットの追加が終わったので、これ以降Yocto LinuxでWi-Fi AP用システムを構築していきます。BSPだけでなく、イメージレシピ、パッケージレシピなども改造していかないと、Yocto LinuxでWi-Fi APのような特定用途向けのシステムを構築することはできません。

10/25の記事に、新しいターゲット用のBSPを作成する場合独立したBSPレイヤに収納するのがセオリーだと書きましたが、これと同様に、特定用途向けシステム用に新しいレシピを作成したり既存のレシピを改造していく場合、これらのレシピは独立したレイヤに収納していくのがYocto Linuxのセオリーです。このセオリーに従って、ここで、先にWi-Fi APシステム用のレイヤを作成することにします。Yocto Linuxで新しいレイヤを作成するには、yocto-layerというスクリプトを使います(既存のレイヤをコピーして作成することもできますが、新しいレイヤを作成する場合は、できるだけこのyocto-layerスクリプトを使うことをお勧めします)。具体的には、以下のようなコマンドを実行すると、新しいレイヤを作成することができます。
$ cd ~/Yocto
$ cd poky-daisy-11.0.1
$ . ./oe-init-build-env de3815tybe
$ cd ..
$ yocto-layer create kronus9
Please enter the layer priority you'd like to use for the layer: [default: 6]
Would you like to have an example recipe created? (y/n) [default: n] y
Please enter the name you'd like to use for your example recipe: [default: example]
Would you like to have an example bbappend file created? (y/n) [default: n]

New layer created in meta-kronus9.

Don't forget to add it to your BBLAYERS (for details see meta-kronus9\README).

yocto-layerスクリプトは、oe-init-build-envスクリプトによって設定される環境変数を参照するので、先に一度oe-init-build-envを実行しておく必要があります。上では、既存のビルド作業ディレクトリであるde3815tybeを同スクリプトのパラメータとして指定していますが、ビルド作業ディレクトリを一つも作成していない場合は、パラメータなしでoe-init-build-envスクリプトを実行すると良いでしょう(その場合、デフォルトのbuildというビルド作業ディレクトリが作成されます)。上のコマンドを実行すると、「meta-kronus9」という名前のディレクトリが作成されます。作成直後のレイヤ・ディレクトリには以下のようなファイルが格納されています。

  meta-kronus9
|
|-- conf
| `-- layer.conf
|-- recipes-example
| `-- example
| |-- example-0.1
| | |-- example-patch
| | `-- helloworld.c
| `-- example_0.1.bb
|-- COPYING.MIT
`-- README

上のいずれのファイルも特に編集する必要はありませんが、各ファイルの内容は一度見ておくことをお勧めします。recipes-exampleディレクトリは「yocto-layers create」コマンドを実行した際の2番目の質問に「y」と入力したときに作成されます。このディレクトリには、サンプル・プログラムの定番であるhello worldアプリのソースやレシピファイルなどが格納されています。これらが必要がなれば、同質問に「n」と入力すると良いでしょう。

また、「yocto-layers create」コマンドで作成されるファイル群の中で一つ重要な役割を持っているファイルがあるので、これについて説明しておきます。レイヤ定義ファイルであるconf/layer.confがそれですが、このファイルは以下のような内容になっています。
# We have a conf and classes directory, add to BBPATH
BBPATH .= ":${LAYERDIR}"

# We have recipes-* directories, add to BBFILES
BBFILES += "${LAYERDIR}/recipes-*/*/*.bb \
${LAYERDIR}/recipes-*/*/*.bbappend"

BBFILE_COLLECTIONS += "kronus9"
BBFILE_PATTERN_kronus9 = "^${LAYERDIR}/"
BBFILE_PRIORITY_kronus9 = "6"

上の「BBFILE_PRIORITY_kronus9 」という変数の設定値は「yocto-layers create」コマンドを実行した際の1番目の質問に入力した値が適用されます。この設定値はbitbakeコマンドによってレシピファイルが参照される際の優先順位に影響を与えます。例えば、複数のレイヤに同名のレシピが存在するケースを想像してください。このようなケースにおいて、bitbakeコマンドにレシピ名だけを指定した場合、BBFILE_PRIORITYの値が大きい方のレイヤに格納されているレシピファイルの方が参照されます。レイヤを管理しているのはbblayers.confですが、このファイル内で定義している各レイヤの優先度を知りたい場合は、下のコマンドで確認することができます。
$ bitbake-layers show-layers
layer path priority
==========================================================================
meta /home/yuhri/Yocto/poky-daisy-11.0.1/meta 5
meta-yocto /home/yuhri/Yocto/poky-daisy-11.0.1/meta-yocto 5
meta-yocto-bsp /home/yuhri/Yocto/poky-daisy-11.0.1/meta-yocto-bsp 5
meta-oe /home/yuhri/Yocto/poky-daisy-11.0.1/meta-openembedded/meta-oe 6
meta-intel /home/yuhri/Yocto/poky-daisy-11.0.1/meta-intel 5
meta-de3815tybe /home/yuhri/Yocto/poky-daisy-11.0.1/meta-de3815tybe 6
meta-kronus9 /home/yuhri/Yocto/poky-daisy-11.0.1/meta-kronus9 6

以上、カスタム・レイヤの作成方法について説明しましたが、いかがでしたでしょうか。特に難しい箇所はなかったと思うので、練習のつもりで一度新しいレイヤを作成してみることをお勧めします。作成直後のレイヤ・ディレクトリにはhello worldアプリのレシピしか格納されていないので、既存のレイヤのレシピに影響を与えることはありません。

これ以降、上で作成したmeta-kronus9レイヤにWi-Fi APシステム用のレシピを追加していきますが、説明の都合上、先に最終的なファイル構成を示しておきます。

  meta-kronus9
|
|-- conf
| `-- layer.conf
|-- recipes-core
| |-- busybox
| | |-- busybox
| | | `-- de3815tybe-ap
| | | `-- udhcpd.conf
| | `-- busybox_1.22.1.bbappend
| |-- images
| | `-- kronus9-image-wifiap.bb
| `-- init-ifupdown
| |-- init-ifupdown
| | `-- de3815tybe-ap
| | `-- interfaces
| `-- init-ifupdown_1.0.bbappend
|-- recipes-connectivity
| |-- connman
| | |-- connman
| | | `-- de3815tybe-ap
| | | `-- main.conf
| | `-- connman_1.22.bbappend
| `-- hostapd
| |-- hostap-daemon
| | `-- hostapd.conf-kronus9
| `-- hostap-daemon_1.0.bbappend
|-- COPYING.MIT
`-- README


■ Wi-Fi AP用イメージレシピの作成


前記事で紹介したlocal.confに「IMAGE_INSTALL_append_pn-<IMAGE_NAME>」という設定を追加する方法によって、既存のイメージへパッケージを組み込むことができます。数個のパッケージを追加するだけなら、この方法は手っ取り早い方法なのですが、パッケージを列記しているだけなので、パッケージの種類と数が増えてくると管理が大変になってくるでしょう。

特定用途向けにシステムを構築するなら、やはりその目的に合ったイメージレシピをちゃんと作成しておくべきです。今回の目的はDE3815TYKHEをWi-Fiアクセスポイントとして使用することなので、meta-kronus9レイヤの中に以下のようなWi-Fi AP用のイメージレシピを作成しました。
#
# Copyright (C) 2014 Kronus Nine Computer Works
#

DESCRIPTION = "A console-only image for a Wi-Fi access point target."

IMAGE_FEATURES += "splash ssh-server-openssh package-management"

IMAGE_INSTALL = "\
${CORE_IMAGE_BASE_INSTALL} \
packagegroup-core-full-cmdline \
${CORE_IMAGE_EXTRA_INSTALL} \
"

inherit core-image

IMAGE_INSTALL += "\
kernel-modules \
connman \
wireless-tools \
hostap-daemon \
busybox-udhcpd \
"

「core-image」クラスレシピ(「クラスレシピ」については別の記事で解説するつもりです)を継承しているので、このイメージレシピの格納先はrecipes-core/imagesディレクトリにしました。ディレクトリ階層さえ合っていれば、レシピファイルの格納先は特に制限はありません。ただし、第2階層(レイヤ・ディレクトリの直下)のディレクトリ名は「recipes-*」でなければなりません。また、上のkronus9-image-wifiap.bbに「IMAGE_INSTALL = "... packagegroup-core-full-cmdline"」という記述が存在していることから判るかと思いますが、このイメージレシピはCLI環境用です。Wi-Fi APにGUI環境は必要ないので、GUI関連のパッケージは除外してあります。

■ hostap-daemonレシピのカスタマイズ


Wi-Fi AP用のイメージレシピを作成できたので、続いて、個々のパッケージレシピをカスタマイズしていきます。

最初に、Wi-Fi APの要となるhostapdのレシピを改造します。hostapdからいくつかのパッケージが生成されますが、改造するのはhostapdのデーモン部分であるhostap-daemonのレシピです。以下が、ここでの改造の対象となるhostap-daemonのレシピです。
HOMEPAGE = "http://hostap.epitest.fi"
SECTION = "kernel/userland"
LICENSE = "GPLv2 | BSD"
LIC_FILES_CHKSUM = "file://README;md5=4d709ce0f9c84b87d148e16731f647e1"
DEPENDS = "libnl openssl"
SUMMARY = "User space daemon for extended IEEE 802.11 management"

inherit update-rc.d
INITSCRIPT_NAME = "hostapd"


DEFAULT_PREFERENCE = "-1"

SRC_URI = " \
http://hostap.epitest.fi/releases/hostapd-${PV}.tar.gz \
file://defconfig \
file://init \
"

S = "${WORKDIR}/hostapd-${PV}/hostapd"


do_configure() {
install -m 0644 ${WORKDIR}/defconfig ${S}/.config
}

do_compile() {
export CFLAGS="-MMD -O2 -Wall -g -I${STAGING_INCDIR}/libnl3"
make
}

do_install() {
install -d ${D}${sbindir} ${D}${sysconfdir}/init.d
install -m 0644 ${S}/hostapd.conf ${D}${sysconfdir}
install -m 0755 ${S}/hostapd ${D}${sbindir}
install -m 0755 ${S}/hostapd_cli ${D}${sbindir}
install -m 755 ${WORKDIR}/init ${D}${sysconfdir}/init.d/hostapd
}

CONFFILES_${PN} += "${sysconfdir}/hostapd.conf"

SRC_URI[md5sum] = "236247a7bbd4f60d5fa3e99849d1ffc9"
SRC_URI[sha256sum] = "002e9dcb7e46cf82b5900a2fcf92b30fc8cdfd32a72d7fd4488588f1c013dfcc"

そして、上のhostap-daemonのレシピを改造するために、今回作成した拡張レシピを以下に示します。
FILESEXTRAPATHS_prepend := "${THISDIR}/${PN}:"

SRC_URI += "file://hostapd.conf-kronus9"

do_install_append () {
install -d ${D}${sysconfdir}
install -m 0644 ${WORKDIR}/hostapd.conf-kronus9 ${D}${sysconfdir}/hostapd.conf
}

いままで特に区別せずに、.bbと.bbappendのどちらもレシピファイルと呼んできましたが、この2つのファイルは役割が異なっています。bbがレシピ本体の定義を含み、bbappendの方は既存のレシピに対する拡張定義として働きます。bb + bbappendで一つのレシピを構成している考えれば解かり易いでしょう。ただし、レシピの名前とバージョンは一致している必要があります。例えば、hostap-daemon_1.0.bbappendというファイルを作成した場合、このファイルはhostap-daemon_1.0.bbに適用される拡張レシピ定義が記述されていると、bitbakeコマンドによって解釈されます。仮にhostap-daemon_1.1.bbappendというファイルを作成した場合、このファイルはhostap-daemon_1.0.bbには適用されません。既存のレシピをカスタマイズしたい場合、bbファイル側には一切変更を加えず、bbappendファイルを作成してその中に改造したい内容を記述するようにします。これはYocto Linuxのレシピ・カスタマイズの基本ルールです。なお、各レシピのbbファイルに適用されるbbappendファイルが存在するかどうかを知りたい場合は、下のコマンドによってその一覧情報を表示させることができます。
$ bitbake-layers show-appends
Parsing recipes..done.
=== Appended recipes ===
alsa-state.bb:
/home/yuhri/Yocto/poky-daisy-11.0.1/meta-yocto-bsp/recipes-bsp/alsa-state/alsa-state.bbappend
busybox_1.22.1.bb:
/home/yuhri/Yocto/poky-daisy-11.0.1/meta-kronus9/recipes-core/busybox/busybox_1.22.1.bbappend
connman_1.22.bb:
/home/yuhri/Yocto/poky-daisy-11.0.1/meta-kronus9/recipes-connectivity/connman/connman_1.22.bbappend
formfactor_0.0.bb:
/home/yuhri/Yocto/poky-daisy-11.0.1/meta-yocto-bsp/recipes-bsp/formfactor/formfactor_0.0.bbappend
/home/yuhri/Yocto/poky-daisy-11.0.1/meta-de3815tybe/recipes-bsp/formfactor/formfactor_0.0.bbappend
hostap-daemon_1.0.bb:
/home/yuhri/Yocto/poky-daisy-11.0.1/meta-kronus9/recipes-connectivity/hostapd/hostap-daemon_1.0.bbappend
init-ifupdown_1.0.bb:
/home/yuhri/Yocto/poky-daisy-11.0.1/meta-kronus9/recipes-core/init-ifupdown/init-ifupdown_1.0.bbappend
linux-yocto_3.14.bb:
/home/yuhri/Yocto/poky-daisy-11.0.1/meta-yocto-bsp/recipes-kernel/linux/linux-yocto_3.14.bbappend
/home/yuhri/Yocto/poky-daisy-11.0.1/meta-intel/common/recipes-kernel/linux/linux-yocto_3.14.bbappend
linux-yocto_3.10.bb:
/home/yuhri/Yocto/poky-daisy-11.0.1/meta-yocto-bsp/recipes-kernel/linux/linux-yocto_3.10.bbappend
/home/yuhri/Yocto/poky-daisy-11.0.1/meta-intel/common/recipes-kernel/linux/linux-yocto_3.10.bbappend
/home/yuhri/Yocto/poky-daisy-11.0.1/meta-de3815tybe/recipes-kernel/linux/linux-yocto_3.10.bbappend
linux-yocto-rt_3.10.bb:
/home/yuhri/Yocto/poky-daisy-11.0.1/meta-intel/common/recipes-kernel/linux/linux-yocto-rt_3.10.bbappend
linux-yocto-rt_3.14.bb:
/home/yuhri/Yocto/poky-daisy-11.0.1/meta-intel/common/recipes-kernel/linux/linux-yocto-rt_3.14.bbappend
packagegroup-core-tools-profile.bb:
/home/yuhri/Yocto/poky-daisy-11.0.1/meta-yocto-bsp/recipes-core/packagegroups/packagegroup-core-tools-profile.bbappend
psplash_git.bb:
/home/yuhri/Yocto/poky-daisy-11.0.1/meta-yocto/recipes-core/psplash/psplash_git.bbappend
xserver-xf86-config_0.1.bb:
/home/yuhri/Yocto/poky-daisy-11.0.1/meta-yocto-bsp/recipes-graphics/xorg-xserver/xserver-xf86-config_0.1.bbappend
linux-yocto_3.4.bb (skipped):
/home/yuhri/Yocto/poky-daisy-11.0.1/meta-yocto-bsp/recipes-kernel/linux/linux-yocto_3.4.bbappend
linux-yocto-dev.bb (skipped):
/home/yuhri/Yocto/poky-daisy-11.0.1/meta-intel/common/recipes-kernel/linux/linux-yocto-dev.bbappend
uclibc_git.bb (skipped):
/home/yuhri/Yocto/poky-daisy-11.0.1/meta-yocto-bsp/recipes-core/uclibc/uclibc_git.bbappend

プログラムのコンフィグレーション設定、コンパイル・ルール、パッケージ生成方法などはすべてbbファイルの方に記述されているので、bbappendの方には追加パッチの適用方法やシステム固有の設定ファイルのインストール方法などを記述するのが一般的です(bbファイル側のすべての変数や関数を書き換えることも可能です)。上のhostap-daemon_1.0.bbappendに「SRC_URI += ...」という変数と「do_install_append」という関数が記述されていますが、前者はhostap-daemon_1.0.bb側に存在する「SRC_URI」変数へ値を追加し、後者は同ファイルに存在する「do_install」関数への追加処理コードとして働きます。

上記のhostap-daemon_1.0.bbappendでは、「install」コマンドによってhostapd.conf-kronus9というファイルをhostapd.confにリネームしながらパッケージへ追加しています。ターゲットシステム上では/etc/hostapd.confに配置されますが、このファイルは以下のような内容になっています。
ctrl_interface=/var/run/hostapd
interface=wlan0
driver=nl80211
ssid=kronus9-ap
wps_pin_requests=/var/run/hostapd_wps_pin_requests
wps_state=2
ap_setup_locked=0
ap_pin=69691515
eapol_key_index_workaround=0
eap_server=0
macaddr_acl=0
auth_algs=1
ignore_broadcast_ssid=0
wpa=3
wpa_key_mgmt=WPA-PSK
wpa_pairwise=CCMP
rsn_pairwise=CCMP
wpa_group_rekey=0
wpa_passphrase=k9141214
wmm_enabled=1
ieee80211n=1
ht_capab=[HT40-][SHORT-GI-20][SHORT-GI-40][RX-STBC1]
ieee80211d=1
country_code=JP
hw_mode=g
channel=9

このファイルに含まれているのは、hostap daemon(hostapdのデーモン・プログラム部分)の動作を制御するための設定項目です。「ssid=kronus9-ap」がWi-Fi APのSSID、「wpa_passphrase=k9141214」がパスフレーズに相当します(hostapdの配布元サイトに全設定項目の説明が記載されたサンプルhostapd.confが置かれています。また、hostapdのソースパッケージにも同ファイルが収納されています。hostapd.confの各項目の詳細についてはこれらを参照してください)。

Yocto Linuxのレシピファイルであるbbとbbappendで使われているプログラミング言語はPythonとシェルスクリプトです。レシピファイルの記述方法には色々なルールやテクニックが存在しています。これらを理解・習得すると、Yocto Linuxのシステム構成を自由自在に変えることができるようになります。こういう情報については、これからの記事でおいおい解説していきたいと思っています。

■ connmanレシピのカスタマイズ


hostap-daemonレシピの改造が終ったので、続いてconnmanのレシピを改造していきましょう。

connman(Connection Manage)はIntelとNokiaが共同で開発したソフトウェアで、inetdやxinetdに代わってネッワークマネージャとして働きます。Yocto LinuxだけでなくTizen, OpenELEC, Saifish OSでも採用されています。connmanはWi-Fiだけでなく、Ethernet, Bluetooth, 3G, WiMAX、そしてVPNまで管理できる優れ物のネッワークマネージャです。

以下に、Wi-Fi APシステム用のconnmanレシピの改造内容を示します。
FILESEXTRAPATHS_prepend := "${THISDIR}/${PN}:"

SRC_URI_de3815tybe-ap += "file://main.conf"

do_install_append_de3815tybe-ap () {
install -d ${D}${sysconfdir}/connman
install -m 0644 ${WORKDIR}/main.conf ${D}${sysconfdir}/connman/main.conf
}

上のレシピに記述されているのは、ターゲットシステムに/etc/connman/main.confというファイルを作成する処理だけです。このファイルの内容を下に示します。
[General]
NetworkInterfaceBlacklist=mon.wlan,wlan

一連の作業の最初の方で、DE3815TYKHE BSPのlinux-yocto_3.10.bbappendにWi-Fi AP用のカーネル・コンフィグレーション設定を追加しましたが、この変更によって、ターゲットシステム上でカーネルの起動時に「mon.wlan0」と「wlan0」という2つのデバイスが生成されます。この2つのデバイスをconnmanの管理から外すのが、上のmain.confの役割です。connmanの無線LANインターフェース管理機能はwpa-supplicant経由で動作しますが、これはWi-Fi端末(無線LAN子機)側専用の機能です。Wi-Fi AP(無線LAN親機)では、mon.wlan0とwlan0デバイスはhostapdによって管理されなればなりません。connmanとhostapdの無線LANインターフェース管理機能はバッティングしてしまうので、前者を活かしておくと後者は正常に動作しなくなります。

なお、上のレシピで使われている一つのテクニックについて解説しておきましょう。connman_1.22.bbappend内の「SRC_URI_de3815tybe-ap += 」と「do_install_append_de3815tybe-ap」という2つの記述と、main.confファイルのconnman/connman/de3815tybe-ap/main.confという配置に注目してください。このようにすると、上のconnman_1.22.bbappendはターゲット「de3815tybe-ap」に対してのみ適用されるようになります。複数のターゲット向けにシステムを構築していて、ターゲット別に特定のパッケージのコンフィグレーションや設定ファイルの内容を変えたい場合は、この方法を使うと対応できます。Yocto Linuxではこのテクニックがあちらこちらのレシピで使われおり、もっとも利用頻度の高いテクニックの一つになっています。

■ init-ifupdownレシピのカスタマイズ


hostap-daemonとconnmanのレシピを改造しましたが、Wi-Fi APシステムでは、これ以外に2つほど改造しなればならないパッケージがあります。init-ifupdownとbusyboxがそれです。

先にinit-ifupdownレシピの拡張定義の内容を以下に示します。
FILESEXTRAPATHS_prepend := "${THISDIR}/${PN}:"

hostap-daemonとconnmanには「SRC_URI += 」と「do_install_append 」という記述が存在しましたが、上のレシピにはどちらも存在しましせん。それでも生成されるパッケージ内のinterfaces(ターゲットシステムの/etc/network/interfaces)はinit-ifupdown/init-ifupdown/de3815tybe-ap/interfacesの内容に書き換えられます。なぜかというと、上のinit-ifupdown_1.0.bbappendの拡張対象となるinit-ifupdown_1.0.bbが以下のような内容だからです。
SUMMARY = "Basic TCP/IP networking init scripts and configuration files"
DESCRIPTION = "This package provides high level tools to configure network interfaces"
HOMEPAGE = "http://packages.debian.org/ifupdown"
SECTION = "base"
LICENSE = "GPLv2"
LIC_FILES_CHKSUM = "file://${WORKDIR}/copyright;md5=3dd6192d306f582dee7687da3d8748ab"
PR = "r7"

inherit update-rc.d

INITSCRIPT_NAME = "networking"
INITSCRIPT_PARAMS = "start 01 2 3 4 5 . stop 80 0 6 1 ."

SRC_URI = "file://copyright \
file://init \
file://interfaces \
file://nfsroot"

do_install () {
install -d ${D}${sysconfdir}/init.d \
${D}${sysconfdir}/network/if-pre-up.d \
${D}${sysconfdir}/network/if-up.d \
${D}${sysconfdir}/network/if-down.d \
${D}${sysconfdir}/network/if-post-down.d
install -m 0755 ${WORKDIR}/init ${D}${sysconfdir}/init.d/networking
install -m 0644 ${WORKDIR}/interfaces ${D}${sysconfdir}/network/interfaces
install -m 0755 ${WORKDIR}/nfsroot ${D}${sysconfdir}/network/if-pre-up.d
}

do_install_append_qemuall () {
# Disable network manager on machines that commonly do NFS booting
touch ${D}${sysconfdir}/network/nm-disabled-eth0
}

PACKAGE_ARCH_qemuall = "${MACHINE_ARCH}"
RDEPENDS_${PN} = "netbase"
RCONFLICTS_${PN} = "netbase (< 1:5.0)"

CONFFILES_${PN} = "${sysconfdir}/network/interfaces"

変数「SRC_URI = "..."」の設定値に「file://interfaces」が含まりており、かつ関数「do_install」の処理コードにも「install -m 0644 ${WORKDIR}/interfaces ${D}${sysconfdir}/network/interfaces」という記述が存在しています。これらが存在しているおかげで、init-ifupdown_1.0.bbappend側に同じ記述を書く必要はなくなります。

init-ifupdown_1.0.bbappendによってパッケージに組み込まれるinterfacesは、以下のような内容です。
# /etc/network/interfaces -- configuration file for ifup(8), ifdown(8)

# The loopback interface
auto lo
iface lo inet loopback

# Wireless interfaces
auto wlan0
iface wlan0 inet static
address 192.168.100.1
netmask 255.255.255.0
network 192.168.100.0
post-up iptables -t nat -A POSTROUTING -o eth0 -s 192.168.100.0/24 -j MASQUERADE
pre-down iptables -t nat -D POSTROUTING -o eth0 -s 192.168.100.0/24 -j MASQUERADE

# Wired or wireless interfaces
auto eth0
iface eth0 inet dhcp

上では、wlan0インターフェースにスタティックIPアドレスを割り当てています。そして、iptablesコマンドを使って、NATテーブルへeth0とwlan0間のIPマスカレード転送ルールを追加しています。これは、Wi-Fi APを無線LANルーターとして動作させるために必要な設定です。

■ busyboxレシピのカスタマイズ


hostap-daemon, connman, init-ifupdownのレシピを改造してきましたが、いよいよ最後です。busyboxのレシピを改造します。

以下に、busyboxレシピに対するbbappendの定義と、これによってパッケージへ追加されるudhcpd.confファイル(ターゲットシステム上の/etc/udhcpd.conf)の内容を示します。
FILESEXTRAPATHS_prepend := "${THISDIR}/${PN}:"

SRC_URI_de3815tybe-ap += "file://udhcpd.conf"

do_install_append_de3815tybe-ap () {
install -d ${D}${sysconfdir}
install -m 0644 ${WORKDIR}/udhcpd.conf ${D}${sysconfdir}/udhcpd.conf

echo "net.ipv4.ip_forward = 1" >> ${D}${sysconfdir}/sysctl.conf
}

start 192.168.100.10
end 192.168.100.100
interface wlan0
opt dns 9.9.9.9 6.6.6.6
opt subnet 255.255.255.0
opt router 192.168.100.1
opt lease 864000

udhcpd.confはudhcpd(busyboxのDHCPデーモン)によって参照される設定ファイルです。このファイル内の項目のうち、「opt router 」のIPアドレスはwlan0インターフェースのスタティックIPアドレスと一致していなければなりません。

また、上のbusybox_1.22.1.bbappendの中でsysctl.conf(ターゲットシステム上の/etc/sysctl.conf)に設定を追加していますが、これはIPフォワーディング処理を有効にするための設定です。この設定を有効にしておかないと、/etc/network/interfacesでNATテーブルに転送ルールを追加しても、IP層でのパケット転送は行われません。

■ Wi-Fi AP用イメージのビルド


長々と説明してきましたが、やっとこれでレシピのカスタマイズがすべて終了しました。それでは、Wi-Fi APシステム用のイメージをビルドしてみましょう。meta-kronus9レイヤにWi-Fi AP用のkronus9-image-wifiapというイメージレシピを追加したので、これを使ってターゲットイメージをビルドします。

新しいレイヤに格納されているレシピを使うので、ビルドを行う前に、bblayers.confに以下のような変更を加えておく必要があります。
# LAYER_CONF_VERSION is increased each time build/conf/bblayers.conf
# changes incompatibly
LCONF_VERSION = "6"

BBPATH = "${TOPDIR}"
BBFILES ?= ""

BBLAYERS ?= " \
/home/yuhri/Yocto/poky-daisy-11.0.1/meta \
/home/yuhri/Yocto/poky-daisy-11.0.1/meta-yocto \
/home/yuhri/Yocto/poky-daisy-11.0.1/meta-yocto-bsp \
/home/yuhri/Yocto/poky-daisy-11.0.1/meta-openembedded/meta-oe \
/home/yuhri/Yocto/poky-daisy-11.0.1/meta-intel \
/home/yuhri/Yocto/poky-daisy-11.0.1/meta-de3815tybe \
/home/yuhri/Yocto/poky-daisy-11.0.1/meta-kronus9 \
"
BBLAYERS_NON_REMOVABLE ?= " \
/home/yuhri/Yocto/poky-daisy-11.0.1/meta \
/home/yuhri/Yocto/poky-daisy-11.0.1/meta-yocto \
"

そして、local.confにも以下のような変更と設定を追加します。
# This sets the default machine to be qemux86 if no other machine is selected:
MACHINE ?= "de3815tybe-ap"
MACHINE ??= "valleyisland-64"

#
# DE3815TYBE Wi-Fi AP configuration
#
PACKAGECONFIG_remove_pn-connman = "wifi bluetooth 3g"

上の「PACKAGECONFIG_remove_pn-connman」には説明が必要でしょうね。これは、connmanのビルド時に適用されるコンフィグレーションを変更するための設定です。デフォルトでは、connmanのビルド・コンフィグレーションは「PACKAGECONFIG = "wispr wifi bluetooth 3g"」とconnman_1.22.bb内に定義されているので、この設定値から「"wifi bluetooth 3g"」を除外するために、上のような設定をlocal.confに追加しています。bbファイル内に変数PACKAGECONFIGが定義されていることが条件になりますが、「PACKAGECONFIG_remove_pn-<PACKAGE_NAME>」という変数を使って、その設定値を変更することができます。なお、この設定定義はconnman_1.22.bbappendの方に記述しても構いません。その場合は、「PACKAGECONFIG_remove」という変数名を使います。local.conf側に記述している理由は、ターゲットのハード構成が変わったときにconnman_1.22.bbappend側を変更しなくて済むからです。

それでは、最後にWi-Fi APシステム用イメージのビルドをやってみましょう。ビルド方法は他のイメージと同じです。以下のコマンドを実行すると、kronus9-image-wifiapイメージをビルドできます。
$ bitbake kronus9-image-wifiap -c fetchall
$ bitbake kronus9-image-wifiap

エラーが起きずにビルドが通れば、kronus9-image-wifiap-de3815tybe-ap.hddimgという名前のhddimgファイルが生成されます。以下のコマンドを実行すれば、このファイルからLive USBメディアを作成できます。
$ umount /dev/sdc
$ sudo dd if=tmp/deploy/images/de3815tybe-ap/kronus9-image-wifiap-de3815tybe-ap.hddimg of=/dev/sdc
$ sync

このUSBメディアを使ってDE3815TYKHEでYocto Linuxを起動すると、起動後のifconfigコマンドの出力情報は以下のようになっているはずです。
# ifconfig
eth0 Link encap:Ethernet HWaddr xx:xx:xx:xx:xx:xx
inet addr:192.168.233.9 Bcast:192.168.233.255 Mask:255.255.255.0
inet6 addr: fe80::xxxx:xxff:fexx:xxxx/64 Scope:Link
UP BROADCAST RUNNING MULTICAST DYNAMIC MTU:1500 Metric:1
RX packets:6 errors:0 dropped:0 overruns:0 frame:0
TX packets:16 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:1177 (1.1 KiB) TX bytes:3072 (3.0 KiB)

lo Link encap:Local Loopback
inet addr:127.0.0.1 Mask:255.0.0.0
inet6 addr: ::1/128 Scope:Host
UP LOOPBACK RUNNING MTU:65536 Metric:1
RX packets:10 errors:0 dropped:0 overruns:0 frame:0
TX packets:10 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:700 (700.0 B) TX bytes:700 (700.0 B)

mon.wlan0 Link encap:UNSPEC HWaddr xx-xx-xx-xx-xx-xx-30-00-00-00-00-00-00-00-00-00
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:12 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:3798 (3.7 KiB) TX bytes:0 (0.0 B)

wlan0 Link encap:Ethernet HWaddr xx:xx:xx:xx:xx:xx
inet addr:192.168.100.1 Bcast:192.168.100.255 Mask:255.255.255.0
inet6 addr: fe80::xxxx:xxff:fexx:xxxx/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:21 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:0 (0.0 B) TX bytes:3772 (3.6 KiB)


ここで、Wi-Fi機能を搭載しているノートPC、スマホ、タブレットなどからDE3815TYKHEへ接続してみましょう。そして、Webブラウザで適当なサイトのページを開いてみてください。問題なくページが表示されれば、DE3815TYKHEはWi-Fi APとして正常に動作していることになります。

これで本記事はお終いです。DE3815TYKHEのWi-Fiアクセスポイント化を題材にして、BSPへのターゲット定義の追加方法、レイヤの作成方法、イメージレシピの作成方法、さらにパッケージレシピのカスタマイズ方法について解説しましたが、いかがでしたでしょうか。Yocto Linuxに取り組み始めたばかりのビギナーにはちょっと難易度が高かったかもしれませんが、それでも手も足も出ないほどの世界ではなさそうだと感じてもらえたら良いなぁと思いながら本記事を書きました。そう言う私も、Yocto Linuxの研究に取り組み始めた当初はその世界観になかなか馴染めませんでした。しかし、地道にたくさんのレシピを読み解いていくと、あちらこちらにテクニックのヒントやTipsが存在していることに気づきました。そして、ちゃんと仕組みが理解できてくると、自由自在にシステムを構築できそうだと思えるようになりました。Yocto Linuxは本当によく出来たディストリビューションです。本業の仕事でフルタイムでYocto Linuxの研究開発をやっているのも大きいですが、私は2ヶ月程度でYocto Linuxのあらゆる部分を弄くり回せるようになりました(カーネル移植、ミドルウェア移植、ドライバ/アプリ開発、システム構築など組込みLinuxの豊富な経験を持っていたことも効いています)。いまではYocto Linuxのすばらしさに惚れ込んでいます。そして、私はやっぱり組込みLinuxがとことん好きなんだなぁと自覚しました。

ハードだけでなくソフトについても、やはりIntelの技術力はスゴイなぁーと実感しています。Yocto Projectもそうですが、Intelが主導者的な役割をしているプロジェクトやソフトウェアを研究すると、技術的に得るものが本当に大きいです(Intelには世界トップクラスの技術者が集まっているんだから、これは当然ですが)。例えば、画像認識でもっとも広く使われているOpenCVも元はIntelが開発・公開したソフトです。このようにIntelがオリジナルを開発して、いまでは特定の分野でメジャーな存在になっているソフトはたくさんあります。組込みLinuxに興味を持っていて、Raspberry Piみたいなボードでちょこっと動作確認をやる程度では飽き足らず、さらに深くやってみたいと思っている方がいれば、ぜひYocto Linuxに挑戦しみることをお勧めします。きっと新世界が観えてきて、組込みLinuxのすばらしさを再認識できるでしょう。

【参考ページ】

 hostapd - Linux Wireless
 Software access point - ArchWiki
 How to Set up a Raspberry Pi as a Wireless Access Point
posted by とみやん at 13:15| Comment(0) | TrackBack(0) | Embedded Linux > Yocto Project