2015年01月05日

[Yocto] cryptsetup AES-NI対応機能の有効化

01/02の記事で、Linux用の暗号化ファイルシステムLUKSというものを紹介しました。この記事の中で、LUKSファイルシステムの読み書き速度の性能評価をやりましたが、その計測値が期待していたよりかなり低かったことから、cryptsetupの暗号処理でAES-NIが使われていないのではないかという疑惑が生まれました。

Yocto LinuxのcryptsetupのレシピやValley Island BSPのカーネル・コンフィグレーション設定などを調べていくうちに、やはりこの疑惑が正しいことが判りました。そして、cryptsetupのAES-NI対応機能を有効する方法も見つけました。

結論を先に書くと、DE3815TYKHE BSPのカーネルレシピを以下のように変更すると、cryptsetupのAES-NI対応機能が有効になります(Valley Island BSPも同様)。
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/ciphers/ciphers.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/ciphers/ciphers.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"

linux-yocto_3.10.bbappendに上記のような変更を加えると、カーネルの以下のコンフィグレーション設定項目が有効になります。
CONFIG_CRYPTO_AES_NI_INTEL

-*- Cryptographic API --->
*** Ciphers ***
<*> AES cipher algorithms (AES-NI)


■ LUKSファイルシステムAES-NI対応機能の性能評価


cryptsetupには暗号処理のベンチマーク機能が搭載されています。「cryptsetup benchmark」というコマンドによって、その機能を動かすことができます。

01/02の記事の追記にすでに掲載済みですが、AES-NIが無効な場合のcryptsetup自身による暗号処理のベンチマーク計測値を改めて示します。
# cryptsetup benchmark
# Tests are approximate using memory only (no storage IO).
PBKDF2-sha1 377729 iterations per second
PBKDF2-sha256 236165 iterations per second
PBKDF2-sha512 186712 iterations per second
PBKDF2-ripemd160 298229 iterations per second
PBKDF2-whirlpool 109044 iterations per second
# Algorithm | Key | Encryption | Decryption
aes-cbc 128b 48.0 MiB/s 57.4 MiB/s
serpent-cbc 128b 23.3 MiB/s 24.7 MiB/s
twofish-cbc 128b 45.1 MiB/s 53.9 MiB/s
aes-cbc 256b 38.6 MiB/s 43.8 MiB/s
serpent-cbc 256b 23.3 MiB/s 24.8 MiB/s
twofish-cbc 256b 45.1 MiB/s 53.9 MiB/s
aes-xts 256b 57.6 MiB/s 58.5 MiB/s
serpent-xts 256b 25.3 MiB/s 25.0 MiB/s
twofish-xts 256b 53.4 MiB/s 54.8 MiB/s
aes-xts 512b 44.4 MiB/s 44.4 MiB/s
serpent-xts 512b 25.3 MiB/s 25.0 MiB/s
twofish-xts 512b 53.4 MiB/s 54.8 MiB/s

比較のために、AES-NIが有効な場合の同コマンドの実行結果を以下に示します。
# cryptsetup benchmark
# Tests are approximate using memory only (no storage IO).
PBKDF2-sha1 379369 iterations per second
PBKDF2-sha256 236592 iterations per second
PBKDF2-sha512 186712 iterations per second
PBKDF2-ripemd160 298569 iterations per second
PBKDF2-whirlpool 109409 iterations per second
# Algorithm | Key | Encryption | Decryption
aes-cbc 128b 203.3 MiB/s 284.3 MiB/s
serpent-cbc 128b 23.4 MiB/s 24.9 MiB/s
twofish-cbc 128b 45.2 MiB/s 54.2 MiB/s
aes-cbc 256b 159.4 MiB/s 226.1 MiB/s
serpent-cbc 256b 23.4 MiB/s 25.0 MiB/s
twofish-cbc 256b 45.3 MiB/s 54.1 MiB/s
aes-xts 256b 256.0 MiB/s 257.1 MiB/s
serpent-xts 256b 25.3 MiB/s 25.0 MiB/s
twofish-xts 256b 53.8 MiB/s 55.0 MiB/s
aes-xts 512b 204.3 MiB/s 205.7 MiB/s
serpent-xts 512b 25.4 MiB/s 25.0 MiB/s
twofish-xts 512b 53.7 MiB/s 54.9 MiB/s

上の2つのケースの計測値を比較すると、aes-cbcとaes-xtsの性能に4〜5倍の差が出ています。OpenSSLによる性能差より少し低いですが、暗号処理エンジンとしてのAES-NIの性能は相当優秀であることがこの結果から判ります。

cryptsetupのAES-NI対応機能を有効した状態で、LUKSファイルシステムの読み書き速度の性能評価を改めてやってみました。01/02の記事と同じ方法を使って計測を行いました。以下に、LUKSファイルシステムの読み書き速度の計測結果を示します。

ファイルシステム読み込み速度(MB/sec)比率書き込み速度(MB/sec)比率
素のext3263.3694.96
LUKS ext3 AES-NI無効41.120.1542.400.44
LUKS ext3 AES-NI有効95.490.3690.720.95

AES-NIが有効な場合の計測値は期待していたほど向上していませんでした。もしかすると読み込み速度は200MB/sec位いくんじゃないかと予測していたんですが、さすがにそこまでは届いていません。それでも、AES-NIが無効な場合の計測値と比較すると、2倍強の性能差が出ています。AES-NIの効果はやはり大きいと言えます。

cryptsetup benchmark」コマンドのベンチマーク計測処理はメモリ上でのみ実行されるのに対して、上表はディスクの読み書き処理を伴った計測値です。AES-NIの性能がいかに優れていても、ディスクのI/O性能に引きずられることでこのような結果になるのかもしれません。DE3815TYKHEに組み込んでいるSATAディスクはIntel 320 Series 80GB SSDですが、これは3世代位前のSSDで、シーケンシャル・リード270MB/s、シーケンシャル・ライト90MB/sという性能です。最新の高性能なSSDを使えば、もう少し優秀な計測結果が得られるのではないかと思います。また、DE3815TYKHEに搭載されているE3815はシングルコアのプロセッサです。2コアのE3826/3827や4コアのE3845なら、ディスク読み書きや暗号処理がマルチスレッドで実行されるので、さらに性能は向上するはずです。

【2015/01/06 追記】

本記事の作業は、Poky + Valley Island BSP Daisy 1.6.2を使ってビルドしたcore-image-satoイメージを使っています。ターゲットはいつものとおりDE3815TYKHEです(いまのところ、E38xxx搭載ターゲットはこれしか持っていません)。上記の計測に使用したDE3815TYKHEの基本スペックを示しておきます。
  • CPU Intel(R) Atom(TM) Processor E3815 (512K Cache,1.46 GHz,1コア)
  • メモリ PC3L-12800(DDR3L-1600)2GB
  • ディスク Intel 320 Series 80GB SSD SATA 3Gb/s(シーケンシャル・リード270MB/s,シーケンシャル・ライト90MB/s)

本記事ではcryptsetupのAES-NI対応機能を有効にするための方法だけを記していますが、この解決方法に辿り着くまでの経緯も書いておきます。

じつは、カーネルのコンフィグレーション設定項目CONFIG_CRYPTO_AES_NI_INTELの存在は随分前から知っていました。それでも、cryptsetupのためにこの設定項目を有効にする必要はないと思っていました。その理由は、cryptsetupのレシピが以下のような内容であることを確認済みだったからです。
SUMMARY = "Manage plain dm-crypt and LUKS encrypted volumes"
DESCRIPTION = "Cryptsetup is used to conveniently setup dm-crypt managed \
device-mapper mappings. These include plain dm-crypt volumes and \
LUKS volumes. The difference is that LUKS uses a metadata header \
and can hence offer more features than plain dm-crypt. On the other \
hand, the header is visible and vulnerable to damage."
HOMEPAGE = "http://code.google.com/p/cryptsetup/"
SECTION = "console"
LICENSE = "GPL-2.0-with-OpenSSL-exception"
LIC_FILES_CHKSUM = "file://COPYING;md5=32107dd283b1dfeb66c9b3e6be312326"

DEPENDS = "util-linux lvm2 popt libgcrypt"

SRC_URI = "http://cryptsetup.googlecode.com/files/cryptsetup-${PV}.tar.bz2"
SRC_URI[md5sum] = "cd834da49fbe92dd66df02cc5c61280f"
SRC_URI[sha256sum] = "15723f0198303d4bcb99d480b7a773918e2d319f0348457988c063bdd03e109a"

inherit autotools gettext

# Use openssl because libgcrypt drops root privileges
# if libgcrypt is linked with libcap support
PACKAGECONFIG ??= "openssl"
PACKAGECONFIG[openssl] = "--with-crypto_backend=openssl,,openssl"
PACKAGECONFIG[gcrypt] = "--with-crypto_backend=gcrypt,,libgcrypt"

RRECOMMENDS_${PN} = "kernel-module-aes-generic \
kernel-module-dm-crypt \
kernel-module-md5 \
kernel-module-cbc \
kernel-module-sha256-generic \
"

EXTRA_OECONF = "--enable-static"

ハイライト表示の行に注目してください。この記述によって、cryptsetupをデフォルト状態でビルドすると、そのコンフィグレーション設定に「--with-crypto_backend=openssl」というオプションが適用されます。

このオプションはcryptsetup 1.3.0から追加されたもので、cryptsetupの配布元サイトの以下のページに説明が掲載されています。

 Cryptsetup130 - cryptsetup - Cryptsetup 1.3.0 Release Notes - Setup virtual encryption devices under dm-crypt Linux - Google Project Hosting

cryptsetupは自身では暗号処理機能を持っておらず、その機能は外部のライブラリに依存しています。「--with-crypto_backend=openssl」オプションによって、cryptsetupはOpenSSLの暗号処理機能を利用する形でビルドされます。

12/30の記事に記載したとおり、CONFIG_CRYPTO_AES_NI_INTELを有効にしなくても、OpenSSLのAES-NI対応機能はちゃんと動作していることを確認済みです。そのため、OpenSSLのライブラリに依存しているcryptsetupの暗号処理もAES-NI対応機能は有効なはずだと思い込んでいました。

ところが、実際にcryptsetupの暗号処理の性能を計測すると、AES-NI対応機能が有効になっているとは思えない計測値が得られました。もしかすると、上記のオプションが適用されていない状態でcryptsetupがビルドされているんじゃないかという疑いも持ちましたが、以下のコマンドの実行結果により、その疑惑は否定されました。
# cryptsetup benchmark --debug
# cryptsetup 1.6.2 processing "cryptsetup benchmark --debug"
# Running command benchmark.
# Installing SIGINT/SIGTERM handler.
# Unblocking interruption on signal.
# Tests are approximate using memory only (no storage IO).
# Crypto backend (OpenSSL 1.0.1j 15 Oct 2014) initialized.
# KDF pbkdf2, hash sha1: 378820 iterations per second.
PBKDF2-sha1 378820 iterations per second
# Crypto backend (OpenSSL 1.0.1j 15 Oct 2014) initialized.
# KDF pbkdf2, hash sha256: 235317 iterations per second.
PBKDF2-sha256 235317 iterations per second
# Crypto backend (OpenSSL 1.0.1j 15 Oct 2014) initialized.
# KDF pbkdf2, hash sha512: 186712 iterations per second.
PBKDF2-sha512 186712 iterations per second
# Crypto backend (OpenSSL 1.0.1j 15 Oct 2014) initialized.
# KDF pbkdf2, hash ripemd160: 298229 iterations per second.
PBKDF2-ripemd160 298229 iterations per second
# Crypto backend (OpenSSL 1.0.1j 15 Oct 2014) initialized.
# KDF pbkdf2, hash whirlpool: 109226 iterations per second.
PBKDF2-whirlpool 109226 iterations per second
# Crypto backend (OpenSSL 1.0.1j 15 Oct 2014) initialized.
# Algorithm | Key | Encryption | Decryption
aes-cbc 128b 47.9 MiB/s 57.5 MiB/s
# Crypto backend (OpenSSL 1.0.1j 15 Oct 2014) initialized.
serpent-cbc 128b 23.2 MiB/s 24.7 MiB/s
# Crypto backend (OpenSSL 1.0.1j 15 Oct 2014) initialized.
twofish-cbc 128b 45.0 MiB/s 53.7 MiB/s
# Crypto backend (OpenSSL 1.0.1j 15 Oct 2014) initialized.
aes-cbc 256b 38.6 MiB/s 43.8 MiB/s
# Crypto backend (OpenSSL 1.0.1j 15 Oct 2014) initialized.
serpent-cbc 256b 23.3 MiB/s 24.8 MiB/s
# Crypto backend (OpenSSL 1.0.1j 15 Oct 2014) initialized.
twofish-cbc 256b 45.0 MiB/s 53.8 MiB/s
# Crypto backend (OpenSSL 1.0.1j 15 Oct 2014) initialized.
aes-xts 256b 57.5 MiB/s 58.5 MiB/s
# Crypto backend (OpenSSL 1.0.1j 15 Oct 2014) initialized.
serpent-xts 256b 25.2 MiB/s 25.0 MiB/s
# Crypto backend (OpenSSL 1.0.1j 15 Oct 2014) initialized.
twofish-xts 256b 53.4 MiB/s 54.8 MiB/s
# Crypto backend (OpenSSL 1.0.1j 15 Oct 2014) initialized.
aes-xts 512b 44.5 MiB/s 44.4 MiB/s
# Crypto backend (OpenSSL 1.0.1j 15 Oct 2014) initialized.
serpent-xts 512b 25.3 MiB/s 25.0 MiB/s
# Crypto backend (OpenSSL 1.0.1j 15 Oct 2014) initialized.
twofish-xts 512b 53.4 MiB/s 54.7 MiB/s
Command successful.

--debug」というオプションはcryptsetupのすべての機能に対して働き、cryptsetupの動作時にデバッグ情報を出力してくれます。上のデバッグ情報から、AES暗号処理の実行時にちゃんとOpenSSLの初期化が行われている(多分OpenSSL側のライブラリ・ルーチンの呼び出しも行われている)ということが判ります。

それでは、なぜcryptsetupのAES-NI対応機能は有効に働かないのか。いまだにその原因は判っていませんが、次のような仮説なら立てられるじゃないかと思っています。
  • cryptsetupからのAES暗号処理の呼び出し形式がOpenSSL側のライブラリ・ルーチンと互換性が取れていないため、その処理がエラーになっている。仕方なくcryptsetupはカーネルのAES暗号処理を利用している。

この仮説が正しいかどうかは自信がありません。また、本仮説の証明方法もいまのところ思いつきません。cryptsetupのAES暗号処理のソースコードを解読するしかありませんが、さすがにそこまでする時間はいまは取れません。

ただし、いつかは本問題の原因を究明したいと思っています。上記のcryptsetupのページに "Note that kernel userspace backend is very slow for this type of operation." という記述が存在しています。cryptsetupから呼び出しているOpenSSL側のAES暗号処理がちゅんと有効に働けば、cryptsetupの性能はいまよりさらに向上するのではないかと思えるからです。
posted by とみやん at 17:33| Comment(0) | TrackBack(0) | Embedded Linux > Yocto Project

2015年01月03日

[Yocto] smartmontoolsによるディスク自己診断情報の取得

最近のハードディスクやSSDは自己診断情報を持っていて、一定のアクセス方法に従うと、CPUからこの情報を取得することができます。S.M.A.R.T.(Self-Monitoring, Analysis and Reporting Technology)と呼ばれているものがそれです。

PCに搭載されている最近のBIOSは、起動時のPOST処理実行中にHDD/SSDからS.M.A.R.T. 情報を取得して、問題を検知したらエラーメッセージを表示する機能を備えています。マザーボード・メーカーもHDD診断ソフトを作成して製品の添付CDに収納したりしていますし、フリーのWindows用HDD診断ソフトもいくつか存在します。たとえマイナーな機能のソフトであっても、Windows用が在れば必ずと言って良いほどLinuxでも同種のソフトが存在します(Linux用はオープンソース・ソフトウェアですが)。smartmontoolsというものが在り、これがS.M.A.R.T. 情報を利用したLinux用のHDD診断ソフトとして有名です。

Yocto Linuxにもsmartmontoolsのレシピが存在するので、試しにDE3815TYKHEで使ってみました。bblayers.conflocal.confに以下のような変更を加えれば、core-image-satoイメージにsmartmontoolsを組み込むことができます。
# 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.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-openembedded/meta-oe \
/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 \
/home/yuhri/Yocto/poky-daisy-11.0.2/meta-yocto \
"

#
# Additional packages to be installed to the specific images
#
IMAGE_INSTALL_append_pn-core-image-sato = " \
parted \
hdparm \
cryptsetup \
smartmontools"

ただし、前記事で紹介したcryptsetupと同様に、smartmontoolsのレシピはmeta-openembeddedリポジトリの方に収集されているので、あらかじめ同リポジトリのパッケージレシピを取得しておく必要があります。〔2014/12/14の記事を参照

HDD/SSDのS.M.A.R.T. 情報を調べるには、smartmontoolsパッケージに含まれる「smartctl」というコマンドを使います。

最初にディスクを検索したければ、「--scan」オプションを使ってできるようです。
# smartctl --scan
/dev/sda -d scsi # /dev/sda, SCSI device

「-i」オプションによって、指定したデバイスがS.M.A.R.T.に対応しているかどうかを確認できます。
# smartctl -i /dev/sda
smartctl 6.2 2013-07-26 r3841 [x86_64-linux-3.10.59-ltsi-yocto-standard] (local build)
Copyright (C) 2002-13, Bruce Allen, Christian Franke, www.smartmontools.org

=== START OF INFORMATION SECTION ===
Model Family: Intel 320 Series SSDs
Device Model: INTEL SSDSA2CW080G3
Serial Number: CVPR13710AME080BGN
LU WWN Device Id: 5 001517 9596a5d21
Firmware Version: 4PC10362
User Capacity: 80,026,361,856 bytes [80.0 GB]
Sector Size: 512 bytes logical/physical
Rotation Rate: Solid State Device
Device is: In smartctl database [for details use: -P show]
ATA Version is: ATA8-ACS T13/1699-D revision 4
SATA Version is: SATA 2.6, 3.0 Gb/s
Local Time is: Sun Jan 4 00:58:30 2015 UTC
SMART support is: Available - device has SMART capability.
SMART support is: Enabled


対象デバイスの自己診断情報を取得するには、「-a」まはた「-x」オプションを使います。前者がS.M.A.R.T.から取得可能な全情報を、後者はS.M.A.R.T.以外の情報も表示します。
# smartctl -a /dev/sda
smartctl 6.2 2013-07-26 r3841 [x86_64-linux-3.10.59-ltsi-yocto-standard] (local build)
Copyright (C) 2002-13, Bruce Allen, Christian Franke, www.smartmontools.org

=== START OF INFORMATION SECTION ===
Model Family: Intel 320 Series SSDs
Device Model: INTEL SSDSA2CW080G3
Serial Number: CVPR13710AME080BGN
LU WWN Device Id: 5 001517 9596a5d21
Firmware Version: 4PC10362
User Capacity: 80,026,361,856 bytes [80.0 GB]
Sector Size: 512 bytes logical/physical
Rotation Rate: Solid State Device
Device is: In smartctl database [for details use: -P show]
ATA Version is: ATA8-ACS T13/1699-D revision 4
SATA Version is: SATA 2.6, 3.0 Gb/s
Local Time is: Sun Jan 4 00:13:09 2015 UTC
SMART support is: Available - device has SMART capability.
SMART support is: Enabled

=== START OF READ SMART DATA SECTION ===
SMART overall-health self-assessment test result: PASSED

General SMART Values:
Offline data collection status: (0x00) Offline data collection activity
was never started.
Auto Offline Data Collection: Disabled.
Self-test execution status: ( 0) The previous self-test routine completed
without error or no self-test has ever
been run.
Total time to complete Offline
data collection: ( 1) seconds.
Offline data collection
capabilities: (0x75) SMART execute Offline immediate.
No Auto Offline data collection support.
Abort Offline collection upon new
command.
No Offline surface scan supported.
Self-test supported.
Conveyance Self-test supported.
Selective Self-test supported.
SMART capabilities: (0x0003) Saves SMART data before entering
power-saving mode.
Supports SMART auto save timer.
Error logging capability: (0x01) Error logging supported.
General Purpose Logging supported.
Short self-test routine
recommended polling time: ( 1) minutes.
Extended self-test routine
recommended polling time: ( 1) minutes.
Conveyance self-test routine
recommended polling time: ( 1) minutes.
SCT capabilities: (0x003d) SCT Status supported.
SCT Error Recovery Control supported.
SCT Feature Control supported.
SCT Data Table supported.

SMART Attributes Data Structure revision number: 5
Vendor Specific SMART Attributes with Thresholds:
ID# ATTRIBUTE_NAME FLAG VALUE WORST THRESH TYPE UPDATED WHEN_FAILED RAW_VALUE
3 Spin_Up_Time 0x0020 100 100 000 Old_age Offline - 0
4 Start_Stop_Count 0x0030 100 100 000 Old_age Offline - 0
5 Reallocated_Sector_Ct 0x0032 100 100 000 Old_age Always - 0
9 Power_On_Hours 0x0032 100 100 000 Old_age Always - 917
12 Power_Cycle_Count 0x0032 100 100 000 Old_age Always - 1164
170 Reserve_Block_Count 0x0033 100 100 010 Pre-fail Always - 0
171 Program_Fail_Count 0x0032 100 100 000 Old_age Always - 0
172 Erase_Fail_Count 0x0032 100 100 000 Old_age Always - 0
183 Runtime_Bad_Block 0x0030 100 100 000 Old_age Offline - 7522
184 End-to-End_Error 0x0032 100 100 090 Old_age Always - 0
187 Reported_Uncorrect 0x0032 100 100 000 Old_age Always - 0
192 Unsafe_Shutdown_Count 0x0032 100 100 000 Old_age Always - 120
199 UDMA_CRC_Error_Count 0x0030 100 100 000 Old_age Offline - 0
225 Host_Writes_32MiB 0x0032 100 100 000 Old_age Always - 136685
226 Workld_Media_Wear_Indic 0x0032 100 100 000 Old_age Always - 1515
227 Workld_Host_Reads_Perc 0x0032 100 100 000 Old_age Always - 77
228 Workload_Minutes 0x0032 100 100 000 Old_age Always - 55045
232 Available_Reservd_Space 0x0033 100 100 010 Pre-fail Always - 0
233 Media_Wearout_Indicator 0x0032 099 099 000 Old_age Always - 0
241 Host_Writes_32MiB 0x0032 100 100 000 Old_age Always - 136685
242 Host_Reads_32MiB 0x0032 100 100 000 Old_age Always - 459867

SMART Error Log Version: 1
No Errors Logged

SMART Self-test log structure revision number 1
Num Test_Description Status Remaining LifeTime(hours) LBA_of_first_error
# 1 Vendor (0xeb) Completed without error 00% 917 -

SMART Selective self-test log data structure revision number 0
Note: revision number not 1 implies that no selective self-test has ever been run
SPAN MIN_LBA MAX_LBA CURRENT_TEST_STATUS
1 0 0 Not_testing
2 0 0 Not_testing
3 0 0 Not_testing
4 0 0 Not_testing
5 0 0 Not_testing
Selective self-test flags (0x0):
After scanning selected spans, do NOT read-scan remainder of disk.
If Selective self-test is pending on power-up, resume after 0 minute delay.


# smartctl -x /dev/sda
smartctl 6.2 2013-07-26 r3841 [x86_64-linux-3.10.59-ltsi-yocto-standard] (local build)
Copyright (C) 2002-13, Bruce Allen, Christian Franke, www.smartmontools.org

=== START OF INFORMATION SECTION ===
Model Family: Intel 320 Series SSDs
Device Model: INTEL SSDSA2CW080G3
Serial Number: CVPR13710AME080BGN
LU WWN Device Id: 5 001517 9596a5d21
Firmware Version: 4PC10362
User Capacity: 80,026,361,856 bytes [80.0 GB]
Sector Size: 512 bytes logical/physical
Rotation Rate: Solid State Device
Device is: In smartctl database [for details use: -P show]
ATA Version is: ATA8-ACS T13/1699-D revision 4
SATA Version is: SATA 2.6, 3.0 Gb/s
Local Time is: Sun Jan 4 00:13:13 2015 UTC
SMART support is: Available - device has SMART capability.
SMART support is: Enabled
AAM feature is: Unavailable
APM feature is: Unavailable
Rd look-ahead is: Enabled
Write cache is: Enabled
ATA Security is: Disabled, frozen [SEC2]
Unexpected SCT status 0x0002 (action_code=4, function_code=2)
Wt Cache Reorder: N/A

=== START OF READ SMART DATA SECTION ===
SMART overall-health self-assessment test result: PASSED

General SMART Values:
Offline data collection status: (0x00) Offline data collection activity
was never started.
Auto Offline Data Collection: Disabled.
Self-test execution status: ( 0) The previous self-test routine completed
without error or no self-test has ever
been run.
Total time to complete Offline
data collection: ( 1) seconds.
Offline data collection
capabilities: (0x75) SMART execute Offline immediate.
No Auto Offline data collection support.
Abort Offline collection upon new
command.
No Offline surface scan supported.
Self-test supported.
Conveyance Self-test supported.
Selective Self-test supported.
SMART capabilities: (0x0003) Saves SMART data before entering
power-saving mode.
Supports SMART auto save timer.
Error logging capability: (0x01) Error logging supported.
General Purpose Logging supported.
Short self-test routine
recommended polling time: ( 1) minutes.
Extended self-test routine
recommended polling time: ( 1) minutes.
Conveyance self-test routine
recommended polling time: ( 1) minutes.
SCT capabilities: (0x003d) SCT Status supported.
SCT Error Recovery Control supported.
SCT Feature Control supported.
SCT Data Table supported.

SMART Attributes Data Structure revision number: 5
Vendor Specific SMART Attributes with Thresholds:
ID# ATTRIBUTE_NAME FLAGS VALUE WORST THRESH FAIL RAW_VALUE
3 Spin_Up_Time -----K 100 100 000 - 0
4 Start_Stop_Count ----CK 100 100 000 - 0
5 Reallocated_Sector_Ct -O--CK 100 100 000 - 0
9 Power_On_Hours -O--CK 100 100 000 - 917
12 Power_Cycle_Count -O--CK 100 100 000 - 1164
170 Reserve_Block_Count PO--CK 100 100 010 - 0
171 Program_Fail_Count -O--CK 100 100 000 - 0
172 Erase_Fail_Count -O--CK 100 100 000 - 0
183 Runtime_Bad_Block ----CK 100 100 000 - 7522
184 End-to-End_Error -O--CK 100 100 090 - 0
187 Reported_Uncorrect -O--CK 100 100 000 - 0
192 Unsafe_Shutdown_Count -O--CK 100 100 000 - 120
199 UDMA_CRC_Error_Count ----CK 100 100 000 - 0
225 Host_Writes_32MiB -O--CK 100 100 000 - 136685
226 Workld_Media_Wear_Indic -O--CK 100 100 000 - 1515
227 Workld_Host_Reads_Perc -O--CK 100 100 000 - 77
228 Workload_Minutes -O--CK 100 100 000 - 55045
232 Available_Reservd_Space PO--CK 100 100 010 - 0
233 Media_Wearout_Indicator -O--CK 099 099 000 - 0
241 Host_Writes_32MiB -O--CK 100 100 000 - 136685
242 Host_Reads_32MiB -O--CK 100 100 000 - 459867
||||||_ K auto-keep
|||||__ C event count
||||___ R error rate
|||____ S speed/performance
||_____ O updated online
|______ P prefailure warning

Log Directories not read due to '-F nologdir' option

SMART Extended Comprehensive Error Log Version: 1 (2 sectors)
No Errors Logged

SMART Extended Self-test Log Version: 1 (2 sectors)
Invalid Self-test Log index = 0x00eb (reserved = 0x00)
SMART Selective self-test log data structure revision number 0
Note: revision number not 1 implies that no selective self-test has ever been run
SPAN MIN_LBA MAX_LBA CURRENT_TEST_STATUS
1 0 0 Not_testing
2 0 0 Not_testing
3 0 0 Not_testing
4 0 0 Not_testing
5 0 0 Not_testing
Selective self-test flags (0x0):
After scanning selected spans, do NOT read-scan remainder of disk.
If Selective self-test is pending on power-up, resume after 0 minute delay.

Read SCT Data Table failed: scsi error aborted command
Read SCT Temperature History failed

SCT Error Recovery Control:
Read: Disabled
Write: Disabled

Device Statistics (GP Log 0x04)
Page Offset Size Value Description
1 ===== = = == General Statistics (rev 2) ==
1 0x008 4 1164 Lifetime Power-On Resets
1 0x010 4 917 Power-on Hours
1 0x018 6 8957811011 Logical Sectors Written
1 0x020 6 162155053 Number of Write Commands
1 0x028 6 30137881911 Logical Sectors Read
1 0x030 6 780175533 Number of Read Commands
4 ===== = = == General Errors Statistics (rev 1) ==
4 0x008 4 0 Number of Reported Uncorrectable Errors
4 0x010 4 0 Resets Between Cmd Acceptance and Completion
6 ===== = = == Transport Statistics (rev 1) ==
6 0x008 4 4433 Number of Hardware Resets
6 0x010 4 16383291 Number of ASR Events
6 0x018 4 0 Number of Interface CRC Errors
7 ===== = = == Solid State Device Statistics (rev 1) ==
7 0x008 1 1 Percentage Used Endurance Indicator

SATA Phy Event Counters (GP Log 0x11)
ID Size Value Description
0x0001 4 0 Command failed due to ICRC error
0x0004 4 0 R_ERR response for host-to-device data FIS
0x0007 4 0 R_ERR response for host-to-device non-data FIS
0x0008 4 0 Device-to-host non-data FIS retries
0x0009 4 5 Transition from drive PhyRdy to drive PhyNRdy
0x000a 4 6 Device-to-host register FISes sent due to a COMRESET
0x000b 4 0 CRC errors within host-to-device FIS
0x000d 4 0 Non-CRC errors within host-to-device FIS
0x000f 4 0 R_ERR response for host-to-device data FIS, CRC
0x0010 4 0 R_ERR response for host-to-device data FIS, non-CRC
0x0012 4 0 R_ERR response for host-to-device non-data FIS, CRC
0x0013 4 0 R_ERR response for host-to-device non-data FIS, non-CRC


どちらも難しそうな単語と数値の羅列ですね。S.M.A.R.T.情報はハードディスクの構造や動作に直結している低レベルなデータなので、これらのデータからHDD/SSDの状態を把握するのはかなり困難だと思います。

【参考ページ】

 FreeBSDでsmartmontoolsのインストール | Nobwak's Lair
 SMART:smartmontoolsでハードディスク診断
 S.M.A.R.T. (日本語) - ArchWiki
posted by とみやん at 23:05| Comment(0) | TrackBack(0) | Embedded Linux > Yocto Project

2015年01月02日

[Yocto] 暗号化ファイルシステムLUKSを使ってみた

企業内では、PCにディスク暗号化ソフトを導入して、内蔵ディスクや外付メディア全体に暗号処理を施した状態で使うことが良くあります。セキュリティ上の観点から、PC本体や外付メディアが盗難に遭っても、それらの中に格納されているファイルを読めなくすることが目的です。また、社員がUSBメディアなどを外に持ち出したときに紛失するケースなども想定しているのでしょう。いままで私が働いたことがある会社でも、暗号化ソフトを導入せずにPCを使うことを禁止している所がいくつかありました。こういう堅苦しいルールを設けているのは大抵は日本国内の大手企業だけです。外資系やベンチャー企業にはこういうルールはまずありません。暗号化ソフトを導入すると当然ディスク性能が低下し、アプリの起動やファイルの読み書きに時間がかかるようになるので作業効率が低下します。日本の大手企業は作業効率よりセキュリティを優先するのに対して、ベンチャー企業はセキュリティより作業効率を優先する所が多いです。私は外資系やベンチャー企業でも働いたことがありますが、これらの企業でPCへ暗号化ソフトを導入することを義務化している所は一つもありませんでした。現状企業内のPCから情報が漏洩するケースはインターネット経由がほとんどです。社員の故意または過失によるケースもあるでしょうが、ディスク暗号化ソフトが有益なのは、社員の過失によってディスクメディアが第三者の手に渡ったときだけです(故意の情報漏洩を企む社員なら、ディスク暗号化ソフトを回避するために、持ち込みのディスクを用意したり、スクリプトや常駐ソフトを使ってインターネット経由でデータを漏洩させるなどの方法を取るはずです)。PCの盗難によって情報が漏洩したというケースはあまり聞いたことがありません。結局ディスク暗号化ソフトをPCへ導入することは企業側の自己満足であって、実際にこれが情報漏洩を防ぐようなケースはほとんど存在しないんじゃないかと私は思っています。社員が使う全PCにディスク暗号化ソフトを導入することと、社内のサーバーやゲートウェイなどにセキュリティ対策を施することを比較すると、後者の費用対効果の方が圧倒的に優れています。改めて言いますが、現状企業からの情報漏洩で一番多いケースはインターネット経由です。外資系やベンチャー企業も当然セキュリティを重視していますが、これらの会社は費用対効果を考慮して、現実的なセキュリティ対策を選択している所が多いのが実情です。

冒頭から話が大きく逸れてしまったので元に戻しましょう。日本国内の企業での需要が高いからかWindows用ディスク暗号化ソフトは多くの種類が存在しているようですが、Linuxにも同様のオープンソース・ソフトウェアがいくつか存在します。Linux用の暗号化ファイルシステムとしてもっとも有名なのはLUKS(Linux Unified Key Setup。発音は「ラックス」)というものです。ターゲットシステム上にLUKS暗号化ファイルシステムを作成するには、cryptsetupというパッケージを利用します。本記事に書く内容は、Yocto Linuxのcryptsetupレシピを使ったLUKS暗号化ファイルシステムの評価作業の記録です。

ターゲットとして使ったのはDE3815TYKHEです。DE3815TYKHE用のbblayers.conflocal.confに以下のような変更を加えると、core-image-satoイメージにcryptsetupを組み込むことができます。
# 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.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-openembedded/meta-oe \
/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 \
/home/yuhri/Yocto/poky-daisy-11.0.2/meta-yocto \
"

#
# Additional packages to be installed to the specific images
#
IMAGE_INSTALL_append_pn-core-image-sato = " \
parted \
hdparm \
cryptsetup"

cryptsetupのレシピは、openembedded-coreではなくmeta-openembeddedリポジトリの方に収集されています。そのため、Yocto Linuxの配布パッケージにcryptsetupのレシピは収納されていません。cryptsetupのレシピを利用したい場合は、meta-openembeddedリポジトリのパッケージレシピをgitコマンドで取得しておく必要があります。〔2014/12/14の記事を参照

また、上ではpartedとhdparmパッケージもcore-image-satoイメージへ追加しています。partedは、DE3815TYKHEの内蔵SATAディスク上にLUKSファイルシステム用のパーティションを作成するために使います。hdparmの方は、これを使ってLUKSファイルシステムの読み込み速度の計測を行う目的で組み込んでいます。

■ LUKS用パーティションの確保(Intel E38xx Yocto Linux固有)


bitbakeコマンドによって、partedとcryptsetupを追加したcore-image-satoイメージのhddimgファイルを生成し、そのファイルからYocto LinxのLive USBメディアを作成しました。これはDE3815TYKHEへYocto Linuxをインストールする前のお決まりの手順ですが、その後に、GPartedのLive USBメディアも作成しました。このGPartedとpartedの両方を使って、DE3815TYKHEの内蔵SATA上にLUKSファイルシステム用のパーティション領域を確保します。GPartedとpartedはディスク・パーティションを操作する同種のソフトウェアです。partedが存在するのになぜGPartedが必要になるかというと、Yocto Linxのpartedではなぜか「resize」コマンド(パーティションのサイズを変更するコマンド)が使えないからです。GPartedの方で既存のパーティションをリサイズして空き領域を確保した上で、partedの方でその空き領域上にLUKS用パーティションを作成するというテクニックを使います。DE3815TYKHEの内蔵SATAディスク上にLUKS用パーティションを作成するための具体的な手順を以下に示します。
  1. 上で作成したYocto LinuxのLive USBメディアをUSBポートに挿した状態で、DE3815TYKHEの電源をONにします。

  2. 起動時に表示されるGRUBのメニューから「install」を選択して、DE3815TYKHEの内蔵SATAへYocto Linuxをインストールします。Yocto Linuxのインストールが済んだら(インストール完了時の「Remove your installation media, and press ENTER」というメッセージが表示されたら)、Powerボタンを長押しして、DE3815TYKHEの電源をOFFにします。

  3. USBポートのメディアをGParted Live USBに差し替えてから、DE3815TYKHEの電源をONにします。

  4. GPartedが起動したら、DE3815TYKHEの内蔵SATA上の既存のext3パーティション(/dev/sda2)のサイズを10GB縮小します(同パーティションの後方に10240MiBの空き領域を確保します。空き領域のサイズは任意です)。
    GParted_Live-Resizing_Yocto_ext3_Partition_on_SATA-775x500
    この操作が済んだら、GPartedを終了して、シャットダウンします。

  5. USBポートのメディアをYocto LinuxのLive USBに差し替えてから、DE3815TYKHEの電源をONにします。

  6. 起動時に表示されるGRUBのメニューから「boot」を選択して、Live USBメディアからYocto Linuxを起動します。

  7. ターミナルの画面を開いて、以下の手順を実行します。
    # df
    Filesystem 1K-blocks Used Available Use% Mounted on
    none 964692 4 964688 0% /dev
    /dev/sda1 18378 6410 11968 35% /media/sda1
    /dev/sda2 62736324 411152 59138280 1% /media/sda2
    /dev/sdb 350192 344648 5544 98% /media/sdb
    /dev/loop0 320464 216362 87555 71% /
    tmpfs 40 0 40 0% /mnt/.psplash
    tmpfs 969256 260 968996 0% /run
    tmpfs 969256 168 969088 0% /var/volatile
    # umount /media/sda1
    # umount /media/sda2
    # parted /dev/sda
    GNU Parted 3.1
    Using /dev/sda
    Welcome to GNU Parted! Type 'help' to view a list of commands.
    (parted) print free
    Model: ATA INTEL SSDSA2CW08 (scsi)
    Disk /dev/sda: 80.0GB
    Sector size (logical/physical): 512B/512B
    Partition Table: gpt
    Disk Flags:

    Number Start End Size File system Name Flags
    17.4kB 1049kB 1031kB Free Space
    1 1049kB 19.9MB 18.9MB fat16 primary boot
    2 19.9MB 65.3GB 65.3GB ext3 primary
    65.3GB 76.0GB 10.7GB Free Space
    3 76.0GB 80.0GB 4001MB linux-swap(v1) primary
    80.0GB 80.0GB 73.2kB Free Space

    (parted) rm 3
    (parted) mkpart primary ext2 65.3GB 76.0GB
    (parted) mkpart primary linux-swap 76.0GB 100%
    (parted) print free
    Model: ATA INTEL SSDSA2CW08 (scsi)
    Disk /dev/sda: 80.0GB
    Sector size (logical/physical): 512B/512B
    Partition Table: gpt
    Disk Flags:

    Number Start End Size File system Name Flags
    17.4kB 1049kB 1031kB Free Space
    1 1049kB 19.9MB 18.9MB fat16 primary boot
    2 19.9MB 65.3GB 65.3GB ext3 primary
    3 65.3GB 76.0GB 10.7GB primary
    4 76.0GB 80.0GB 4027MB primary
    80.0GB 80.0GB 73.2kB Free Space

    (parted) quit
    Information: You may need to update /etc/fstab.

    # mkswap /dev/sda4
    Setting up swapspace version 1, size = 4026527744 bytes
    # mount /dev/sda2 /mnt
    # cat /mnt/etc/fstab
    # stock fstab - you probably want to override this with a machine specific one

    /dev/root / auto defaults 1 1
    proc /proc proc defaults 0 0
    devpts /dev/pts devpts mode=0620,gid=5 0 0
    usbdevfs /proc/bus/usb usbdevfs noauto 0 0
    tmpfs /run tmpfs mode=0755,nodev,nosuid,strictatime 0 0
    tmpfs /var/volatile tmpfs defaults 0 0

    # uncomment this if your device has a SD/MMC/Transflash slot
    #/dev/mmcblk0p1 /media/card auto defaults,sync,noauto 0 0

    /dev/sda3 swap swap defaults 0 0
    # sed -i "s@/dev/sda3@/dev/sda4@" /mnt/etc/fstab
    # cat /mnt/etc/fstab
    # stock fstab - you probably want to override this with a machine specific one

    /dev/root / auto defaults 1 1
    proc /proc proc defaults 0 0
    devpts /dev/pts devpts mode=0620,gid=5 0 0
    usbdevfs /proc/bus/usb usbdevfs noauto 0 0
    tmpfs /run tmpfs mode=0755,nodev,nosuid,strictatime 0 0
    tmpfs /var/volatile tmpfs defaults 0 0

    # uncomment this if your device has a SD/MMC/Transflash slot
    #/dev/mmcblk0p1 /media/card auto defaults,sync,noauto 0 0

    /dev/sda4 swap swap defaults 0 0
    # umount /mnt
    # sync

DE3815TYKHEのマザーボード上にはSATAコネクタが1つしか存在しておらず、これは内蔵SATAディスクで使われています。複数のSATAコネクタが在れば、2台目のSATAディスクを接続して、そちらにLUKS用パーティションを作成できるのですが、DE3815TYKHEではそれができません。そのため、上のようなテクニックを使って内蔵SATAディスク上にLUKS用パーティションを確保している訳です。もちろんUSBメディア上にLUKS用パーティションを作成することも可能です。しかし、その場合、LUKSファイルシステムの読み書き速度はUSBメディアの性能に大きく依存してしまいます。USBメディアの読み書き速度はメーカーによって結構バラツキがあるので、比較的読み書き速度のバラツキが小さくより高速なSATAディスクを使いたかったのです。LUKSファイルシステムの読み書き速度の計測をやってみたかったことが、USBメディアではなくSATAディスクを選んだ理由です。

■ LUKSファイルシステムの作成


これでLUKSファイルシステムを使うための準備が整ったので、 さっそくcryptsetupコマンドを使ってLUKSファイルシステムを作成してみましょう。なお、以降の操作は、Yocto LinuxをDE3815TYKHEの内蔵SATAディスクから起動した状態で行っています。

最初に、cryptsetupコマンド のヘルプ情報を表示させてみました。
# cryptsetup --help
cryptsetup 1.6.2
Usage: cryptsetup [OPTION...] <action> <action-specific>
--version Print package version
-v, --verbose Shows more detailed error messages
--debug Show debug messages
-c, --cipher=STRING The cipher used to encrypt the disk (see /proc/crypto)
-h, --hash=STRING The hash used to create the encryption key from the passphrase
-y, --verify-passphrase Verifies the passphrase by asking for it twice
-d, --key-file=STRING Read the key from a file.
--master-key-file=STRING Read the volume (master) key from file.
--dump-master-key Dump volume (master) key instead of keyslots info.
-s, --key-size=BITS The size of the encryption key
-l, --keyfile-size=bytes Limits the read from keyfile
--keyfile-offset=bytes Number of bytes to skip in keyfile
--new-keyfile-size=bytes Limits the read from newly added keyfile
--new-keyfile-offset=bytes Number of bytes to skip in newly added keyfile
-S, --key-slot=INT Slot number for new key (default is first free)
-b, --size=SECTORS The size of the device
-o, --offset=SECTORS The start offset in the backend device
-p, --skip=SECTORS How many sectors of the encrypted data to skip at the beginning
-r, --readonly Create a readonly mapping
-i, --iter-time=msecs PBKDF2 iteration time for LUKS (in ms)
-q, --batch-mode Do not ask for confirmation
-t, --timeout=secs Timeout for interactive passphrase prompt (in seconds)
-T, --tries=INT How often the input of the passphrase can be retried
--align-payload=SECTORS Align payload at <n> sector boundaries - for luksFormat
--header-backup-file=STRING File with LUKS header and keyslots backup.
--use-random Use /dev/random for generating volume key.
--use-urandom Use /dev/urandom for generating volume key.
--shared Share device with another non-overlapping crypt segment.
--uuid=STRING UUID for device to use.
--allow-discards Allow discards (aka TRIM) requests for device.
--header=STRING Device or file with separated LUKS header.
--test-passphrase Do not activate device, just check passphrase.
--tcrypt-hidden Use hidden header (hidden TCRYPT device).
--tcrypt-system Device is system TCRYPT drive (with bootloader).
-M, --type=STRING Type of device metadata: luks, plain, loopaes, tcrypt.
--force-password Disable password quality check (if enabled).

Help options:
-?, --help Show this help message
--usage Display brief usage

<action> is one of:
open <device> [--type <type>] [<name>] - open device as mapping <name>
close <name> - close device (remove mapping)
resize <name> - resize active device
status <name> - show device status
benchmark <name> - benchmark cipher
repair <device> - try to repair on-disk metadata
luksFormat <device> [<new key file>] - formats a LUKS device
luksAddKey <device> [<new key file>] - add key to LUKS device
luksRemoveKey <device> [<key file>] - removes supplied key or key file from LUKS device
luksChangeKey <device> [<key file>] - changes supplied key or key file of LUKS device
luksKillSlot <device> <key slot> - wipes key with number <key slot> from LUKS device
luksUUID <device> - print UUID of LUKS device
isLuks <device> - tests <device> for LUKS partition header
luksDump <device> - dump LUKS partition information
tcryptDump <device> - dump TCRYPT device information
luksSuspend <device> - Suspend LUKS device and wipe key (all IOs are frozen).
luksResume <device> - Resume suspended LUKS device.
luksHeaderBackup <device> - Backup LUKS device header and keyslots
luksHeaderRestore <device> - Restore LUKS device header and keyslots

You can also use old <action> syntax aliases:
open: create (plainOpen), luksOpen, loopaesOpen, tcryptOpen
close: remove (plainClose), luksClose, loopaesClose, tcryptClose

<name> is the device to create under /dev/mapper
<device> is the encrypted device
<key slot> is the LUKS key slot number to modify
<key file> optional key file for the new key for luksAddKey action

Default compiled-in key and passphrase parameters:
Maximum keyfile size: 8192kB, Maximum interactive passphrase length 512 (characters)
Default PBKDF2 iteration time for LUKS: 1000 (ms)

Default compiled-in device cipher parameters:
loop-AES: aes, Key 256 bits
plain: aes-cbc-essiv:sha256, Key: 256 bits, Password hashing: ripemd160
LUKS1: aes-xts-plain64, Key: 256 bits, LUKS header hashing: sha1, RNG: /dev/urandom

親切なヘルプ情報なので、cryptsetupコマンドのほとんどの操作はこのヘルプ情報を見ながらできるんじゃないかと思います。なお、ググれば、cryptsetupコマンドの詳細情報は結構見つかります。

それでは、前述の操作によって確保したパーティション/dev/sda3をLUKSパーティションに設定してみましょう。以下のコマンドによって、それができます。
# parted /dev/sda print free
Model: ATA INTEL SSDSA2CW08 (scsi)
Disk /dev/sda: 80.0GB
Sector size (logical/physical): 512B/512B
Partition Table: gpt
Disk Flags:

Number Start End Size File system Name Flags
17.4kB 1049kB 1031kB Free Space
1 1049kB 19.9MB 18.9MB fat16 primary boot
2 19.9MB 65.3GB 65.3GB ext3 primary
3 65.3GB 76.0GB 10.7GB primary
4 76.0GB 80.0GB 4027MB linux-swap(v1) primary
80.0GB 80.0GB 73.2kB Free Space

# cryptsetup luksFormat /dev/sda3

WARNING!
========
This will overwrite data on /dev/sda3 irrevocably.

Are you sure? (Type uppercase yes): YES
Enter passphrase: 〔← 任意のパスフレーズを入力する〕
Verify passphrase: 〔← 上と同じパスフレーズを入力する〕

上の「cryptsetup luksFormat」コマンドに「-c」や「-s」オプションを付加すると、暗号化の方式や鍵のビット長などを変更することができます。luksFormatに適用されるこれらのデフォルト設定値は、cryptsetupコマンドのヘルプ情報の「Default compiled-in key and passphrase parameters: ... LUKS1: ...」という部分に表示されています。

上で作成したLUKS用パーティションをファイルシステムとしてフォーマットするには、以下のようなコマンドを使います。
# cryptsetup luksOpen /dev/sda3 luks
Enter passphrase for /dev/sda3: 〔← LUKSパーティション設定時のパスフレーズを入力する〕
# ls -l /dev/mapper
crw------- 1 root root 10, 236 Jan 2 16:14 control
brw------- 1 root root 253, 0 Jan 2 16:21 luks
# mkfs.ext3 /dev/mapper/luks
mke2fs 1.42.9 (28-Dec-2013)
Filesystem label=
OS type: Linux
Block size=4096 (log=2)
Fragment size=4096 (log=2)
Stride=0 blocks, Stripe width=0 blocks
654080 inodes, 2614784 blocks
130739 blocks (5.00%) reserved for the super user
First data block=0
Maximum filesystem blocks=2680160256
80 block groups
32768 blocks per group, 32768 fragments per group
8176 inodes per group
Superblock backups stored on blocks:
32768, 98304, 163840, 229376, 294912, 819200, 884736, 1605632

Allocating group tables: done
Writing inode tables: done
Creating journal (32768 blocks): done
Writing superblocks and filesystem accounting information: done

# mkdir /mnt/encrypted
# mount -t ext3 /dev/mapper/luks /mnt/encrypted

最初の「cryptsetup luksOpen」はLUKSパーティションをオープンするために必要なコマンドです。このコマンドを実行すると、/dev/mapperディレクトリの中にLUKSのデバイスファイルが作成されます。LUKSのデバイスファイルが作成されれば、それ以降は普通のパーティションと同様に、このデバイスファイルを使ってmkfs.*コマンドによってLUKSパーティション上にファイルシステムを作成したり、mountコマンドによってマウントすることができます。

そして、LUKSデバイスのマウント後は、ファイルの読み書きも普通にできます。
# cd /mnt/encrypted
# ls -l
drwx------ 2 root root 16384 Jan 2 16:22 lost+found
# echo hello > hello.txt
# ls -l
-rw-r--r-- 1 root root 6 Jan 2 16:23 hello.txt
drwx------ 2 root root 16384 Jan 2 16:22 lost+found
# cat hello.txt
hello

LUKSパーティションをアンマウントしたい場合は、以下の手順を実行します。
# cd
# umount /mnt/encrypted
# cryptsetup luksClose luks
# ls -l /dev/mapper
crw------- 1 root root 10, 236 Jan 2 16:14 control

cryptsetup luksClose 」はLUKSパーティションをクローズするために必要なコマンドです。このコマンドを実行すると、/dev/mapperディレクトリの下のLUKSデバイスファイルは削除されます。

■ LUKSパーティションの鍵操作


LUKSパーティションはヘッダ情報というものを持っています。LUKSパーティションのヘッダ情報は、下のコマンドによって確認できます。
# cryptsetup luksDump /dev/sda3
LUKS header information for /dev/sda3

Version: 1
Cipher name: aes
Cipher mode: xts-plain64
Hash spec: sha1
Payload offset: 4096
MK bits: 256
MK digest: 74 cf a9 e4 33 dd b0 f8 3e d7 4f 0f cd e8 44 e4 83 59 59 54
MK salt: d9 b5 02 90 27 4f 74 b0 f6 fa fd 83 d8 d0 98 dc
18 b0 18 bb af 81 62 90 df 20 ca cf d2 af 69 2e
MK iterations: 46250
UUID: 9d42429a-7ca0-4557-891e-9e3529fda5b8

Key Slot 0: ENABLED
Iterations: 186045
Salt: b8 b3 0a 73 ca 4e 81 39 fe 47 b1 20 ef 61 2b 17
a5 08 f4 5c 62 da 63 07 17 87 b6 53 ad 90 09 7b
Key material offset: 8
AF stripes: 4000
Key Slot 1: DISABLED
Key Slot 2: DISABLED
Key Slot 3: DISABLED
Key Slot 4: DISABLED
Key Slot 5: DISABLED
Key Slot 6: DISABLED
Key Slot 7: DISABLED

LUKSパーティションの設定時に入力したパスフレーズは、ヘッダ情報内のKey Slot 0に保存されています。

LUKSパーティションのパスフレーズは複数登録できます。新たに登録したパスフレーズは、ヘッダ情報内の最初の空きスロットへ保存されます。
# cryptsetup luksAddKey /dev/sda3
Enter any existing passphrase: 〔← 登録済みのいずれかのパスフレーズを入力する〕
Enter new passphrase for key slot: 〔← 新しいパスフレーズを入力する〕
# cryptsetup luksDump /dev/sda3
LUKS header information for /dev/sda3

Version: 1
Cipher name: aes
Cipher mode: xts-plain64
Hash spec: sha1
Payload offset: 4096
MK bits: 256
MK digest: 74 cf a9 e4 33 dd b0 f8 3e d7 4f 0f cd e8 44 e4 83 59 59 54
MK salt: d9 b5 02 90 27 4f 74 b0 f6 fa fd 83 d8 d0 98 dc
18 b0 18 bb af 81 62 90 df 20 ca cf d2 af 69 2e
MK iterations: 46250
UUID: 9d42429a-7ca0-4557-891e-9e3529fda5b8

Key Slot 0: ENABLED
Iterations: 186045
Salt: b8 b3 0a 73 ca 4e 81 39 fe 47 b1 20 ef 61 2b 17
a5 08 f4 5c 62 da 63 07 17 87 b6 53 ad 90 09 7b
Key material offset: 8
AF stripes: 4000
Key Slot 1: ENABLED
Iterations: 183118
Salt: 1e c2 93 20 66 5d eb 40 d6 00 db 7a 32 bb 61 56
71 10 1f e5 37 c3 ee 70 d9 26 8b 34 cf 93 fd 21
Key material offset: 264
AF stripes: 4000
Key Slot 2: DISABLED
Key Slot 3: DISABLED
Key Slot 4: DISABLED
Key Slot 5: DISABLED
Key Slot 6: DISABLED
Key Slot 7: DISABLED

設定済みのパスフレーズを削除することもできます。
# cryptsetup luksKillSlot /dev/sda3 1
Enter any remaining passphrase: 〔← 削除対象スロット以外のいずれかのパスフレーズを入力する〕
# cryptsetup luksDump /dev/sda3
LUKS header information for /dev/sda3

Version: 1
Cipher name: aes
Cipher mode: xts-plain64
Hash spec: sha1
Payload offset: 4096
MK bits: 256
MK digest: 74 cf a9 e4 33 dd b0 f8 3e d7 4f 0f cd e8 44 e4 83 59 59 54
MK salt: d9 b5 02 90 27 4f 74 b0 f6 fa fd 83 d8 d0 98 dc
18 b0 18 bb af 81 62 90 df 20 ca cf d2 af 69 2e
MK iterations: 46250
UUID: 9d42429a-7ca0-4557-891e-9e3529fda5b8

Key Slot 0: ENABLED
Iterations: 186045
Salt: b8 b3 0a 73 ca 4e 81 39 fe 47 b1 20 ef 61 2b 17
a5 08 f4 5c 62 da 63 07 17 87 b6 53 ad 90 09 7b
Key material offset: 8
AF stripes: 4000
Key Slot 1: DISABLED
Key Slot 2: DISABLED
Key Slot 3: DISABLED
Key Slot 4: DISABLED
Key Slot 5: DISABLED
Key Slot 6: DISABLED
Key Slot 7: DISABLED

また、キー・ファイルを作成して、それをLUKSパーティションのパスフレーズの代わりに登録することができます。
# dd if=/dev/urandom of=/etc/luks_key bs=1 count=1024
1024+0 records in
1024+0 records out
# cryptsetup luksAddKey /dev/sda3 /etc/luks_key
Enter any passphrase: 〔← 登録済みのいずれかのパスフレーズを入力する〕
# cryptsetup luksDump /dev/sda3
LUKS header information for /dev/sda3

Version: 1
Cipher name: aes
Cipher mode: xts-plain64
Hash spec: sha1
Payload offset: 4096
MK bits: 256
MK digest: 74 cf a9 e4 33 dd b0 f8 3e d7 4f 0f cd e8 44 e4 83 59 59 54
MK salt: d9 b5 02 90 27 4f 74 b0 f6 fa fd 83 d8 d0 98 dc
18 b0 18 bb af 81 62 90 df 20 ca cf d2 af 69 2e
MK iterations: 46250
UUID: 9d42429a-7ca0-4557-891e-9e3529fda5b8

Key Slot 0: ENABLED
Iterations: 186045
Salt: b8 b3 0a 73 ca 4e 81 39 fe 47 b1 20 ef 61 2b 17
a5 08 f4 5c 62 da 63 07 17 87 b6 53 ad 90 09 7b
Key material offset: 8
AF stripes: 4000
Key Slot 1: ENABLED
Iterations: 183118
Salt: a5 64 bf dd 2a 0d 09 b6 41 c2 42 1e 6c 1d 23 a2
c3 bd 47 e8 da fb fa b8 70 fb b0 70 87 bc d0 46
Key material offset: 264
AF stripes: 4000
Key Slot 2: DISABLED
Key Slot 3: DISABLED
Key Slot 4: DISABLED
Key Slot 5: DISABLED
Key Slot 6: DISABLED
Key Slot 7: DISABLED

キー・ファイルを登録した場合は、そのキー・ファイルを指定してLUKSパーティションをオープンできます。
# cryptsetup luksOpen /dev/sda3 luks --key-file=/etc/luks_key
# mount -t ext3 /dev/mapper/luks /mnt/encrypted
# ls -l /mnt/encrypted
-rw-r--r-- 1 root root 6 Jan 2 16:23 hello.txt
drwx------ 2 root root 16384 Jan 2 16:22 lost+found
# cat /mnt/encrypted/hello.txt
hello

この場合、パスフレーズの入力は求められません。キー・ファイルがパスフレーズとして扱われるからです。

■ LUKSファイルシステムの性能評価


実際にcryptsetupでLUKS暗号化ファイルシステムを使ってみた感想ですが、非常に良く出来ている優れ物のソフトウェアだと思います。ググってみると、cryptsetupとLUKSに関する多くの情報がヒットするので、これらはかなり広く使われているのでしょう。このように普及しているソフトウェアだと、どれ位の性能を持っているのかがすごく気になります。そこで、LUKSファイルシステムの読み書き速度の計測をやってみました。

LUKSファイルシステムの読み込み速度の計測は、次のコマンドを使って行いました。
# hdparm -t /dev/mapper/luks

書き込み速度の方は、次のコマンドを使って計測しました。
# sync;time bash -c "(dd if=/dev/zero of=/mnt/encrypted/bf bs=8k count=500000; sync)"

このコマンドの実行後に、 毎回Ctrl+c と 「rm /mnt/encrypted/bf」を実行しています。

LUKSファイルシステムの読み書き速度の計測結果は以下のようになりました。上記のコマンドによる計測をそれぞれ3回ずつ行って、もっとも良い値を採用しました。

ファイルシステム読み込み速度(MB/sec)比率書き込み速度(MB/sec)比率
素のext3263.3694.96
LUKS ext341.120.1542.400.44

比較のために、LUKSを設定せず通常のext3でフォーマットしたファイルシステムを使ったケースの計測値も示しています。

上表の2種類の計測値の差がちょっと大きすぎる気がします。Intel E38xxxにはAES-NIが搭載されているので、もっと高い性能が出るはずだと予測していました。ググってみると、AES-NIが有効なケースで、LUKSファイルシステムでも100〜200MB/sec程度の読み込み速度計測値が掲載されているページがいくつか見つかりました。もしかすると、cryptsetupの暗号処理でAES-NIが使われていないのかもしれません。本件については現在調査中です。

【2015/01/05 追記】

Yocto Linux(正確には、OpenEmbeddedリポジトリですが)のcryptsetupに関する重要なTips情報を書くのを忘れていました。

デフォルト状態のValley Island BSPを使ってビルドしたイメージにcryptsetupを組み込むと、「cryptsetup luksFormat <device>」コマンドの実行時に以下のようなエラーに遭遇します。
# cryptsetup luksFormat /dev/sda3

WARNING!
========
This will overwrite data on /dev/sda3 irrevocably.

Are you sure? (Type uppercase yes): YES
Enter passphrase:
Verify passphrase:
device-mapper: reload ioctl on failed: No such file or directory
Failed to open temporary keystore device.
device-mapper: remove ioctl on temporary-cryptsetup-664 failed: No such device or address
device-mapper: reload ioctl on temporary-cryptsetup-664 failed: No such device or address
device-mapper: remove ioctl on temporary-cryptsetup-664 failed: No such device or address
device-mapper: remove ioctl on temporary-cryptsetup-664 failed: No such device or address
device-mapper: remove ioctl on temporary-cryptsetup-664 failed: No such device or address
device-mapper: remove ioctl on temporary-cryptsetup-664 failed: No such device or address

このエラーを解決するには、カーネルの以下の2つのコンフィグレーション設定項目を有効にしてください。
CONFIG_CRYPTO_XTS

-*- Cryptographic API --->
*** Block modes ***
<M> XTS support

CONFIG_CRYPTO_USER_API_SKCIPHER

-*- Cryptographic API --->
*** Random Number Generation ***
<M> User-space interface for symmetric key cipher algorithms

どちらもカーネルがサポートしている暗号処理機能ですが、Valley Island BSPのカーネル設定ではいずれもデフォルト状態で無効になっています。

「cryptsetup benchmark」というコマンドを利用して、上記のカーネルのコンフィグレーション設定項目が有効になっているかどうかを確認することもできます。どちらの設定項目も有効な場合、本コマンドの実行結果は以下のようになります。
# cryptsetup benchmark
# Tests are approximate using memory only (no storage IO).
PBKDF2-sha1 377729 iterations per second
PBKDF2-sha256 236165 iterations per second
PBKDF2-sha512 186712 iterations per second
PBKDF2-ripemd160 298229 iterations per second
PBKDF2-whirlpool 109044 iterations per second
# Algorithm | Key | Encryption | Decryption
aes-cbc 128b 48.0 MiB/s 57.4 MiB/s
serpent-cbc 128b 23.3 MiB/s 24.7 MiB/s
twofish-cbc 128b 45.1 MiB/s 53.9 MiB/s
aes-cbc 256b 38.6 MiB/s 43.8 MiB/s
serpent-cbc 256b 23.3 MiB/s 24.8 MiB/s
twofish-cbc 256b 45.1 MiB/s 53.9 MiB/s
aes-xts 256b 57.6 MiB/s 58.5 MiB/s
serpent-xts 256b 25.3 MiB/s 25.0 MiB/s
twofish-xts 256b 53.4 MiB/s 54.8 MiB/s
aes-xts 512b 44.4 MiB/s 44.4 MiB/s
serpent-xts 512b 25.3 MiB/s 25.0 MiB/s
twofish-xts 512b 53.4 MiB/s 54.8 MiB/s

上記の両方の設定項目が無効な場合、「cryptsetup benchmark」コマンドの実行結果は以下のようになります。
# cryptsetup benchmark
# Tests are approximate using memory only (no storage IO).
PBKDF2-sha1 378274 iterations per second
PBKDF2-sha256 236592 iterations per second
PBKDF2-sha512 185129 iterations per second
PBKDF2-ripemd160 297215 iterations per second
PBKDF2-whirlpool 109226 iterations per second
Required kernel crypto interface not available.
Ensure you have algif_skcipher kernel module loaded.

CONFIG_CRYPTO_USER_API_SKCIPHERがcryptsetupの*-cbcで、CONFIG_CRYPTO_XTSの方が*-xtsで使われる暗号処理機能です。cryptsetupのluksFormatに適用されるデフォルトの暗号パラメータは「aes-xts-plain64, Key: 256 bits」になっています。本エラーが発生する原因は、CONFIG_CRYPTO_XTSによって有効になる暗号処理機能がカーネル側に存在していないからです。

本エラーを解決するにあたって、共通鍵暗号処理について少し調べてみました(数学知識を持たない素人の理解なので、以降の内容が正確どうかは保証しません)。共通鍵暗号処理というのは、暗号化アルゴリズムとブロック操作モードの2つの大きな構成要素によって成り立っているらしいです。上記の件に関連して言うと、AESが暗号化アルゴリズムに、CBC(Cipher-block chaining)やXTS(XEX-based tweaked-codebook mode with ciphertext stealing)がブロック操作モードに相当します(ブロック操作モードはこの2つ以外にもいくつか種類が存在します)。以下のWikipediaページに共通鍵暗号処理のブロック操作モードに関する説明が掲載されているので、詳細が知りたければこれらのページの情報を参照してください。

 Block cipher mode of operation - Wikipedia, the free encyclopedia
 Disk encryption theory - Wikipedia, the free encyclopedia

暗号化ディスクボリュームにおいて使われる共通鍵暗号処理のブロック操作モードを比較すると、CBCよりXTSの方が圧倒的に強度が高いそうです。cryptsetupのluksFormatのデフォルト暗号化パラメータが「aes-xts-plain64, Key: 256 bits」になっているのは、この理由によるのだと思われます。

【参考ページ】

 LUKS(Linux Unified Key Setup)を使ってみる - think-t の晴耕雨読
 (Linux)LUKSでファイルシステムを暗号化してみた : 3流プログラマのメモ書き
 lost and found ( for me ? ): cryptsetup で暗号化ファイルシステムの作成
 dm-crypt/Device encryption - ArchWiki
 hdparm (日本語) - ArchWiki
posted by とみやん at 16:01| Comment(0) | TrackBack(0) | Embedded Linux > Yocto Project

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

2014年11月28日

[Yocto] DE3815TYKHEへのWi-Fi端末機能追加

最近組込み分野におけるYocto Projectの存在感は益々大きくなってきています。IntelはYocto Projectを積極的に後押しており、かなり大きな開発リソースを投入しています。また、Intelは組込み向けの新しいプロセッサや評価ボードなどを次々と発表していますが、組込みOSとしてYocto ProjectとAndroidを強力にプッシュしています。Wind Riverなどの組込みLinuxのベンダー企業もYocto Projectに積極的に開発リソースを投入しているようです。ここに来て、Yocto Projectを取り巻く動きはさらに活発になっています。

前記事では、DE3815TYKHEの内蔵EthernetコントローラであるRealtek RTL8111のドライバをYocto Linuxへ追加する方法について書きました。Valley Island(Intel E38xx)用BSPをカスタマイズすることで目的を達成しましたが、新しいターゲット・ハードウェアへYocto Linuxを移植する場合、既存のBSPを改造することが手っ取り早い方法です。Yocto Linuxに取り組むプログラマが増えているようなので、BSPのカスタマイズ方法に関する導入ガイド的な情報として、前記事は役に立つ内容になっているのではないかと自負しています。本業の仕事でもYocto Linuxの研究開発に携わっていますが、休日などのプライベートな時間もYocto Linuxの研究に相当な時間を割いています。仕事上必要に迫られてYocto Projectについてググって調べることが多いですが、日本語の情報はまだまだ少ないのが実情です。オープンソース・コミュニティへの貢献にもなるので、プライベートな研究活動で得られた成果や情報を積極的に公開していこうと思っています(本業の仕事があまりに忙しすぎて、記事を書く時間がなかなか取れないのが悩みですが・・・)。

さて、10/13の記事でDE3815TYKHEへSO-DIMMメモリとSSDを組み込む作業について書きましたが、DE3815TYKHEにはMini-PCIeスロットと無線LAN用のアンテナ・ケーブルが内蔵されていました。せっかくスロットが内蔵されているのに使わないのはもったいないので、DE3815TYKHEへ無線LANカードを追加してみました。同時にYocto LinuxへWi-Fi端末機能を追加する作業も行ったので、その作業の詳細についても書きます。

■ DE3815TYKHEへの無線LANカードの組込み


今回入手したのはRalink RT3090というチップを搭載した無線LANカードです。このチップはIEEE802.11b/g/nの無線通信規格に対応しています。
ANIMG_20141127_084730-DE3815TYKHE-Embedding_WLAN-Ralink_RT3090.jpg
ANIMG_20141127_085658-DE3815TYKHE-Embedding_WLAN-Ralink_RT3090.jpg
まずは、DE3815TYKHEへの無線カードの組み込みから始めました。組み込み作業は簡単でした。内蔵のMini-PCIeスロットにカードを挿して、カード上の2つのコネクタにアンテナ・ケーブルを取り付けるだけです。
ANIMG_20141129_155541-DE3815TYKHE_Embedding_WLAN-Ralink_RT3090.jpg
なお、上の写真のとおり、本無線カードは技術基準適合証明(いわゆる「技適マーク」)を取得済みの物なので、屋外や正式な稼働現場でも無線機能内蔵機器として使うことができますが、技適マークの付いていない無線カードを組み込んだ機器を屋外や正式な稼働現場などで使用することは違法です(屋内限定の実験レベルでの使用なら電波法に抵触しないという解釈もあるようですが、この辺は曖昧みいたいです)。無線カードを機器に組み込んで使う場合は、この点に注意しなければなりません。

■ DE3815TYKHE BSPへのWi-Fi設定追加


無線カードの組み込み作業が済んだので、さっそくDE3815TYKHEでYocto Linuxを起動してみました。そして、PCI/PCIeボードを追加したときの定番コマンドであるlspciコマンドを最初に実行してみました。無線LANカードを挿した状態でのlspciコマンドの出力情報は下のようになりました。
# lspci
00:00.0 Host bridge: Intel Corporation ValleyView SSA-CUnit (rev 0c)
00:02.0 VGA compatible controller: Intel Corporation ValleyView Gen7 (rev 0c)
00:13.0 SATA controller: Intel Corporation ValleyView 6-Port SATA AHCI Controller (rev 0c)
00:14.0 USB controller: Intel Corporation ValleyView USB xHCI Host Controller (rev 0c)
00:1a.0 Encryption controller: Intel Corporation ValleyView SEC (rev 0c)
00:1b.0 Audio device: Intel Corporation ValleyView High Definition Audio Controller (rev 0c)
00:1c.0 PCI bridge: Intel Corporation ValleyView PCI Express Root Port (rev 0c)
00:1c.1 PCI bridge: Intel Corporation ValleyView PCI Express Root Port (rev 0c)
00:1c.2 PCI bridge: Intel Corporation ValleyView PCI Express Root Port (rev 0c)
00:1f.0 ISA bridge: Intel Corporation ValleyView Power Control Unit (rev 0c)
00:1f.3 SMBus: Intel Corporation ValleyView SMBus Controller (rev 0c)
02:00.0 Network controller: Ralink corp. RT3090 Wireless 802.11n 1T/1R PCIe
03:00.0 Ethernet controller: Realtek Semiconductor Co., Ltd. RTL8111/8168/8411 PCI Express Gigabit Ethernet Controller (rev 0c)

PCIバス・レベルでカードは認識されていますが、ifconfigコマンドで情報を取得しても、無線LANのインスターフェースは存在していませんでした。カーネルにRalink RT3090用のドライバを組み込んでいないので当然です。dmesgコマンドの情報でも、それらしいドライバはロードされていませんでした。それでは、Yocto Linuxに無線LANドライバを組み込むにはどうすれば良いのでしょうか。

本件に関する情報が欲しくて、Yocto Projectの公式サイトのページを探し回ったり同プロジェクトのGitリポジトリに存在するレシピなどを片っ端から読んだりしました。結論を先に書くと、前記事で作成したDE3815TYKHE用BSPに以下のような変更を加えると、Yocto LinuxへWi-Fi機能を組み込むことができます(ターゲット名を「de3815tyke」から「de3815tybe」に変更しました。その関係で、前記事からファイル名を変更しています。ちなみに、「DE3815TYBE」はDE3815TYKHEに搭載されているボードの型番です。Intelは本ボードを単独でも販売しています)。
#@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 \
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"

module_autoload_i2c-dev = "i2c-dev"

Yocto LinuxへWi-Fi(無線LAN)端末機能を追加するために必要な変更はたったこれだけです。linux-yocto_3.10.bbappendに加えた変更によって、カーネルのソースツリーに存在する主要な無線LANドライバがすべて組み込まれます。一方、de3815tybe-32.confde3815tybe-64.confの変更内容は、ターゲットイメージへWi-Fi関連パッケージを追加する役割を持っています。後者の変更によって、以下のパッケージがターゲットイメージへ組み込まれます。
  • linux-firmware-*
  • wireless-tools
  • wpa-supplicant
  • connman-gnome

「linux-firmware-」という名前で始まるパッケージには無線LANチップのファームウェアがバイナリ形式で格納されており、チップの種類分数が存在します。無線LANチップのファームウェアはデバイス・メーカーから配布されており、git.kernel.orgに収集されています(ファームウェアを公開していないメーカーも存在します。その場合は、有志の独自調査によりファームウェアを作成しているようです)。このサイトからダウンロードしたファームウェアから各無線LANチップ用のlinux-firmwareパッケージが生成されます。無線LANドライバがチップの初期化時にファームウェアをカードへロードする仕組みになっており、対象チップに適合したファームウェアが存在しないと、無線LANカードは正常に動作しません。上の「MACHINE_EXTRA_RRECOMMENDS += "linux-firmware"」という設定によって、主要な無線LANチップ用のlinux-firmwareパッケージがすべてターゲットイメージへ組み込まれます。

■ connman-gnomeによるWi-Fi接続


DE3815TYKHE BSPに上の変更を加えた後、以下のコマンドによってカーネルとターゲットイメージの再ビルドを行えば、Yocto LinuxへWi-Fi端末機能が追加されます。
$ bitbake linux-yocto -c cleansstate
$ bitbake linux-yocto
$ bitbake core-image-sato

上記の変更を加えたBSPから再ビルドしたYocto LinuxをDE3815TYKHEで起動すると、dmesgコマンドの出力情報に下のような行が追加されます。
# dmesg
.... ....
.... ....
.... ....
.... ....
[ 1.746796] cfg80211: Calling CRDA to update world regulatory domain
.... ....
[ 1.909116] rt2800pci 0000:02:00.0: enabling device (0000 -> 0002)
[ 1.915002] ieee80211 phy0: rt2x00_set_rt: Info - RT chipset 3090, rev 3213 detected
[ 1.966563] ieee80211 phy0: rt2x00_set_rf: Info - RF chipset 0005 detected
[ 2.201021] ieee80211 phy0: Selected rate control algorithm 'minstrel_ht'
.... ....

これでRalink RT3090用のドライバはロードされチップの初期化は行われていますが、この段階でifconfigコマンドを実行しても、無線LANのインターフェースは存在していません。その理由は、Yocto Linuxのネットワーク・インターフェースはconnman(Connection Manager)というソフトウェアによって管理されているからです。connmanによっていずれかのWi-Fiアクセスポイントに接続した段階で、初めて無線LANのインターフェースが作成されます。

core-image-sato(Sato Mobile Desktop)イメージでYocto Linuxを起動している場合、具体的には、以下のような操作を行う必要があります。
  1. Sato Mobile Desktop画面の右上に存在するLANケーブルのアイコンをクリックすると、下のようなメニューが表示されます。
    UBShot_20141202_154430-DE3815TYKHE-connman-gnome-WiFi_Setup-1024x768
    このメニューから[Preferences]メニューを選択します。

  2. すると、下のようなウィンドウが開きます。これがGUI版Connection Manager(connman-gnome)の画面です。
    UBShot_20141202_154506-DE3815TYKHE-connman-gnome-WiFi_Setup-1024x768
    上は、左側のServicesリストから[Wireless Networks]を選択したときのウィンドウ表示です。

    このウィンドウの[Enable]ボタンを押すと、無線LANインターフェースが有効になります。同時にWi-Fiアクセスポイントの検索処理が行われ、数秒後にServicesリスト内の[Wireless Networks]の下に見つかったアクセスポイントのSSIDの一覧が表示されます。
    UBShot_20141202_154705-DE3815TYKHE-connman-gnome-WiFi_Setup-1024x768
    なお、無線LANインターフェースが有効な状態で[Scan]ボタンを押すと、アクセスポイントの再検索を行うことができます。

  3. SSIDのリストから、接続したいアクセスポイントを選択してください。すると、下のようなウィンドウ表示に変わります。
    UBShot_20141202_154725-DE3815TYKHE-connman-gnome-WiFi_Setup-1024x768
    このウィンドウの[Connect]ボタンを押すと、下のようなポップアップ・ウィンドウが表示されます。
    UBShot_20141202_154918-DE3815TYKHE-connman-gnome-WiFi_Setup-1024x768
    このウィンドウの[Passphrase]エディットボックスに、接続しようとしているアクセスポイントのパスフレーズ(共有キー)を入力して、[OK]ボタンを押してください。

  4. アクセスポイントへの接続処理が実行され、上で入力したパスフレーズが正しければ、Servicesリストの対象SSIDの下に「connected」という表示が追加されます(接続処理の進行によって、この表示は「associating...」→「configuring...」→「connected」と変化します)。
    UBShot_20141202_155059-DE3815TYKHE-connman-gnome-WiFi_Setup-1024x768
    上のような状態になれば、アクセスポイントへの接続は完了しています。

上の操作を行った後、ターミナルからifconfigコマンドを実行すると、wlan0というインターフェースが作成されているはずです。これが無線LANのネットワーク・インターフェースです。
# ifconfig
eth0 Link encap:Ethernet HWaddr XX:XX:XX:XX:XX:XX
inet addr:192.168.223.9 Bcast:192.168.223.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:1220 errors:0 dropped:0 overruns:0 frame:0
TX packets:616 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:92049 (89.8 KiB) TX bytes:492673 (481.1 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:12 errors:0 dropped:0 overruns:0 frame:0
TX packets:12 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:660 (660.0 B) TX bytes:660 (660.0 B)

wlan0 Link encap:Ethernet HWaddr XX:XX:XX:XX:XX:XX
inet addr:192.168.179.6 Bcast:192.168.179.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:39 errors:0 dropped:0 overruns:0 frame:0
TX packets:59 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:2005 (1.9 KiB) TX bytes:9075 (8.8 KiB)


また、connmanによる無線LANインターフェースの有効化とアクセスポイントへの接続操作を行うと、下のようなカーネルログも出力されます。
# dmesg
.... ....
.... ....
[ 35.727187] ieee80211 phy0: rt2x00lib_request_firmware: Info - Loading firmware file 'rt2860.bin' 'rt2860.bin'
[ 35.732481] ieee80211 phy0: rt2x00lib_request_firmware: Info - Firmware detected - version: 0.34
[ 35.778497] IPv6: ADDRCONF(NETDEV_UP): wlan0: link is not ready
[ 66.643277] wlan0: authenticate with xx:xx:xx:xx:xx:xx
[ 66.652945] wlan0: send auth to xx:xx:xx:xx:xx:xx (try 1/3)
[ 66.654514] wlan0: authenticated
[ 66.655252] wlan0: associate with xx:xx:xx:xx:xx:xx (try 1/3)
[ 66.662697] wlan0: RX AssocResp from xx:xx:xx:xx:xx:xx (capab=0x431 status=0 aid=1)
[ 66.662811] wlan0: associated
[ 66.662860] IPv6: ADDRCONF(NETDEV_CHANGE): wlan0: link becomes ready

connmanで接続したアクセスポイントを経由してインターネットにアクセスできるかどうか試すには、ターミナルから下のようなpingコマンドを実行してみると良いでしょう。
# ping www.yoctoproject.org
PING www.yoctoproject.org (140.211.169.56): 56 data bytes
64 bytes from 140.211.169.56: seq=0 ttl=48 time=156.630 ms
64 bytes from 140.211.169.56: seq=1 ttl=48 time=156.535 ms
64 bytes from 140.211.169.56: seq=2 ttl=48 time=156.484 ms
64 bytes from 140.211.169.56: seq=3 ttl=48 time=156.374 ms
64 bytes from 140.211.169.56: seq=4 ttl=48 time=156.321 ms
64 bytes from 140.211.169.56: seq=5 ttl=48 time=156.516 ms

ただし、Ethernet側のLANケーブルを外した状態で行うべきです。Ethernet側の有線LAN回線経由ではなく、無線LAN回線経由でのインターネット接続を確認することが目的だからです。Webブラウザが在ればもっと簡単に確認できるのですが、残念ながら、デフォルトの状態ではcore-image-satoイメージにWebブラウザは組み込まれていません。

connman-gnomeによって接続したWi-Fiアクセスポイントの情報は保存されています。そのため、システムを再起動しても、自動的に前回接続していたアクセスポイントへ接続され、wlan0インターフェースが作成されます。

■ connman-clientによるCLI環境へのWi-Fi機能追加


これでYocto LinuxへのWi-Fi端末機能の組み込み作業は一応終わりですが、もう一つ補足的な情報を掲載しておきます。GUIではなくCLI環境にWi-Fi端末機能を追加する方法についてです。これまで、ずっとcore-image-sato(Sato Mobile Desktop)というGUI環境のイメージをビルドしてきましたが、Yocto LinuxにはCLI環境用のイメージレシピもいくつか収納されています。その中から、core-image-full-cmdlineというイメージにWi-Fi端末機能を組み込んでみたので、その作業の内容も紹介しておきましょう。モニタやタッチスクリーンの存在しないCLIベースのターゲット用にYocto LinuxでWi-Fi端末システムを構築するケースを想定しています。

CLI環境用イメージにWi-Fi機能を組み込む場合、BSPの内容は特に変わりはありません。上記のBSPをそのまま使うことができます。Wi-Fi関連パッケージもconnman-gnome以外はそのまま使えます。connman-gnomeだけはGUI環境用のパッケージなので使えません。connman-gnomeに代わって、connman-clientというパッケージを追加する必要があります。これはコマンドラインで動作するconnmanの接続設定アプリです。

Yocto Linuxのシステム構成イメージにパッケージを追加する方法はいくつか存在します。この辺の詳しい情報は別の記事で解説したいと思っていますが、今回は手っ取り早くlocal.confに設定記述を追加することで実現してみました。具体的には、以下のようにlocal.confを変更しました。
#
# Additional packages to be installed to the specific images
#
IMAGE_INSTALL_append_pn-core-image-full-cmdline = " \
kernel-modules \
wireless-tools \
wpa-supplicant \
connman \
connman-client"

#
# Extra image configuration defaults
#
# The EXTRA_IMAGE_FEATURES variable allows extra packages to be added to the generated
# images. Some of these options are added to certain image types automatically. The
# variable can contain the following options:
# "dbg-pkgs" - add -dbg packages for all installed packages
# (adds symbol information for debugging/profiling)
# "dev-pkgs" - add -dev packages for all installed packages
# (useful if you want to develop against libs in the image)
# "ptest-pkgs" - add -ptest packages for all ptest-enabled packages
# (useful if you want to run the package test suites)
# "tools-sdk" - add development tools (gcc, make, pkgconfig etc.)
# "tools-debug" - add debugging tools (gdb, strace)
# "eclipse-debug" - add Eclipse remote debugging support
# "tools-profile" - add profiling tools (oprofile, exmap, lttng, valgrind)
# "tools-testapps" - add useful testing tools (ts_print, aplay, arecord etc.)
# "debug-tweaks" - make an image suitable for development
# e.g. ssh root access has a blank password
# There are other application targets that can be used here too, see
# meta/classes/image.bbclass and meta/classes/core-image.bbclass for more details.
# We default to enabling the debugging tweaks.
EXTRA_IMAGE_FEATURES = "debug-tweaks package-management"

IMAGE_INSTALL_append」という変数を使うと、すべてのイメージが対象になりますが、上のように「IMAGE_INSTALL_append_pn-<IMAGE_NAME>」という変数名にすると、指定したイメージに対してのみパッケージを追加することができます。また、core-image-full-cmdlineイメージにはrpmコマンドが入っていないので、これを組み込むために「EXTRA_IMAGE_FEATURES」の設定も変更しました。rpmコマンドを使えると、後からターゲット環境へパッケージをインストールすることができます。システム構成を調べる際にも役立つので、ターゲットイメージには必ずrpmやopkgなどのパッケージ管理コマンを入れておくことをお勧めします。

core-image-full-cmdlineイメージのビルド手順はcore-image-satoと同じです。以下のコマンドによって、ビルドできます。
$ bitbake core-image-full-cmdline -c fetchall
$ bitbake core-image-full-cmdline

起動&インストール用USBメディアの作成方法も同じです。USBメモリを開発マシンへ挿した状態で、以下のコマンドを実行すれば、同メディアを作成できます。
$ umount /dev/sdc
$ sudo dd if=tmp/deploy/images/de3815tybe-64/core-image-full-cmdline-de3815tybe-64.hddimg of=/dev/sdc
$ sync

上で作成したUSBメディアを使って、DE3815TYKHEの内蔵SSDへYocto Linuxをインストールしました。その上で、内蔵SSDからYocto Linuxを再起動しました。core-image-full-cmdlineイメージでは、Yocto Projectのスプラッシュ画面に続いて、ログインプロンプトがモニタ画面に表示されます。

ログインした後ifconfigコマンドを実行すると、やはり無線LANのwlan0インターフェースは作成されていません。これはcore-image-satoと同じです。ここで、無線LANインターフェースの有効化とWi-Fiアクセスポイントへの接続操作を行います。CLI環境でこれらを行うには、「connmanctl」というコマンドを使います。具体的には、以下のような手順を実行します。
# connmanctl
connmanctl> enable wifi
Enabled wifi
connmanctl> scan wifi
Scan completed for wifi
connmanctl> agent on
Agent registered
connmanctl> services
AirPort15044 wifi_xxxxxxxxxxxx_416972506f72743135303434_managed_psk
Guest15044 wifi_xxxxxxxxxxxx_47756573743135303434_managed_psk
nad11-2e8ac2 wifi_xxxxxxxxxxxx_6e616431312d326538616332_managed_psk
ZL wifi_xxxxxxxxxxxx_5a4c_managed_psk
106F3F655F8A3 wifi_xxxxxxxxxxxx_313036463346363546384133_managed_psk
106F3F655F8A3-1 wifi_xxxxxxxxxxxx_3130364633463635463841332d31_managed_psk
TP-LINK_648426 wifi_xxxxxxxxxxxx_54502d4c494e4b5f363438343236_managed_psk
001D738E88FB-3 wifi_xxxxxxxxxxxx_3030314437333845383846422d33_managed_psk
001D738E88FB wifi_xxxxxxxxxxxx_303031443733384538384642_managed_psk
001D738E88FB-3 wifi_xxxxxxxxxxxx_3030314437333845383846422d31_managed_psk
0000docomo wifi_xxxxxxxxxxxx_30303030646f636f6d6f_managed_psk
connmanctl> connect wifi_xxxxxxxxxxxx_6e616431312d326538616332_managed_psk
Agent RequestInput wifi_xxxxxxxxxxxx_6e616431312d326538616332_managed_psk
Passphrase = [ Type=psk, Requirement=mandatory, Alternates=[ WPS ] ]
WPS = [ Type=wpspin, Requirement=alternate ]
Passphrase? ************〔← 接続対象アクセスポイントのパスフレーズ(共有キー)を入力する〕
Connected wifi_xxxxxxxxxxxx_6e616431312d326538616332_managed_psk
connmanctl> quit

上の操作を行った後ifconfigコマンドを実行すれば、無線LANのwlan0インターフェースが作成されていることが確認できます。Wi-Fiアクセスポイントへの接続が完了すれば、無線LANのネットワーク環境はSato Mobile Desktopと変わりありません。インターネットへのアクセスも問題なくできます。

【参考ページ】

 connman: wifi configuration ・ IntelOpenDesign/MakerNode Wiki ・ GitHub
 WiFi access on Intel(TM) Galileo with Yocto* Linux
 インテル Galileo 開発ボードでWi-Fi/BTを適法に使用する方法の実践 | KEI SAKAKI's PAGE.
 Connman - ArchWiki


posted by とみやん at 16:29| Comment(0) | TrackBack(0) | Embedded Linux > Yocto Project

2014年10月25日

[Yocto] BSPカスタマイズによるDE3815TYKHEのEthernet対応追加

前記事に書いたとおり、Shuttle XS36V4でYocto Linuxを動かすことはトラブルに遭遇することもなくすんなりと成功してしまいました。Valley Island BSPに収納されているバイナリ・イメージと自分でビルドしたDE3815TYKHE用のイメージの2つを使いましたが、どちらでも特に問題なくXS36V4でYocto Linuxは動作しました。Valley Island BSPはデフォルト状態でRTL8168/8169/8111/8411ドライバが有効になっていたので、ドライバを組み込むことなくEthernetインターフェースも使えました。ただし、一つ大きな課題を見つけてしまいました。それは、Yocto LinuxがXS36V4の無線LANデバイスを認識していないことです。

前記事で使ったDE3815TYKHE用のcore-image-satoイメージは、カーネルレシピに主要な無線LANドライバをすべて組み込んた状態でビルドしたものです。〔2014/12/29の記事linux-yocto_3.10.bbappendを参照〕lspciコマンドの出力情報によって、XS36V4に搭載されている無線LANデバイスはRealtek RTL8188EEという物であることが判りました。しかし、dmesgコマンドのカーネル・ログを確認しても、RTL8188EE用ドライバはロードされていませんでした。Sato Mobile DesktopのGUI画面からconnman-gnomeを起動してみましが、下のとおり、やはりServiesリストに[Wireless Networks]というカテゴリ・エントリは存在していません。
UBShot_20150113_103340-YoctoLinux-Enabling_RTL8188EE_WLAN_Driver-1366x768
どうやらRTL8188EE用の無線LANドライバがカーネルへ組み込まれていないようです。

ググって調べてみると、カーネルソース・ツリーにRTL8188EE用ドライバは存在しており、これを有効にするにはCONFIG_RTL8188EEというコンフィグレーション設定項目を有効する必要があることが判りました。現状のカーネルのコンフィグレーション設定を確認すると、やはりこの項目は有効になっていませんでした。
# zcat /proc/config.gz | grep CONFIG_RTL8188EE
# CONFIG_RTL8188EE is not set

上記の情報に基いて、XS36V4のWi-Fi機能を利用可能にする作業を行ったので、その作業記録を本記事に書きます。

■ RTL8188EE無線LANドライバの組み込み


まずは、一時的にコンフィグレーション設定を変更して、カーネルへRTL8188EEドライバを組み込む作業を行いました。

bitbake linux-yocto -c menuconfig」コマンドによってカーネルのコンフィグレーション・メニュー画面を開いて、以下のメニュー項目を有効にすれば、RTL8188EEドライバを組み込むことができます。〔2014/10/25の記事を参照〕
UBShot_20150113_115841-YoctoLinux-Enabling_RTL8188EE_WLAN_Driver-704x766
         Device Drivers  --->

[*] Nework device support --->

[*] Wireless LAN --->

<M> Realtek RTL8188EE Wireless Network Adapter

上の操作を行った後、以下のコマンドを実行して、RTL8188EEドライバを組み込んだcore-image-satoイメージを作成しました。
% bitbake linux-yocto -c compile -f
% bitbake linux-yocto -c deploy
% bitbake linux-yocto
% bitbake core-image-sato

core-image-satoのhddimgファイルからLive USBを作成して、このUSBメディアを使って、XS36V4でYocto Linuxを起動しました。そして、CONFIG_RTL8188EEが有効になっていることを確認しました。
# zcat /proc/config.gz | grep CONFIG_RTL8188EE
CONFIG_RTL8188EE=m

続いて、dmesgコマンドによってRTL8188EEドライバがロードされているかを確認しました。
# dmesg
.... ....
.... ....
.... ....
.... ....
[ 6.241182] cfg80211: Calling CRDA to update world regulatory domain
[ 6.375266] rtl8188ee 0000:01:00.0: enabling device (0000 -> 0003)
[ 6.383289] rtl8188ee: Using firmware rtlwifi/rtl8188efw.bin
[ 6.397905] ieee80211 phy0: Selected rate control algorithm 'rtl_rc'
[ 6.398161] rtlwifi: wireless switch is on
.... ....

connman-gnomeを起動してみると、Serviesリストにちゃんと[Wireless Networks]のエントリが追加されていました。
UBShot_20150113_123138-YoctoLinux-Enabling_RTL8188EE_WLAN_Driver-1366x768
Wi-Fiアクセスポイントへの接続を試してみると、こちらも問題なくできました。
UBShot_20150113_123405-YoctoLinux-Enabling_RTL8188EE_WLAN_Driver-1366x768

■ XS36V4用BSPの作成


上記のとおり、一時的にカーネルのコンフィグレーション設定を変更してRTL8188EEドライバを組み込めば、Yocto LinuxでXS36V4のWi-Fi機能を使えるようになることを確認できました。そこで、XS36V4用のBSPを作成して、この成果をそれに反映しました。

2014/10/25の記事にDE3815TYKHE用BSPの作成方法を書きましたが、これと同じ方法でXS36V4用のBSPを作成しました。今回作成したXS36V4 BSPのファイル構成を以下に示します。

  meta-xs36v4
|-- conf
| |-- machine
| | `-- xs36v4.conf
| `-- layer.conf
|-- recipes-bsp
| `-- formfactor
| |-- formfactor
| | `-- xs36v4
| | `-- machconfig
| `-- formfactor_0.0.bbappend
`-- recipes-kernel
`-- linux
`-- linux-yocto_3.10.bbappend

また、以下にXS36V4 BSPのレイヤ定義ファイル、ターゲット定義ファイル、カーネルレシピの内容を示します。
#We have a conf and classes directory, add to BBPATH
BBPATH .= ":${LAYERDIR}"

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

BBFILE_COLLECTIONS += "xs36v4"
BBFILE_PATTERN_xs36v4 := "^${LAYERDIR}/"
BBFILE_PRIORITY_xs36v4 = "6"

LAYERDEPENDS_xs36v4 = "intel"

LICENSE_PATH += "${LAYERDIR}/custom-licenses"

#@TYPE: Machine
#@NAME: Shuttle XS36V4

#@WEBTITLE: Intel Celeron J1900 Processor (XS36V4) 64-bit with Open Source Frame Buffer Graphics

#@DESCRIPTION: Machine configuration for XS36V4 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 = xs36v4 #
#############################
COMPATIBLE_MACHINE_xs36v4 = "xs36v4"
KMACHINE_xs36v4 = "valleyisland"
KBRANCH_xs36v4 = "standard/base"
KERNEL_FEATURES_xs36v4 = " features/valleyisland-io/valleyisland-io.scc \
features/valleyisland-io/valleyisland-io-pci.scc \
features/wifi/wifi-all.scc"

LINUX_VERSION_xs36v4 = "3.10.59"
SRCREV_machine_xs36v4 = "747e1cbd12b15db8bc2ae86e2359c1b113f120d6"
SRCREV_meta_xs36v4 = "8f05306a8e6f5ee422d50c3317acce0cf9e6aada"
SRCREV_valleyisland-io_xs36v4 = "0992d01f5f382f6da60004ef87f67ebd3ca13732"

SRC_URI_xs36v4 = "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"

SRC_URI_xs36v4 += "file://add_driver-net_wlan_rtl8188ee.cfg"

module_autoload_i2c-dev = "i2c-dev"

上のファイルで定義しているのは64ビット版ターゲットだけです。今回32ビット版ターゲットの定義は省略しました。XS36V4で32ビット版Yocto Linuxを動かすことはまずないだろうと思ったからです。DE3815TYKHEでも、32ビット版ターゲット用にYocto Linuxをビルドしたことはいままで一度もありません。

上のカーネルレシピで使っているコンフィグレーションフラグメントは以下のような内容です。
++ .config	2015-01-12 15:55:39.777257022 +0900
CONFIG_RTL8188EE=m

このファイルは、カーネルのコンフィグレーション・メニュー画面でCONFIG_RTL8188EEの設定項目を有効にした直後に「bitbake linux-yocto -c diffconfig」コマンドを実行することで作成しました。

上記のXS36V4用BSPを作成した後、このBSPを使ってcore-image-satoイメージをビルドし、XS36V4でYocto Linuxが起動することを確認しました。Wi-Fi機能も問題なく動作しています。

なお、Shuttle XS36V4にはXS35V4という姉妹モデルが存在しますが、この2つの機種のハード仕様は同一だと思われます。未確認ですが、今回作成したBSPはXS35V4でも使えるはずです。〔本記事に掲載したXS36V4 BSPを利用してXS35V4で動作確認を行った方がいれば、その結果をコメントで報告していただけると有難いです〕

ページ前記事で紹介したとおり、Intel DE3815TYKHEというE3815搭載ベアボーンPCでYocto Linuxを動かしましたが、この作業はすんなりと終わりました。しかし、Yocto Linuxを動かすことには成功しましたが、一つ課題が見つかりました。それは、Yocto LinuxがDE3815TYKHE内蔵のEthernetデバイスを認識していないことです。

DE3815TYKHEでYocto Linuxを起動した後に、ターミナルからifconfigコマンドを実行すると、下のような出力が表示されました。
# ifconfig
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:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)


Ethernetデバイスが認識されていれば「eth0」というネットワーク・インターフェースが表示されるはずですが、それが存在していません。

DE3815TYKHEのハードウェア仕様について調べてみると、こいつに搭載されているEthernetデバイスはどうもRealtekのRTL8111Gのようです。 lspciコマンドによる情報でもそれが判ります。
# lspci
00:00.0 Host bridge: Intel Corporation ValleyView SSA-CUnit (rev 0c)
00:02.0 VGA compatible controller: Intel Corporation ValleyView Gen7 (rev 0c)
00:13.0 SATA controller: Intel Corporation ValleyView 6-Port SATA AHCI Controller (rev 0c)
00:14.0 USB controller: Intel Corporation ValleyView USB xHCI Host Controller (rev 0c)
00:1a.0 Encryption controller: Intel Corporation ValleyView SEC (rev 0c)
00:1b.0 Audio device: Intel Corporation ValleyView High Definition Audio Controller (rev 0c)
00:1c.0 PCI bridge: Intel Corporation ValleyView PCI Express Root Port (rev 0c)
00:1c.1 PCI bridge: Intel Corporation ValleyView PCI Express Root Port (rev 0c)
00:1c.2 PCI bridge: Intel Corporation ValleyView PCI Express Root Port (rev 0c)
00:1f.0 ISA bridge: Intel Corporation ValleyView Power Control Unit (rev 0c)
00:1f.3 SMBus: Intel Corporation ValleyView SMBus Controller (rev 0c)
03:00.0 Ethernet controller: Realtek Semiconductor Co., Ltd. RTL8111/8168/8411 PCI Express Gigabit Ethernet Controller (rev 0c)

さらにググって調べると、Realtek RTL8111用ドライバはLinuxカーネルのソースツリーに存在しており、それをカーネルへ組み込むには、「CONFIG_R8169」という設定を有効にすれば良いらしいことが判りました。現状のE38xx用Yocto Linuxでこのコンフィグレーション設定が有効になっているか確認すると、やはり有効になっていませんでした。
# zcat /proc/config.gz | grep CONFIG_R8169
# CONFIG_R8169 is not set

上記の情報に基づいて、Yocto LinuxのE38xx BSPへRTL8111用ドライバを追加するカスタマイズを行ったので、その作業の詳細内容を掲載します。このカスタマイズ作業は特定のBSPに依存していません。したがって、Yocto LinuxのBSPをカスタマイズしたい場合の参考情報になると思います。

■ カーネル・カスタマイズのワークフロー


最初に、Yocto Linuxのカーネルをカスタマイズする方法について記します。カーネルのカスタマイズによって課題を解決できた後にその結果をBSPへ反映する流れで、2つのフェーズに分けて作業をします。なお、Yocto Projectの公式サイトに掲載されている以下のページの内容を参考にして以降の作業を行いました。

 Yocto Project Linux Kernel Development Manual

また、以降の内容は、09/24の記事のYocto Linuxのビルド作業が一度完了していることを仮定しています。

システム構成イメージまたはカーネルのビルドが完了している状態で、Yocto Linuxのカーネルのカスタマイズを始めたい場合は、次のコマンドを使います。
$ bitbake linux-yocto -c menuconfig

このコマンドを実行すると、カーネルの「make menuconfig」に相当する処理が起動され、カーネルのコンフィグレーション・メニュー画面が別ウィンドウで開きます。
UBShot_20141025_124348-Customizing_YoctoLinux1.6.1_E38xx_BSP_for_DE3815TYKE.png
ここで表示されているメニュー画面には、ビルド済みのターゲット用カーネルのコンフィグレーション設定が完全に反映されています。このメニュー画面から目的の設定項目を変更すれば、カーネルをカスタマイズすることができます。

今回の目的はRTL8111用ドライバをカーネルへ組み込むことなので、以下のとおりに、メニューを辿って該当する設定項目を有効にしました。
         Device Drivers  --->

[*] Nework device support --->

[*] Ethernet driver support --->

[*] Realtek devices
<M> Realtek 8169 gigabit ethernet support

UBShot_20141025_124750-Customizing_YoctoLinux1.6.1_E38xx_BSP_for_DE3815TYKE.png
上のメニュー項目名では「Realtek 8169」となっています。Realtekのサイトの情報によると、RTL8169/8110はPCIベースのEthernet Controllerですが、カーネルに組み込まれているドライバは最新版であり、このドライバはPCIeベースのRTL8168/8111にも対応しているらしいです。

コンフィグレーション・メニュー画面によるカーネル設定の変更がすべて終わったら、<Exit>を選びながら画面を遡っていき、最後の確認画面で<Yes>を選択すれば設定内容を保存できます。
UBShot_20141025_135805-Customizing_YoctoLinux1.6.1_E38xx_BSP_for_DE3815TYKE.png
変更したコンフィグレーション設定を適用してカーネルを再ビルドしたい場合は、次のコマンドを実行すれば、その処理が走ります。
$ bitbake linux-yocto -c compile -f

カーネルの再ビルドが終了したら、以下のコマンドを実行すれば、<BUILD_DIR>/tmp/deploy/images/${MACHINE}ディレクトリへカーネルイメージがデプロイ(配置)されます。
$ bitbake linux-yocto -c deploy

さらに、sysrootの更新とカーネル・パッケージの作成も行いたい場合は、以下のコマンドを実行します。
$ bitbake linux-yocto

そして、さらに続けて下のコマンドを実行すると、再ビルドしたカーネルイメージを組み込んだシステム構成イメージを生成することができます。
$ bitbake core-image-sato

これによって、新しいhddimgイメージファイルが生成されます。

再ビルドによって更新したcore-image-satoのhddimgファイルをUSBメディアに書き込み、それを使ってDE3815TYKHEでYocto Linuxを起動してみました。そして、カーネルの「CONFIG_R8169」設定が有効になっているか確認しました。
# zcat /proc/config.gz | grep CONFIG_R8169
CONFIG_R8169=m

dmesgコマンドで起動直後のカーネルログを表示すると、以下のとおり、RTL8168/8169/8110/8111用ドライバがロードされていることが確認できました。
# dmesg
.... ....
.... ....
.... ....
.... ....
[ 6.060784] r8169 Gigabit Ethernet driver 2.3LK-NAPI loaded
[ 6.062982] r8169 0000:03:00.0: irq 107 for MSI/MSI-X
[ 6.063331] r8169 0000:03:00.0 eth0: RTL8168g/8111g at 0xffffc9000001e000, xx:xx:xx:xx:xx:xx, XID 0c000800 IRQ 107
[ 6.063340] r8169 0000:03:00.0 eth0: jumbo features [frames: 9200 bytes, tx checksumming: ko]
[ 6.837858] r8169 0000:03:00.0 eth0: unable to load firmware patch rtl_nic/rtl8168g-2.fw (-2)
[ 6.842495] r8169 0000:03:00.0 eth0: link down
[ 6.842511] r8169 0000:03:00.0 eth0: link down
[ 6.842564] IPv6: ADDRCONF(NETDEV_UP): eth0: link is not ready
[ 8.901567] r8169 0000:03:00.0 eth0: link up
[ 8.901604] IPv6: ADDRCONF(NETDEV_CHANGE): eth0: link becomes ready
[ 12.206428] r8169 0000:03:00.0 eth0: link down
[ 12.206447] r8169 0000:03:00.0 eth0: link down
[ 12.206554] IPv6: ADDRCONF(NETDEV_UP): eth0: link is not ready
[ 12.256193] r8169 0000:03:00.0 eth0: link up
[ 12.256233] IPv6: ADDRCONF(NETDEV_CHANGE): eth0: link becomes ready

Ethernetのネットワーク・インターフェースもちゃんと認識されていました。
# ifconfig
eth0 Link encap:Ethernet HWaddr XX:XX:XX:XX:XX:XX
inet addr:192.168.223.9 Bcast:192.168.223.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:18 errors:0 dropped:0 overruns:0 frame:0
TX packets:49 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:3902 (3.8 KiB) TX bytes:8543 (8.3 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:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)



■ DE3815TYKHE用BSPレイヤの作成


上記の作業によって、カーネルへのRTL8111用ドライバの組み込みは一応終わりましたが、この作業の結果は、<BUILD_DIR>/tmp/workディレクトリの下に一時的なビルド状態として残っています。この状態で(ソースの展開を伴う)カーネルのクリーンビルドを行うと、一時的なビルド状態は破棄されてしまいます。カーネルに対する変更内容を永続的な設定情報として保存したい場合は、それをBSPへ反映する必要があります。

Yocto LinuxのBSPはレシピの集合体ですが、BSPにはカーネルのレシピが含まれています。カーネルのコンフィグレーション設定を変更したい場合は、カーネルレシピにその内容を記述しなければなりません。E38xx BSPのレシピはディレクトリmeta-intel/meta-isg/meta-valleyisland以下に格納されており、そのファイル構成は以下のようになっています。

  meta-valleyisland
|-- conf
| |-- machine
| | |-- valleyisland-32.conf
| | `-- valleyisland-64.conf
| `-- layer.conf
|-- recipes-bsp
| `-- formfactor
| |-- formfactor
| | |-- valleyisland-32
| | | `-- machconfig
| | `-- valleyisland-64
| | `-- machconfig
| `-- formfactor_0.0.bbappend
`-- recipes-kernel
`-- linux
`-- linux-yocto_3.10.bbappend

上のうち、conf/layer.confがレイヤの定義ファイルです。そして、recipes-kernel/linux/linux-yocto_3.10.bbappendがカーネルのレシピ・ファイルです。この2つのファイルの内容を以下に示します。
#We have a conf and classes directory, add to BBPATH
BBPATH .= ":${LAYERDIR}"

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

BBFILE_COLLECTIONS += "valleyisland\"
BBFILE_PATTERN_valleyisland := "^${LAYERDIR}/"
BBFILE_PRIORITY_valleyisland = "6"

LAYERDEPENDS_valleyisland = "intel"

LICENSE_PATH += "${LAYERDIR}/custom-licenses"

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

#############################
# MACHINE = valleyisland-32 #
#############################
COMPATIBLE_MACHINE_valleyisland-32 = "valleyisland-32"
KMACHINE_valleyisland-32 = "valleyisland-32"
KBRANCH_valleyisland-32 = "standard/base"
KERNEL_FEATURES_valleyisland-32 = " features/valleyisland-io/valleyisland-io \
features/valleyisland-io/valleyisland-io-pci"

LINUX_VERSION_valleyisland-32 = "3.10.43"
SRCREV_machine_valleyisland-32 = "aa677a2d02677ec92d59a8c36d001cf2f5cf3260"
SRCREV_meta_valleyisland-32 = "199943142f7e0a283240246ee6c02f4376b315f0"
SRCREV_valleyisland-io_valleyisland-32 = "27bc40c174bb4ca160eafd6ccf3da9e774c9a8c7"

SRC_URI_valleyisland-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"

#############################
# MACHINE = valleyisland-64 #
#############################
COMPATIBLE_MACHINE_valleyisland-64 = "valleyisland-64"
KMACHINE_valleyisland-64 = "valleyisland"
KBRANCH_valleyisland-64 = "standard/base"
KERNEL_FEATURES_valleyisland-64 = " features/valleyisland-io/valleyisland-io \
features/valleyisland-io/valleyisland-io-pci.scc"

LINUX_VERSION_valleyisland-64 = "3.10.43"
SRCREV_machine_valleyisland-64 = "aa677a2d02677ec92d59a8c36d001cf2f5cf3260"
SRCREV_meta_valleyisland-64 = "199943142f7e0a283240246ee6c02f4376b315f0"
SRCREV_valleyisland-io_valleyisland-64 = "27bc40c174bb4ca160eafd6ccf3da9e774c9a8c7"

SRC_URI_valleyisland-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"

module_autoload_i2c-dev = "i2c-dev"

上のlinux-yocto_3.10.bbappendを直接編集してレシピを改造することもできますが、Yocto Linuxで新しいターゲット用のBSPを作成する場合は、既存のBSPとは独立した新規のレイヤを作成するのがセオリーです。このセオリーに従って、ここでDE3815TYKHEのBSPレイヤの格納先ディレクトリを作成しました。
$ cd ~/Yocto
$ cd poky-daisy-11.0.1
$ cp -r meta-intel/meta-isg/meta-valleyisland meta-ed3815tyke

E38xx用BSPの全ファイルをディレクトリ構成を維持したままコピーして、DE3815TYKHE用BSPのディレクリトを作成しています(Yocto Linuxのレイヤ・ディレクトリには「meta-」という接頭詞を付けるのがルールになっています)。さらに、ファイルとディレクトリの名前にBSPのターゲット名が含まれているものをすべてリネームしました(DE3815TYKHE用BSPのターゲット名として、本体貼付のラベルに記載されている「DE3815TYKE」の方を採用しました)。
$ cd meta-ed3815tyke
$ cd conf/machine
$ mv valleyisland-32 de3815tyke-32
$ mv valleyisland-64 de3815tyke-64
$ cd ../..
$ cd recipes-bsp/formfactor
$ mv valleyisland-32 de3815tyke-32
$ mv valleyisland-64 de3815tyke-64

ここまでの操作によって、DE3815TYKHE用BSPレイヤのファイル構成は以下のようになりました。

  meta-de3815tyke
|-- conf
| |-- machine
| | |-- de3815tyke-32.conf
| | `-- de3815tyke-64.conf
| `-- layer.conf
|-- recipes-bsp
| `-- formfactor
| |-- formfactor
| | |-- de3815tyke-32
| | | `-- machconfig
| | `-- de3815tyke-64
| | `-- machconfig
| `-- formfactor_0.0.bbappend
`-- recipes-kernel
`-- linux
`-- linux-yocto_3.10.bbappend

ファイルとディレクトリのリネームが終わった後、conf/layer.confを以下のように編集しました。
#We have a conf and classes directory, add to BBPATH
BBPATH .= ":${LAYERDIR}"

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

BBFILE_COLLECTIONS += "de3815tyke"
BBFILE_PATTERN_de3815tyke := "^${LAYERDIR}/"
BBFILE_PRIORITY_de3815tyke = "6"

LAYERDEPENDS_de3815tyke = "intel"

LICENSE_PATH += "${LAYERDIR}/custom-licenses"

さらに、カーネルレシピであるrecipes-kernel/linux/linux-yocto_3.10.bbappendも以下のように編集しました。
FILESEXTRAPATHS_prepend := "${THISDIR}/${PN}:"

#############################
# MACHINE = de3815tyke-32 #
#############################
COMPATIBLE_MACHINE_de3815tyke-32 = "de3815tyke-32"
KMACHINE_de3815tyke-32 = " valleyisland-32"
KBRANCH_de3815tyke-32 = "standard/base"
KERNEL_FEATURES_de3815tyke-32 = " features/valleyisland-io/valleyisland-io \
features/valleyisland-io/valleyisland-io-pci"

LINUX_VERSION_de3815tyke-32 = "3.10.43"
SRCREV_machine_de3815tyke-32 = "aa677a2d02677ec92d59a8c36d001cf2f5cf3260"
SRCREV_meta_de3815tyke-32 = "199943142f7e0a283240246ee6c02f4376b315f0"
SRCREV_valleyisland-io_de3815tyke-32 = "27bc40c174bb4ca160eafd6ccf3da9e774c9a8c7"

SRC_URI_de3815tyke-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"

#############################
# MACHINE = de3815tyke-64 #
#############################
COMPATIBLE_MACHINE_de3815tyke-64 = "de3815tyke-64"
KMACHINE_de3815tyke-64 = "valleyisland"
KBRANCH_de3815tyke-64 = "standard/base"
KERNEL_FEATURES_de3815tyke-64 = " features/valleyisland-io/valleyisland-io \
features/valleyisland-io/valleyisland-io-pci.scc"

LINUX_VERSION_de3815tyke-64 = "3.10.43"
SRCREV_machine_de3815tyke-64 = "aa677a2d02677ec92d59a8c36d001cf2f5cf3260"
SRCREV_meta_de3815tyke-64 = "199943142f7e0a283240246ee6c02f4376b315f0"
SRCREV_valleyisland-io_de3815tyke-64 = "27bc40c174bb4ca160eafd6ccf3da9e774c9a8c7"

SRC_URI_de3815tyke-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"

module_autoload_i2c-dev = "i2c-dev"

以上でDE3815TYKHE用BSPレイヤの作成は終わりですが、ここまでの作業でやった内容をまとめます。
  1. 改造したい既存のBSPの全ファイルを、ディレクトリ構成を維持してコピーする。
  2. ファイルとディレクトリの名前にターゲット名が含まれていたら、それらをすべて新ターゲット名にリネームする。
  3. conf, bb, bbappendファイル内の変数名にターゲット名が含まれていたら、それらをすべて新ターゲット名にリネームする(ついでに、コメント内のターゲット名もリネームしておく)。

上記の作業によって、コピー元のBSPと完全に同一の内容でターゲット名だけが異なるBSPを作成したことになります。

■ defconfigによるBSPのカスタマイズ


DE3815TYKHE用のBSPレイヤが作成できたので、これのカーネルレシピに、CONFIG_R8169を有効にするコンフィグレーション設定を追加します。

上記で「bitbake linux-yocto -c menuconfig」コマンドによってカーネルの設定を変更する方法を紹介しましたが、コンフィグレーション・メニュー画面によって変更を加えたカーネルの全設定内容は.configというファイルに保存されています。bitbakeコマンドによるカーネルのビルド時に実行されるコンフィグレーション・フェーズにおいて、変更後の.configの内容が適用されるようにすれば目的を達成できます。ここからDE3815TYKHE BSPをカスタマイズしていきます。

まずは、「bitbake linux-yocto -c menuconfig」コマンドによってカーネルのコンフィグレーション設定の変更を行った後、その設定内容が保存されている.configをDE3815TYKHE用BSPレイヤの特定のディレクトリへコピーします。
$ mkdir ../meta-de3815tyke/recipes-kernel/linux/linux-yocto
$ cp tmp/work/corei7-64-intel-common-poky-linux/linux-yocto/3.10.43+gitAUTOINC+199943142f_aa677a2d02-r0/linux-corei7-64-intel-common-standard-build/.config ../meta-de3815tyke/recipes-kernel/linux/linux-yocto/defconfig

コピー時にファイル名をdefconfigにリネームしてください(後述の「bitbake linux-yocto -c diffconfig」コマンドを実行した後だと、コピー元の.configの内容はコンフィグレーション・メニュー画面で変更を加える前の旧設定値に書き戻されています。その場合は、もう一度「bitbake linux-yocto -c menuconfig」コマンドによって設定変更をやり直した上で、.configdefconfigへコピーしてください)。

defconfigの作成が終わったら、新しく作成したDE3815TYKHE BSPのカーネルレシピを以下のとおりに書き換えます。
FILESEXTRAPATHS_prepend := "${THISDIR}/${PN}:"

#############################
# MACHINE = de3815tyke-32 #
#############################
COMPATIBLE_MACHINE_de3815tyke-32 = "de3815tyke-32"
KMACHINE_de3815tyke-32 = " valleyisland-32"
KBRANCH_de3815tyke-32 = "standard/base"
KERNEL_FEATURES_de3815tyke-32 = " features/valleyisland-io/valleyisland-io \
features/valleyisland-io/valleyisland-io-pci"

LINUX_VERSION_de3815tyke-32 = "3.10.43"
SRCREV_machine_de3815tyke-32 = "aa677a2d02677ec92d59a8c36d001cf2f5cf3260"
SRCREV_meta_de3815tyke-32 = "199943142f7e0a283240246ee6c02f4376b315f0"
SRCREV_valleyisland-io_de3815tyke-32 = "27bc40c174bb4ca160eafd6ccf3da9e774c9a8c7"

SRC_URI_de3815tyke-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_de3815tyke-32 += "file://defconfig"

#############################
# MACHINE = de3815tyke-64 #
#############################
COMPATIBLE_MACHINE_de3815tyke-64 = "de3815tyke-64"
KMACHINE_de3815tyke-64 = "valleyisland"
KBRANCH_de3815tyke-64 = "standard/base"
KERNEL_FEATURES_de3815tyke-64 = " features/valleyisland-io/valleyisland-io \
features/valleyisland-io/valleyisland-io-pci.scc"

LINUX_VERSION_de3815tyke-64 = "3.10.43"
SRCREV_machine_de3815tyke-64 = "aa677a2d02677ec92d59a8c36d001cf2f5cf3260"
SRCREV_meta_de3815tyke-64 = "199943142f7e0a283240246ee6c02f4376b315f0"
SRCREV_valleyisland-io_de3815tyke-64 = "27bc40c174bb4ca160eafd6ccf3da9e774c9a8c7"

SRC_URI_de3815tyke-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_de3815tyke-64 += "file://defconfig"

module_autoload_i2c-dev = "i2c-dev"

上のカーネルレシピの先頭に存在する「FILESEXTRAPATHS_prepend := "${THISDIR}/${PN}:"」という記述に注目してください。この設定記述がdefconfigファイルの格納先ディレクトリ・パスを表しています。「${THISDIR}」がこのレシピファイル自身が格納されているディレクトリパスに、「${PN}」がファイル名linux-yocto_3.10.bbappendのパッケージ名部分である「linux-yocto」に翻訳されます。

以上で、DE3815TYKHE BSPのカスタマイズは完了です。「えー。たったこれだけ」と思われるかもしれませんが、本当にこれで完成です。ここまでの操作によって、DE3815TYKHE用BSPレイヤのファイル構成は以下のようになっています。

  meta-de3815tyke
|-- conf
| |-- machine
| | |-- de3815tyke-32.conf
| | `-- de3815tyke-64.conf
| `-- layer.conf
|-- recipes-bsp
| `-- formfactor
| |-- formfactor
| | |-- de3815tyke-32
| | | `-- machconfig
| | `-- de3815tyke-64
| | `-- machconfig
| `-- formfactor_0.0.bbappend
`-- recipes-kernel
`-- linux
|-- linux-yocto
| `-- defconfig
`-- linux-yocto_3.10.bbappend

このカスタマイズ済みのBSPを使って、Yocto Linuxをビルドしてみましょう。以下の手順に従えば、DE3815TYKHE用にYocto Linuxをビルドできます。
  1. 新しいターミナルを開いて、DE3815TYKHE用のビルド作業ディレクトリを作成します。
    $ cd ~/Yocto
    $ cd poky-daisy-11.0.1
    $ source oe-init-build-env de3815tyke

  2. ディレクリトde3815tykeの下に作成される以下の2つのファイルを編集します。
    --- conf/bblayers.conf.000	2014-10-24 17:59:58.912820953 +0900
    +++ conf/bblayers.conf 2014-10-24 18:01:19.972135858 +0900
    @@ -9,6 +9,9 @@
    /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-intel \
    + /home/yuhri/Yocto/poky-daisy-11.0.1/meta-intel/meta-tlk \
    + /home/yuhri/Yocto/poky-daisy-11.0.1/meta-de3815tyke \
    "
    BBLAYERS_NON_REMOVABLE ?= " \
    /home/yuhri/Yocto/poky-daisy-11.0.1/meta \

    --- conf/local.conf.000	2014-10-24 17:59:58.904820607 +0900
    +++ conf/local.conf 2014-10-24 18:06:16.568385416 +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 ?= "8"
    #
    # 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 8"
    #
    # 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 ?= "de3815tyke-64"
    +MACHINE ??= "valleyisland-64"

    #
    # Where to place downloads
    @@ -251,3 +252,8 @@
    # track the version of this file when it was generated. This can safely be ignored if
    # this doesn't mean anything to you.
    CONF_VERSION = "1"
    +
    +# The meta-valleyisland contains support for Intel HD Audio. However, HD Audio
    +# driver is dependent on gstreamer plugins and ffmpeg plugins to work properly.
    +# These gstreamer plugins require license flags in order to be included in the build.
    +LICENSE_FLAGS_WHITELIST = "commercial"

  3. ここまでの準備が終わったら、DE3815TYKHE用のターゲット・イメージをビルドすることができます。
    $ bitbake core-image-sato -c fetchall
    $ bitbake core-image-sato

    上のコマンドによって、tmp/deploy/images/de3815tyke-64/core-image-sato-de3815tyke-64.hddimgというイメージ・ファイルが生成されます。

■ cfgファイルによるBSPのカスタマイズ


上記ではdefconfigを使ってBSPをカスタマイズする方法について説明しましたが、もう一つ別の方法があるのでそれも紹介しましょう。コンフィグレーションフラグメントというものを使って、カーネル・ビルド時の.configへ変更を加える方法です。

まずは、旧BSPのビルド作業ディレクリトに戻りましょう。Valley Island用にYocto Linuxをビルドした際のターミナル画面が開いたままなら、そちらの画面を選択します。ターミナル画面を閉じてしまっていたら、新しいターミナル画面を開き、oe-init-build-envスクリプトによってValley Island用のビルド作業ディレクリトへ移動してください。
$ cd ~/Yocto
$ cd poky-daisy-11.0.1
$ source oe-init-build-env valleyisland

そして、カーネルのコンフィグレーション・メニュー画面で変更した設定内容の差分を取得します。「bitbake linux-yocto -c menuconfig」コマンドを実行した後に、以下のコマンドを実行するとそれができます。
$ bitbake linux-yocto -c diffconfig

このコマンドによって、<BUILD_DIR>/tmp/work/corei7-64-intel-common-poky-linux/linux-yocto/3.10.43+gitAUTOINC+199943142f_aa677a2d02-r0の中にfragment.cfgというファイルが作成されます(Yocto Linuxでは、個々のコンフィグレーション設定のことを「Configuration Fragment(コンフィグレーションフラグメント)」と呼びます)。このfragment.cfgの中にカーネルのコンフィグレーション設定の差分情報が格納されています。このファイルの内容を以下に示します。
++ .config	2014-10-24 11:18:48.549296777 +0900
CONFIG_FW_LOADER=m
CONFIG_FIRMWARE_IN_KERNEL=y
CONFIG_EXTRA_FIRMWARE=""
CONFIG_FW_LOADER_USER_HELPER=y
CONFIG_R8169=m
# CONFIG_SND_HDA_CODEC_CA0132_DSP is not set

bitbake linux-yocto -c menuconfig」コマンドによって変更を加えたカーネルの新旧のコンフィグレーション設定値はそれぞれ.config.config.oldというファイルに保存されますが、上のコマンドはこの2つのファイルを比較して差分を生成しているようです。なお、「bitbake linux-yocto -c diffconfig」コマンドを実行すると、.configの内容はコンフィグレーション・メニュー画面によって変更する前の.config.oldの内容に書き戻されてしまいます(このコマンドによって生成したfragment.cfgは、変更前のカーネル・コンフィグレーション設定に対して適用すべきものだからでしょう)。

fragment.cfgを作成できたら、それをDE3815TYKHEのBSPレイヤ・ディレクトリへコピーします。
$ cp -p tmp/work/corei7-64-intel-common-poky-linux/linux-yocto/3.10.43+gitAUTOINC+199943142f_aa677a2d02-r0/fragment.cfg ../meta-de3815tyke/recipes-kernel/linux/linux-yocto/add_driver-net_ethernet_r8169.cfg

そして、DE3815TYKHE BSPのカーネルレシピを以下のとおりに書き換えます。
FILESEXTRAPATHS_prepend := "${THISDIR}/${PN}:"

#############################
# MACHINE = de3815tyke-32 #
#############################
COMPATIBLE_MACHINE_de3815tyke-32 = "de3815tyke-32"
KMACHINE_de3815tyke-32 = " valleyisland-32"
KBRANCH_de3815tyke-32 = "standard/base"
KERNEL_FEATURES_de3815tyke-32 = " features/valleyisland-io/valleyisland-io \
features/valleyisland-io/valleyisland-io-pci"

LINUX_VERSION_de3815tyke-32 = "3.10.43"
SRCREV_machine_de3815tyke-32 = "aa677a2d02677ec92d59a8c36d001cf2f5cf3260"
SRCREV_meta_de3815tyke-32 = "199943142f7e0a283240246ee6c02f4376b315f0"
SRCREV_valleyisland-io_de3815tyke-32 = "27bc40c174bb4ca160eafd6ccf3da9e774c9a8c7"

SRC_URI_de3815tyke-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_de3815tyke-32 += "file://add_driver-net_ethernet_r8169.cfg"

#############################
# MACHINE = de3815tyke-64 #
#############################
COMPATIBLE_MACHINE_de3815tyke-64 = "de3815tyke-64"
KMACHINE_de3815tyke-64 = "valleyisland"
KBRANCH_de3815tyke-64 = "standard/base"
KERNEL_FEATURES_de3815tyke-64 = " features/valleyisland-io/valleyisland-io \
features/valleyisland-io/valleyisland-io-pci.scc"

LINUX_VERSION_de3815tyke-64 = "3.10.43"
SRCREV_machine_de3815tyke-64 = "aa677a2d02677ec92d59a8c36d001cf2f5cf3260"
SRCREV_meta_de3815tyke-64 = "199943142f7e0a283240246ee6c02f4376b315f0"
SRCREV_valleyisland-io_de3815tyke-64 = "27bc40c174bb4ca160eafd6ccf3da9e774c9a8c7"

SRC_URI_de3815tyke-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_de3815tyke-64 += "file://add_driver-net_ethernet_r8169.cfg"

module_autoload_i2c-dev = "i2c-dev"

これでコンフィグレーションフラグメント版のBSPは完成です。コンフィグレーションフラグメント版のDE3815TYKHE用BSPレイヤのファイル構成を以下に示します。

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

このBSPを使って、DE3815TYKE用にYocto Linuxをビルドしてみましょう。

まずは、新しいターミナル画面を開いて、すでに作成済みのDE3815TYKE用ビルド作業ディレクトリへ移動します(もしDE3815TYKE用ビルド時のターミナル画面が開いていたら、そちらを選択します)。
$ cd ~/Yocto
$ cd poky-daisy-11.01
$ source oe-init-build-env de3815tyke

その上で、以下のコマンドを実行すれば、DE3815TYKE用のcore-image-satoイメージを再生成できます。
$ bitbake linux-yocto -c cleansstate
$ bitbake linux-yocto
$ bitbake core-image-sato

最初の「bitbake linux-yocto -c cleansstate」というコマンドは、既存のカーネルのビルド状態をすべて破棄するためのものです。このコマンドを実行すると、<BUILD_DIR>/tmp/work/corei7-64-intel-common-poky-linux/linux-yocto以下に作成されるカーネル用のビルド作業ディレクトリだけでなく、<BUILD_DIR>/tmp/deploy/images/${MACHINE}内のカーネルイメージファイルも削除されます。既存のカーネルのビルド状態をクリーンした後、「bitbake linux-yocto」コマンドを実行すれば、上で改変したカーネルレシピが適用されてカーネルが再ビルドされます。

以上、defconfigとcfgファイルを使ってBSPをカスタマイズする方法を紹介しました。どちらの方法でカスタマイズしても、改造後のBSPからビルドされるYocto Linuxは同一です。目的に応じて、この2つの方法を使い分けてれば良いと思いますが、前者の方法ではカーネルレシピの変更は一度だけで済みます。defconfigにはカーネル・コンフィグレーションの全設定内容が格納されているからです。カーネルのコンフィグレーション設定をさらに変更したい場合でも、BSPレイヤ内のdefconfigだけを更新してやれば良い訳です。これに対して、後者では、カーネルのコンフィグレーション設定を追加変更したい場合、毎回cfgファイルを生成して、その内容がカーネルへ反映されるようにカーネルレシピも変更してやる必要があります。後者の方法は手間がかかるように思えますが、機能別にcfgファイルを作成することができるというメリットがあります。

Yocto Projectから公開・配布されている全ファイルは、下のGitリポジトリで管理されています。

 Yocto Project - Source Repositories

このサイトのファイルはWebブラウザで参照することもできます。本業の仕事とプライベートな活動の両方でYocto Projectの研究を始めて以来、毎日上記のサイトのたくさんのレシピファイルを眺めていますが、Yocto LinuxのBSPの多くはcfgファイルを利用した形式になっています。

【2014/11/27 追記】

Yocto Project Gitリポジトリのlinux-yocto-3.10ツリーをチェックしていたら、下のようなコミットが存在することに気づきました。
SCShot_141127_0007-YoctoProejct_Git-linux-yocto-3.10-8f05306a8e6f5ee422d50c3317acce0cf9e6aada-1145x967
このコミットにより、Valley Island BSPのカーネルへRealtek RTL8168/8169/8110/8111用ドライバを有効にするコンフィグレーション設定が追加されたようです。本コミットのコメントでは「valleyisland 32bit」となっていますが、「valleyisland 64bit」の方にも同じ変更が加えられていることを確認しました。以下が、その内容です。
kconf hardware valleyisland.cfg

include cfg/x86_64.scc
include cfg/efi.scc
include cfg/dmaengine.scc
include cfg/8250.scc

include features/power/intel.scc

include features/i2c/i2c.scc
include features/i2c/i2cdev.scc

include features/i915/i915.scc

include features/intel-e1xxxx/intel-e100.scc
include features/intel-e1xxxx/intel-e1xxxx.scc

include features/spi/spi.scc
include features/spi/spidev.scc

include features/usb/ehci-hcd.scc
include features/usb/xhci-hcd.scc

kconf hardware bsp/common-pc/common-pc-eth.cfg

# Common Ethernet networking devices (including QEMU and Common PCs)
# Set very common NICs to y to avoid common NFS booting failures and the
# resulting bug reports.
CONFIG_NET_CORE=y
CONFIG_ETHERNET=y
CONFIG_MII=y
CONFIG_NET_VENDOR_BROADCOM=y
CONFIG_TIGON3=y
CONFIG_NET_VENDOR_ATHEROS=y
CONFIG_ATL2=m
CONFIG_NET_VENDOR_INTEL=y
CONFIG_E1000=y
CONFIG_NET_VENDOR_AMD=y
CONFIG_PCNET32=y
CONFIG_NET_VENDOR_REALTEK=y
CONFIG_8139CP=m
CONFIG_8139TOO=m
CONFIG_R8169=m
CONFIG_NET_VENDOR_ATHEROS=y
CONFIG_ATL1E=m

試しに、Yocto ProjectのGitリポジトリからPoky(Yocto Core)とValley Island BSPの最新版を取得して、この2つを組み合わせて、valleyisland-64ターゲット用のcore-image-satoイメージをビルドしてみました。さらに、生成したcore-image-sato-valleyisland-64.hddimgをUSBメディアへ書き込んで、そのメデイアを使ってDE3815TYKHEでYocto Linuxを起動してみました。その結果、カーネルのブート時にRTL8111ドライバがロードされて、eth0インターフェースがちゃんと作成されていることが確認できました。なお、PokyとValley Island BSPの公式リリース版はいずれもDaisy 1.6.1からDizzy 1.7へバージョンアップされていますが、後者には上記の変更内容が収納されているようです。

Yocto Projectの公式サイトやGitリポジトリからValley Island(Intel E38xx)BSPのDizzy 1.7以降(最新版を含む)を取得して、そのBSPからYocto Linuxのビルドを行う場合は、すでにカーネルにRTL8111(r8169)ドライバが組み込まれているので、本記事に記載した作業を行う必要はありません(もしかして、本記事の内容が上記のコミットのきっかけになったんでしょうか。もしそうなら嬉しいんですが・・・。Yocto Projectの開発者メンバーは日本語の記事なんかチェックしていないでしょうから、その可能性はないでしょうね)。

ちなみに、J1800/1900やE38xxプロセッサを搭載したボードは大抵Intel I210かRealtek RTL8111のどちらかのEthernetコントローラが実装されています。

【2014/12/27 追記】

Yocto Projectの公式サイトで、Poky(Yocto Project Core)のDaiay 1.6.2がリリースされています。下がそのリリース情報ページです。

 YP Core - Daisy 1.6.2 | Yocto Project

公式サイトも毎日チェックしているので、上のリリースの存在は知っていたのですが、昨日公式サイトのダウンロード・ページをチェックしていたら、Valley Island (Intel E38xx)BSPのDaisy 1.6.2リリース版がアップされているのを見つけました。公式サイト上にまだリンクは存在していないようですが、下がこのリリース版ファイルのリンクです。

 http://downloads.yoctoproject.org/releases/yocto/yocto-1.6.2/machines/valleyisland/valleyisland-1.0-daisy-1.6.2.tar.bz2

私がいままで使っていたPokyとValley Island はいずれもDaisy 1.6.1リリースのものです。じつは、(いままでのリリースも含めて)このValley Island (Intel E38xx)BSPの配布パッケージにはcore-sato-imageのhddimgファイルが収納されています。core-sato-imageイメージのビルドは最低でも2時間以上かかるので、手っ取り早くターゲットでYocto Linuxの動作確認をやりたい場合は、このファイルを利用すると良いです。

上のValley Island BSP Daisy 1.6.2に収納されているcore-sato-image-valleyisland-64.hddimgからLive USBメディアを作成し、それを使ってDE3815TYKHEでYocto Linuxを起動してみました。そして、ifconfigコマンドを実行すると、何とeth0インターフェースが生成されていました。dmesgコマンドの情報でも、r8169ドライバがロードされていることが確認できました。このBSPには、上の追記で紹介したGitコミットの更新内容が適用されているようです。
posted by とみやん at 10:28| Comment(0) | TrackBack(0) | Embedded Linux > Yocto Project

2014年10月13日

[Yocto] Intel DE3815TYKHEでYocto Linuxを動かす

Yocto Projectの研究に取り組みを始めて以来、最近はYocto Linuxの研究活動ばかりやっています。本業の仕事でもYocto Linuxの研究開発をやっているので、休日の時間までYocto Linuxをいじくり回すのに使ったりしています。Intel E38xxシリーズが組み込み向けに有望なプロセッサであることを知って以来、プライベートな研究活動用のターゲットとして同プロセッサを搭載したハードを探していましたが、やっとIntel NUC DE3815TYKHE(本体貼付のラベルでは、製品名は「DE3815TYKE」と記載されています)というベアボーンキットを入手できました。この機種に搭載されているプロセッサはIntel E3815です。
ANShot_20141012_113551-DE3815TYKHE-PackageItems.jpg
ANShot_20141012_113831-DE3815TYKHE-BackView.jpg
ANShot_20141013_134008-DE3815TYKHE-LabelOnBack.jpg
ANShot_20141012_130601-DE3815TYKHE-StandView.jpg
サイズは小さめの弁当箱くらいです。こういう小型のベアボーンキットは結構前から出回っていて、秋葉原のPCショップなどで見かけることもありました。デストップPC用のベアボーンキットはメジャー・メーカー製の物が多いですが、小型のベアボーンキットは大抵はマイナーなメーカーの製品でした。ところが、ここ数年省電力PCやホームサーバーの需要が高くなっているため、ASUSやGIGABYTEなどのメジャーなメーカーもこの種の製品を多く販売するようになっています。最近ではIntel自らこういう製品を販売していて(Intelが製造している訳ではなく、台湾か中国メーカーのOEM品でしょうが)、小型省電力ベアボーンPCの統一的な製品呼称としてIntelは「NUC(Next Unit of Computing)」という名称を使っています。今回私が購入したDE3815TYKHEという製品もIntel NUCシリーズ・ベアボーンキットの一つです。

じつは、MinnowBoard MAXのE3825 Daul-core版が欲しくて、こいつを個人輸入するべきかずいぶん悩みました。このボードはまだ予約注文しか受けつけていない状況のようで、MOUSERの商品ページでは「在庫:0 工場リードタイム:20週間」(本記事投稿時点)になっています。いま注文しても、実際に入手できるのは3〜4ヶ月位(もしかするともっと先)になるんじゃないかと思えました。これ以外にE38xx搭載ボードが他にないかと探し廻ったのですが、現状日本国内ですぐに入手できるのはDE3815TYKHEくらいしか見つかりませんでした。J1800/J1900 Bay Trail-Dを搭載したMini-ITXボードならASUS, GIGABYTE, ASRockなどから多くの種類の製品が販売されており、秋葉原のPCショップやAmazonでも購入できます。しかし、Bay Trailシリーズの最新版かつ最省電力版プロセッサであるE3800シリーズを搭載したボードは産業用として売られているものが多く、まだ製品の種類も製造量も少ないのが実情です。「E3845 Mini-ITX」というキーワードでググってみると、以下のようなページくらいしか見つかりませんでした。
 
  1. EMB-BT1 - Industrial Motherboards - Mini-ITX Motherboards
  2. WADE-8078,Mini-ITX,Embedded System Board,Embedded Computer- Portwell, Inc.
  3. COMMELL LV-67O Mini-ITX Support Bay Trail Intel Celeron J1900/N2930 and Atom E3845 Processor
  4. DFI Low-Power Mini-ITX Motherboards Support Intel Atom Processor-based SoC
  5. ASRock > UTX-110
  6. ASRock > ASRock UTX-110: スリム、スマート、そしてパワフル!

上のうち、1〜2は産業用ボード製品のようです。価格も高そうなので、入手は諦めた方が良さそうです。COMMELLとDFIのボードも産業用かもしれませんが、この2つのメーカーはデスクトップやサーバー用PCのマザーボードも製造しています(COMMELLは産業用ボードが主力製品です)。しかし、どちらもマイナーなメーカーなので、これらのボードも日本国内で入手するのは難しいでしょう。最後の2つのリンクは、ASRock製のUTXフォームファクタのボードの製品ページです。このボードも産業用みたいで、まだ発売されて間もない製品のようです。じつは、上のボードの中で一番欲しいと思ったのがこれです。ASRockはメジャーなメーカーなので、もしかすると日本へもこの製品が入ってくる可能性があるかもしれません。もしそうならったら、ぜひこいつを購入してみたいです。MinnowBoard MAXのようにフォームファクタがMini-ITXでないボードもありますが、ケーブルやケースなどの入手性を考えると、やはりMini-ITXがベストの選択でしょう。当面は今回入手したDE3815TYKHEを使っていきますが、近いうちにE3845(4コアのBay Trail-I)を搭載したMini-ITXボードを必ず入手しようと思っています。

■ DE3815TYKHEの組み立て


DE3815TYKHEに部品を追加して組み上げたので、その作業の様子を紹介します。DE3815TYKHEはベアボーンキットですが、CPUのE3815はオンボードの直付けです。したがって、追加部品として必要なのはメモリとSATAディスクだけです。以下の2つの部品を用意しました。
  • SAMSUNG純正PC3-12800 SO-DIMM 2GB DDR3L(電圧1.35V)対応モデル
  • Intel 320 Series SSD 80GB

前者はDE3815TYKHEと一緒にAmazonから購入し、後者はオークションで中古品を落札しました。メモリは2GBと4GBのどちらにするかずいぶん悩みました。Windows 7/8/8.1ならメモリは最低4GB搭載しないと実用になりませんが、こいつにWindowsを入れるつもりはまったくありません。Linuxの場合も実用機として使うならメモリは4GBあった方がベターですが、このDE3815TYKHEは開発専用ターゲットとしてしか使わないつもりなので2GBで十分だと思いました。

まずはDE3815TYKHEのカバーを開いてみました。下がDE3815TYKHEの内部の写真です。
ANShot_20141012_121052-DE3815TYKHE-BuildingUp.jpg
左側の一番大きなコネクタがDIMMスロットで、右側のスペースがディスクドライブを取り付け場所のようです。ちなみに、真ん中に位置するコネクタはMini-PCIeのスロットのようで、アンテナケーブルらしき物も見受けられます。ディスクドライブ用の金具を取り外して確認すると、このケーブルの先にちゃんとアンテナが付いていて、アンテナ本体部分はケース内側に貼り付けられていました。ということは、無線LANモジュールを取り付けるだけでWi-Fi機能を追加できることになります。そのうち、適当な無線LANモジュールを入手して、このMini-PCIeスロットに取り付けようと思っています。

いずれの部品も取り付け作業は特に難しくありません。部品用のネジもすべて付属しています。メモリはDIMMスロットへ挿し込むだけです。ディスクドライブの方は、金具を外して、それにディスクをネジ止めしてから、元の場所に戻すだけです。
ANShot_20141012_121831-DE3815TYKHE-BuildingUp.jpg
ANShot_20141012_122023-DE3815TYKHE-BuildingUp.jpg
ANShot_20141012_122800-DE3815TYKHE-BuildingUp.jpg
ANShot_20141012_122857-DE3815TYKHE-BuildingUp.jpg
ANShot_20141012_123402-DE3815TYKHE-BuildingUp.jpg
下の写真が、DE3815TYKHEにメモリとSSDを取り付けた状態です。
ANShot_20141012_124338-DE3815TYKHE-BuildingUp.jpg
PCを組み立てたことのある人なら誰でもできるでしょうし、そういう経験を持ってない人でもできそうなほど簡単な作業でした。メモリとSSDを取り付けたら、カバーを閉めれば組み立ては終わりです。

組み立て作業が終わったので、さっそくDE3815TYKHEの電源を入れてみました。すると、下のようなIntel NUCのロゴ画面がモニタに表示されました。
ANShot_20141012_151426-DE3815TYKHE-BIOS_Screen.jpg
この画面が表示された直後に、キーボードの[F2]キーを押すと、BIOSの画面が表示されました。
ANShot_20141012_134629-DE3815TYKHE-BIOS_Screen.jpg
PCやマザーボードのBIOS画面は大抵はキャラクタ・ベースのものが多いのですが、DE3815TYKHEのBIOS画面はグラフィカルなものでなかなか凝っています。このBIOS画面にはポインタ(矢印)が表示されているので、一見マウスが必要なように思えますが、キーボードだけでも操作できます。[Tab]キーを押す度に、画面上の選択可能なボタンやタブへ順次カーソル(オレンジ色の枠線)が移動するので、目的の場所で[Space]キーを押せば、それを選択できるようになっています。DE3815TYKHEのBIOSの構成画面を以下に示します。
ANShot_20141012_135636-DE3815TYKHE-BIOS_Screen.jpg
ANShot_20141012_135750-DE3815TYKHE-BIOS_Screen.jpg
ANShot_20141012_140010-DE3815TYKHE-BIOS_Screen.jpg
ANShot_20141012_140053-DE3815TYKHE-BIOS_Screen.jpg
ANShot_20141012_140153-DE3815TYKHE-BIOS_Screen.jpg
ANShot_20141012_140220-DE3815TYKHE-BIOS_Screen.jpg
ANShot_20141012_140256-DE3815TYKHE-BIOS_Screen.jpg
最近のPCやマザーボードに搭載されているBIOSはほとんどUEFI(Unified Extensible Firmware Interface)ベースのものばかりです。予想していたとおり、やはりDE3815TYKHEのBIOSもUEFIベースでした。UEFIベースのBIOSでLinuxを動かす場合、色々なTipsがあります。この辺の情報もそのうち書こうと思っています。

一般のユーザーなら、こういうベアポーンPCへインストールするのはWindowsだと思いますが、私の場合はあくまで組込みターゲットとして使うことが目的なので、Windowsを入れることは将来もないでしょう。Bay Trailについて調べているうちに、DE3815TYKHEのような小型の省電力ベアボーンキットが数多く販売されていることを知ったので、近いうちにこういうベアボーンキットを使ってメディアサーバーを一台を組んでみたいと思っていますが、この計画を実行するときは、WindowsではなくLinuxでサーバー環境を構築するつもりです。最近はオープンソースソフトも充実してきているので、デスクトップとサーバーのいずれもLinuxで十分に実用的な環境を構築できるはずです。Windowsの方が楽かもしれませんが、Linuxを使った方がより深い知識が得られます。私にとってWindowsはすでに過去のOSなので、使うのは仕事上どうしても必要な場合だけです。

■ DE3815TYKHEによるYocto Linuxの動作確認


DE3815TYKHEを入手した最大の目的がYocto Linuxを動かすことだったので、さっそくそれに挑戦してみました。Intel E38xx用BSPのビルドは前記事の作業で終わっているので、ビルドによって生成したYocto Linuxのイメージから起動用メディアを作成するところから始めました。

Intelのサイトから入手できる参考ドキュメント「Building Intel(R) Atom(TM) Processor E3800 Development Kit Yocto Project Board Support Package (BSP): User Guide 」には、開発ホスト機へUSBメモリを挿した状態で以下のコマンドを実行すれば、Yocto Linuxの起動メディアを作成できると記載されています。
# Identify the device file for your USB thumb drive.
$ df
# To write the bootable image to USB thumb drive, we assume it is at /dev/sdc.
# Unmount the the USB thumb drive first.
$ umount /dev/sdc

# Go to the scripts directory in poky.
$ cd ~/development/poky/scripts/contrib/
# Command: ./mkefidisk.sh <USB> <path/to/image> <target/rootfs>

上の手順を私の環境に合わせて読み換えて、以下ようなコマンドを実行しました。
$ cd ~/Yocto/poky-daisy-11.0.1
$ source oe-init-build-env valleyisland

### Shell environment set up for builds. ###

You can now run 'bitbake <target>'

Common targets are:
core-image-minimal
core-image-sato
meta-toolchain
adt-installer
meta-ide-support

You can also run generated qemu images with a command like 'runqemu qemux86'
$ df
Filesystem 1K-blocks Used Available Use% Mounted on
/dev/sda1 97019612 5535000 86556308 7% /
udev 2053336 4 2053332 1% /dev
tmpfs 412128 828 411300 1% /run
none 5120 0 5120 0% /run/lock
none 2060640 152 2060488 1% /run/shm
/dev/sdb1 264223716 143770272 107031684 58% /mnt/vmdk1
.host:/ 499268000 283111972 216156028 57% /mnt/hgfs
/dev/sdc1 15729584 8 15729576 1% /media/3809-5052
$ umount /dev/sdc1
$ cd ../scripts/contrib
$ sudo ./mkefidisk.sh /dev/sdc ../../valleyisland/tmp/deploy/images/valleyisland-64/core-image-sato-valleyisland-64.hddimg /dev/sda
Image details
=============
image: `../../valleyisland/tmp/deploy/images/valleyisland-64/core-image-sato-valleyisland-64.hddimg' -> `core-image-sato-valleyisland-64-20140924035205.hddimg'
size: 259637248 bytes
modified: 2014-09-24 16:11:08.177183633 +0900
type: x86 boot sector, code offset 0x58, OEM-ID "SYSLINUX", sectors/cluster 8, root entries 512, Media descriptor 0xf8, sectors/FAT 248, heads 64, sectors 507104 (volumes > 32 MB) , serial number 0x54226e8b, label: "boot ", FAT (16 bit)

Device details
==============
device: /dev/sdc
vendor: BUFFALO
model: USB Flash Disk
size: 15453913088 bytes

Prepare EFI image on /dev/sdc [y/N]? y
Information: You may need to update /etc/fstab.

*****************
Boot partition size: 20 MB (/dev/sdc1)
ROOTFS partition size: 14662 MB (/dev/sdc2)
Swap partition size: 772 MB (/dev/sdc3)
*****************
Deleting partition table on /dev/sdc ...
2+0 records in
2+0 records out
1024 bytes (1.0 kB) copied, 7.3805e-05 s, 13.9 MB/s
Creating new partition table (MSDOS) on /dev/sdc ...
Information: You may need to update /etc/fstab.

Creating boot partition on /dev/sdc1
Information: You may need to update /etc/fstab.

Enabling boot flag on /dev/sdc1
Information: You may need to update /etc/fstab.

Creating ROOTFS partition on /dev/sdc2
Information: You may need to update /etc/fstab.

Creating swap partition on /dev/sdc3
Information: You may need to update /etc/fstab.

Model: BUFFALO USB Flash Disk (scsi)
Disk /dev/sdc: 15.5GB
Sector size (logical/physical): 512B/512B
Partition Table: msdos

Number Start End Size Type File system Flags
1 1049kB 19.9MB 18.9MB primary boot
2 19.9MB 14.7GB 14.7GB primary
3 14.7GB 15.5GB 772MB primary


Formatting /dev/sdc1 as vfat...
mkfs.vfat 3.0.12 (29 Oct 2011)
Formatting /dev/sdc2 as ext3...
mke2fs 1.42 (29-Nov-2011)
Filesystem label=root
OS type: Linux
Block size=4096 (log=2)
Fragment size=4096 (log=2)
Stride=0 blocks, Stripe width=0 blocks
895840 inodes, 3579648 blocks
178982 blocks (5.00%) reserved for the super user
First data block=0
Maximum filesystem blocks=3665821696
110 block groups
32768 blocks per group, 32768 fragments per group
8144 inodes per group
Superblock backups stored on blocks:
32768, 98304, 163840, 229376, 294912, 819200, 884736, 1605632, 2654208

Allocating group tables: done
Writing inode tables: done
Creating journal (32768 blocks): done
Writing superblocks and filesystem accounting information: done

Formatting swap partition...(/dev/sdc3)
Setting up swapspace version 1, size = 753660 KiB
no label, UUID=311c78ce-c4e0-418f-9f56-9aa3d80575f1

Mounting images and device in preparation for installation...
Copying ROOTFS files...
Preparing boot partition...
Installation complete.

mkefdisk.shスクリプトの「Copying ROOTFS files…」というメッセージ出力の処理が実行されている途中で下のような警告ウィンドウが表示されましたが、USBメディアの作成は成功しているようです。
UBShot_20141012_150324-DE3815TYKHE-Running_YoctoLinux.png
ちなみに、起動メディアとして用意したのは16GBのUSBメモリ(USB 3.0対応の物)です。

上のコマンドによって作成したUSBメモリをDE3815TYKHEの前面のUSB 3.0対応ポートに挿した状態で、同機の電源を投入してみました。すると、モニタに下のようなGRUBのメニュー画面が表示されました。
ANShot_20141012_143831-DE3815TYKHE-Running_YoctoLinux.jpg
「おー。ブートできそうかなぁ?」と思いながら、この画面から「boot」という項目を選択してみましたが、下のようなエラーが表示されて、カーネルのブートシーケンスは途中で停止してしまいました。
ANShot_20141012_143917-DE3815TYKHE-Running_YoctoLinux.jpg
この現象の原因は良く判りませんが、もしかするとmkefdisk.shスクリプトによって作成したUSBメディアが対応しているのは、E38xx BSPの正規ターゲットであるIntel製の3種類のボードだけなのかもしれません。

上記の方法で作成したUSBメディアによってYocto Linuxを起動できなかったので、ここで色々な試行錯誤をしました。その結果、mkefdisk.shスクリプトに代わって下のようなコマンドを使えば、DE3815TYKHE用のUSB起動メディアを作成できることが判りました(DE3815TYKHEだけでなく他のメーカーのE38xx搭載ボードでも、下記の方法によって、Yocto LinuxのUSB起動メディアを作成できるんじゃないかと思います)。
$ cd ../../valleyisland
$ umount /dev/sdc1
$ sudo dd if=/dev/zero of=/dev/sdc bs=1M count=512
512+0 records in
512+0 records out
536870912 bytes (537 MB) copied, 41.7172 s, 12.9 MB/s
$ sync
$ sudo dd if=tmp/deploy/images/valleyisland-64/core-image-sato-valleyisland-64.hddimg of=/dev/sdc
507104+0 records in
507104+0 records out
259637248 bytes (260 MB) copied, 89.28 s, 2.9 MB/s
$ sync

最初にumountコマンドでUSBメモリをアンマウントしています。続いて、ddコマンドでUSBメモリの内容を消去し、さらにddコマンドにYocto Linuxのhddimgイメージ・ファイルを指定して、その格納イメージをUSBメモリへ書き込んでいます。このhddimgファイルには、ddコマンドに直接渡すことができるディスクバイナリ・イメージが格納されているようです。

上の手順によって作成したUSBメモリを挿した状態で、再度DE3815TYKHEの電源を投入してみました。すると、下のようなGRUBのメニュー画面がモニタに表示されました。
ANShot_20141012_154347-DE3815TYKHE-Running_YoctoLinux.jpg
この画面から「boot」を選択すると、今度はカーネルのブートシーケンスが正常に流れて、数秒後にYocto Projectのスプラッシュ画面が表示され、最後にSato Mobile Desktopの画面が表示されました。
ANShot_20141012_154838-DE3815TYKHE-Running_YoctoLinux.jpg
ANShot_20141012_155626-DE3815TYKHE-Running_YoctoLinux.jpg
USBメモリからYocto Linuxをブートできることが確認できたので、続いて、SATAディスクからブートできるか試してみました。USBメモリから起動した際にGRUBのメニュー画面に「install」という項目が存在しています。この「install」を選択することで、SATAディスクヘYocto Linuxのイメージを書き込むことができます。具体的な手順としては、GRUBのメニュー画面で「install」を選択します。
ANShot_20141012_155931-DE3815TYKHE-Running_YoctoLinux.jpg
すると、カーネルのブートシーケンスがしばらく流れた後、数秒後にディスクメディアの検索処理が自動的に実行されます。そして、USBメモリ以外のディスクメディアが見つかると、下のようなメッセージが表示されます。
ANShot_20141012_160429-DE3815TYKHE-Running_YoctoLinux.jpg
このメッセージに「y」と入力すれば、対象ディスク上にパーティションテーブルが作成され、さらにカーネルの起動イメージとrootfsファイル群の書き込みも自動的に実行されます。これらの処理が完了すると、下のようなメッセージが表示されてその状況が通知されます。
ANShot_20141012_160701-DE3815TYKHE-Running_YoctoLinux.jpg
上のメッセージの指示に従って、USBメモリを抜いてから[Enter]キーを押せば、PCがリブートして、SATAディスクからYocto Linuxが再起動します。下の写真が、DE3815TYKHEの内蔵SATAディスクから起動したSato Mobile Desktopが動いている様子です。
ANShot_20141012_161044-DE3815TYKHE-Running_YoctoLinux.jpg


posted by とみやん at 10:23| Comment(0) | TrackBack(0) | Embedded Linux > Yocto Project