Intel EdisonにXenomaiを入れる(ただしWiFi, BlueToothなし...) − (準備編)

お久しぶりです。
とーっっっっても久しぶりに書きます(4年9ヶ月ぶりくらいですね)。編集方法忘れてましたwww


Intel Edisonという、SDカードサイズで組込みLinuxの動作する機器がありますが、そこにLinuxのリアルタイム拡張であるXenomaiを導入してみます。ただし、Broadcomカーネルドライバ(WiFiBlueTooth)についてはXenomaiに対応できなかったので、現状では外しています。あしからず。


Edison では、Yocto ProjectLinuxが使われており、Edison用の環境のソースコードここからダウンロードでき、このドキュメントの通りにすれば、自分でビルドできます。
まずは一旦、ビルドしてみてください。

EdisonのKernelバージョンを変更する

さて、Edison上のLinux kernelは、Yocto Projectの3.10.17をベースにEdison用のパッチを適用してビルドしています。
一方、XenomaiはVanilla kernelの3.10.32に対するパッチが最も近いものになります。
なので手順としては、Edison上で3.10.32が動作する環境をまず作ってみて、その後Xenomaiパッチを作成・適用してビルドしていきます。
そこで、まずはEdison用のkernel 3.10.32を準備しましょう。

Yoctoの3.10.32のソースコードダウンロード

Yoctoの3.10.32のソースコードは、Yocto Projectのリポジトリ内のここからダウンロードできます。

3.10.32のEdison用パッチの作成

ダウンロードしたら展開し、Edison用パッチを当ててみます。ここでEdisonのソースを展開したディレクトリにダウンロードしたカーネルを展開するものとします。

$ ls
edison-src  linux-yocto-3.10-3.10.32.tar.bz2
$ tar jxf linux-yocto-3.10-3.10.32.tar.bz2
$ ls
edison-src  linux-yocto-3.10-3.10.32  linux-yocto-3.10-3.10.32.tar.bz2
$ cd linux-yocto-3.10-3.10.32
$ patch -p1 < ../edison-src/device-software/meta-edison/recipes-kernel/linux/files/upstream_to_edison.patch

すると以下のように2回ほどリバースパッチを検出して入力を求められますので、すべてリターンキーを押してやり過ごします。

...
patching file kernel/cgroup.c
Reversed (or previously applied) patch detected!  Assume -R? [n]               <--- Return
Apply anyway? [n]                                                              <--- Return
Skipping patch.
3 out of 3 hunks ignored -- saving rejects to file kernel/cgroup.c.rej
...
patching file kernel/trace/trace.c
Reversed (or previously applied) patch detected!  Assume -R? [n]               <--- Return
Apply anyway? [n]                                                              <--- Return
Skipping patch.
1 out of 1 hunk ignored -- saving rejects to file kernel/trace/trace.c.rej
patching file sound/soc/codecs/sn95031.c
$

このとき、パッチ適用に失敗したファイルは3個ほどになります。

$ find . -name "*.rej"
./drivers/hwmon/coretemp.c.rej
./kernel/trace/trace.c.rej
./kernel/cgroup.c.rej
$ 

このうち、kernel/trace/trace.cとkernel/cgroup.cについては無視してかまいません。3.10.17から3.10.32にバージョンが変わった間に適用された修正がEdisonパッチにも含まれていただけですので。

drivers/hwmon/coretemp.cに対する失敗は手動で修正します。
54行目から以下のように修正します。

#define BASE_SYSFS_ATTR_NO      2       /* Sysfs Base attr no for coretemp */
#define NUM_REAL_CORES          32      /* Number of Real cores per cpu */
#define CORETEMP_NAME_LENGTH    19      /* String Length of attrs */
#define MAX_CORE_ATTRS          4       /* Maximum no of basic attrs */
#define TOTAL_ATTRS             (MAX_CORE_ATTRS + 1)
#define MAX_CORE_DATA           (NUM_REAL_CORES + BASE_SYSFS_ATTR_NO)

        ↓↓↓↓↓

#define BASE_SYSFS_ATTR_NO      2       /* Sysfs Base attr no for coretemp */
#define NUM_REAL_CORES          32      /* Number of Real cores per cpu */
#define CORETEMP_NAME_LENGTH    33      /* String Length of attrs */
#define MAX_CORE_ATTRS          5       /* Maximum no of basic attrs */
#define MAX_THRESH_ATTRS        4       /* Maximum no of threshold attrs */
#define TOTAL_ATTRS             (MAX_CORE_ATTRS + MAX_THRESH_ATTRS)
#define MAX_CORE_DATA           (NUM_REAL_CORES + BASE_SYSFS_ATTR_NO)

あとはパッチ時に出来た余計なファイルを消します。Emacsで編集した場合には、編集時のバックアップファイル(drivers/hwmon/coretemp.c~)も消しましょう。

$ find . -name "*.rej" -exec rm {} \;
$ find . -name "*.orig" -exec rm {} \;

あとはもとの3.10.32カーネルと差分をとってパッチを作成します。

$ cd ..
$ mv linux-yocto-3.10-3.10.32 linux-yocto-3.10-3.10.32-edison
$ tar jxf linux-yocto-3.10-3.10.32.tar.bz2
$ diff -Narup linux-yocto-3.10-3.10.32 linux-yocto-3.10-3.10.32-edison > upstream_to_edison.3.10.32.patch

これを元のパッチがあった場所に配置して3.10.32用のEdisonパッチの作成はひとまず完了です。

$ cp upstream_to_edison.3.10.32.patch edison-src/device-software/meta-edison/recipes-kernel/linux/files/
bitbakeの設定ファイルの修正

bitbakeで3.10.32カーネルコンパイルするためには、ディレクトリ edison-src/device-software/meta-edison/recipes-kernel/linux/ にある
linux-yocto_3.10.bbappend を修正する必要があります。

このファイルの中身は以下のようになっています。

FILESEXTRAPATHS_prepend := "${THISDIR}/files:"
COMPATIBLE_MACHINE = "edison"
LINUX_VERSION = "3.10.17"
SRCREV_machine = "c03195ed6e3066494e3fb4be69154a57066e845b"
SRCREV_meta = "6ad20f049abd52b515a8e0a4664861cfd331f684"

SRC_URI += "file://defconfig"
SRC_URI += "file://upstream_to_edison.patch"
do_configure() {
  cp "${WORKDIR}/defconfig" "${B}/.config"
}
do_kernel_configme() {
  cp "${WORKDIR}/defconfig" "${B}/.config"
}
do_patch() {
  cd ${S}
  git am "${WORKDIR}/upstream_to_edison.patch"
}

このなかで分かりにくいのは、SRCREV_machineとSRCREV_meta です。
SRCREV_machineには、Yocto Project内のGitリポジトリにある、3.10.32カーネルのcommit IDです。3.10.32は"61dde96f97bb5b1ed4c11caf9a857d55ad8f6e17"です。
SRCREV_metaは、ここから探すことが出来ます。3.10.32の最も新しいもの(3.10.34に変わる直前)のcommit IDは、"e46e0e44708e23533f8df904cebf23a352e9053a"となります。
またこの中には先ほど作成したパッチを適用するように修正する必要があります。ただし、diffコマンドを用いたパッチですので、「git am 〜」ではなく「git apply 〜」に変更します。
修正は以下のようになります。

FILESEXTRAPATHS_prepend := "${THISDIR}/files:"
COMPATIBLE_MACHINE = "edison"
LINUX_VERSION = "3.10.32"
SRCREV_machine = "61dde96f97bb5b1ed4c11caf9a857d55ad8f6e17"
SRCREV_meta = "e46e0e44708e23533f8df904cebf23a352e9053a"

SRC_URI += "file://defconfig"
SRC_URI += "file://upstream_to_edison.3.10.32.patch"
do_configure() {
  cp "${WORKDIR}/defconfig" "${B}/.config"
}
do_kernel_configme() {
  cp "${WORKDIR}/defconfig" "${B}/.config"
}
do_patch() {
  cd ${S}
  git apply "${WORKDIR}/upstream_to_edison.3.10.32.patch"
}

ここまでくれば、あとはコンパイルです。

もし、bitbakeが使える環境になっていなければedison-srcディレクトリで、以下のように使えるようにしてやります。

$ cd edison-src
$ source poky/oe-init-build-env

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

You can now run 'bitbake '

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'
$

そしてビルドしてやります。

$ bitbake virtual/kernel
...
$ bitbake edison-image
...
$ ../device-software/utils/flash/postBuild.sh

以上で、Edison用の3.10.32カーネルのビルドが出来ました。出来上がったtoFlashディレクトリ内のファイルをEdisonに転送し、Edison上で"reboot ota"で再起動すると、3.10.32カーネルで起動するはずです。


とりあえず、今日はここまで。

Xenomaiパッチの適用については、次回書きますね。


追記:Bluetoothは使えそうですね。