Intel EdisonにXenomaiを入れる(ただしWiFiなし...) − (本題)
前回に続き、EdisonにXenomaiを入れていきます。
Xenomai用のパッチを作成する
まず、コンパイルに必要なEdison用のXenomaiパッチを作成していきます。最初にXenomaiのコードをとってきましょう。以下では、Edison、Linuxのソースコードを展開したディレクトリを基準としています。
$ ls edison-src linux-yocto-3.10-3.10.32.tar.bz2 linux-yocto-3.10-3.10.32 upstream_to_edison.3.10.32.patch linux-yocto-3.10-3.10.32-edison $ git clone git://git.xenomai.org/xenomai-3.git Cloning into 'xenomai-3'... remote: Counting objects: 120758, done. remote: Compressing objects: 100% (20429/20429), done. remote: Total 120758 (delta 98188), reused 119251 (delta 96934) Receiving objects: 100% (120758/120758), 273.37 MiB | 625.00 KiB/s, done. Resolving deltas: 100% (98188/98188), done. Checking connectivity... done. $ ls edison-src linux-yocto-3.10-3.10.32.tar.bz2 linux-yocto-3.10-3.10.32 upstream_to_edison.3.10.32.patch linux-yocto-3.10-3.10.32-edison xenomai-3 $
続いて、元のYocto Projectのカーネル3.10.32に対してXenomaiのパッチを当てます。Xenomaiパッチを当てるにはドキュメントにあるように、スクリプトを実行してやります。パッチを当てたら、分かるようにディレクトリ名を変更しておきましょう。
$ xenomai-3/scripts/prepare-kernel.sh --help usage: prepare-kernel --linux=--ipipe= [--arch= ] [--outpatch= [--filterkvers=y|n] [--filterarch=y|n]] [--forcelink] [--def ault] [--verbose] $ xenomai-3/scripts/prepare-kernel.sh --linux=linux-yocto-3.10-3.10.32 \ checking file arch/x86/Kconfig checking file arch/x86/Kconfig.debug checking file arch/x86/include/asm/apic.h ... checking file mm/mmu_context.c checking file mm/mprotect.c checking file mm/vmalloc.c $ mv linux-yocto-3.10-3.10.32 linux-yocto-3.10-3.10.32-ipipe $ ls edison-src linux-yocto-3.10-3.10.32.tar.bz2 linux-yocto-3.10-3.10.32-edison upstream_to_edison.3.10.32.patch linux-yocto-3.10-3.10.32-ipipe xenomai-3 $今度はXenomaiパッチを当てたカーネルソースコードにEdisonパッチを当ててやります。ここで使用するのは、前回作成した3.10.32用のパッチです。$ cd linux-yocto-3.10-3.10.32-ipipe/ $ patch -p1 < ../upstream_to_edison.3.10.32.patch patching file Documentation/kernel-parameters.txt patching file arch/x86/Kconfig Hunk #1 succeeded at 446 (offset 4 lines). ... patching file kernel/power/process.c patching file kernel/printk.c patching file sound/soc/codecs/sn95031.c $ find . -name "*.rej" ./arch/x86/kernel/apic/io_apic.c.rej $
このとき、ひとつのファイル(arch/x86/kernel/apic/io_apic.c)でパッチ適用失敗となります。これについては、手動で修正してやります。2656行目から以下のように修正します。static struct irq_chip ioapic_chip __read_mostly = { .name = "IO-APIC", .irq_startup = startup_ioapic_irq, .irq_mask = mask_ioapic_irq, .irq_unmask = unmask_ioapic_irq, .irq_ack = ack_apic_edge, .irq_eoi = ack_apic_level, .irq_set_affinity = native_ioapic_set_affinity, .irq_retrigger = ioapic_retrigger_irq, #ifdef CONFIG_IPIPE #ifdef CONFIG_SMP .irq_move = move_xxapic_irq, #endif .irq_hold = hold_ioapic_irq, .irq_release = release_ioapic_irq, #endif };↓↓↓↓↓static struct irq_chip ioapic_chip __read_mostly = { .name = "IO-APIC", .irq_startup = startup_ioapic_irq, .irq_mask = mask_ioapic_irq, .irq_unmask = unmask_ioapic_irq, .irq_ack = ack_apic_edge, .irq_eoi = ack_apic_level, .irq_set_affinity = native_ioapic_set_affinity, .irq_set_wake = ioapic_set_wake, .irq_retrigger = ioapic_retrigger_irq, #ifdef CONFIG_IPIPE #ifdef CONFIG_SMP .irq_move = move_xxapic_irq, #endif .irq_hold = hold_ioapic_irq, .irq_release = release_ioapic_irq, #endif .flags = IRQCHIP_SKIP_SET_WAKE, };修正したら、パッチ適用時に出来た余計なファイルを削除します。Emacsで編集した場合には、編集時のバックアップファイル(arch/x86/kernel/apic/io_apic.c~)も消しましょう。その後パッチを当てたことを忘れないように、ディレクトリ名も変更しておきましょう。$ find . -name "*.rej" -exec rm {} \; $ find . -name "*.orig" -exec rm {} \; $ cd .. $ mv linux-yocto-3.10-3.10.32-ipipe linux-yocto-3.10-3.10.32-ipipe-edison $ ls edison-src linux-yocto-3.10-3.10.32.tar.bz2 linux-yocto-3.10-3.10.32-edison upstream_to_edison.3.10.32.patch linux-yocto-3.10-3.10.32-ipipe-edison xenomai-3 $
これで、Edison用のXenomaiパッチを作ることが出来ます。作成したパッチは前回作成したパッチと同じ場所にコピーしましょう。これでパッチの作成が完了です。$ diff -Narup *-3.10.32-edison *-3.10.32-ipipe-edison > xenomai-3.0-3.10.32.patch $ cp xenomai-3.0-3.10.32.patch edison-src/device-software/meta-edison/recipes-kernel/linux/files/ $コンパイル環境の修正
カーネルのビルド時に作成したXenomaiパッチが適用できるよう、linux-yocto_3.10.bbappendを修正してやります。修正は以下の赤い部分を追加するだけです。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" SRC_URI += "file://xenomai-3.0-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" git apply "${WORKDIR}/xenomai-3.0-3.10.32.patch" }次に、WiFi関係を修正します。 EdisonのWiFiおよびBluetoothのカーネルモジュールは、カーネルとは別にedison-src/broadcom_cwsディレクトリに用意されています。カーネルのビルド後、これらのモジュールをビルドして組み込んでいます。 現状、WiFiモジュールはXenomaiカーネル上でそのままでは動作しないため、今回ははずします。 なお、Bluetoothモジュールはかろうじて動作はしますが、不安定です。 WiFiモジュールのビルドをしないようにするには、edison-src/device-software/meta-edison-distro/recipes-core/imagesディレクトリにあるedison-image.bbを修正します。 81行目から以下のように赤い部分をコメントアウトします。Bluetoothモジュールもビルドしない場合はbcm43340-btとbluetooth-rfkill-eventの行もコメントアウトします。 (ちなみに、Edison起動後にWiFiを使わなければ問題ないので、この修正は必須ではありません。)# Wifi firmware #IMAGE_INSTALL += "bcm43340-fw" # Bluetooth Firmware patch for 43340 and its patch utility IMAGE_INSTALL += "bcm43340-bt" # service daemon that listens to rfkill events and trigger FW patch download IMAGE_INSTALL += "bluetooth-rfkill-event" # Wifi driver built as a kernel module #IMAGE_INSTALL += "bcm43340-mod"出来上がったEdisonのイメージをEdisonに書き込んだ時には、次の起動時に一旦全体の設定が行われます。その時WiFiの設定も行われ、その時にモジュールが組み込まれます。Xenomaiを組み込んだカーネルではこのときハングしてしまいますので、以下ではこの設定をしないように修正します。 Edisonへのイメージの更新方法には2通りあり、USB経由でファイルをコピーして"reboot ota"する方法と、dfu-utilを使う方法があります。それぞれ動作するスクリプトが異なり、 前者はedison-src/device-software/meta-edison-distro/recipes-core/ota-update/files/ota-update.sh 後者はedison-src/device-software/meta-edison-distro/recipes-core/first-install/files/first-install.sh となります。 それぞれファイルの最後から9行目付近の「# Setup Access Point SSID and passphrase」以下2行をコメントアウトします。# Setup Access Point SSID and passphrase #setup_ap_ssid_and_passphrase #fi_assert $? "Generating Wifi Access Point SSID and passphrase"これでひとまず修正は完了です。カーネルとイメージのビルド
あとはカーネルをビルドし、Edisonのイメージを構築します。 念のため、カーネルをcleanしてからビルドします。$ cd edison-src/build $ bitbake virtual/kernel -c clean $ bitbake virtual/kernelこのとき、ビルドエラーが発生します。これは使用したカーネルの設定ファイル(.config)が元のEdisonオリジナルのものであり、この中にはXenomai関連の設定項目がないためです(内部的にmake oldconfigを行い、新しい項目では入力を求めているため)。 ここでは明示的にカーネルの設定を行います。$ bitbake virtual/kernel -c menuconfigこの中では、以下の設定を行います。さて、後はもう一度カーネルのビルドとEdisonイメージの作成です。
- [General setup]--->[Local version - append to kernel release]
- "-poky-edison"となってますので、Xenomaiだと分かるように設定しましょう。たとえば"-poky-edison-ipipe"など。
- [Xenomai/cobalt]
- 有効にします。
- [Processor type and features]--->[Interrupt pipeline]
- 有効にします。([Xenomi/cobalt]が有効だと、ここもすでに有効になっています。)
- [Power management and ACPI options]--->[CPU Frequency scaling]--->[CPU Frequency scaling]
- 無効にします。
- [Power management and ACPI options]--->[CPU idle PM support]
- 無効にします。
- [Device Drivers]--->[Network device support]--->[Wireless LAN]
- 無効にします。(WiFiモジュールのビルドのところと同様、Xenomai上で使用しなければ無効にしなくてもいいけど…)
$ bitbake virtual/kernel ... $ bitbake edison-image ... $ ../device-software/utils/flash/postBuild.sh以上で、Edison用のXenomaiカーネルのビルドが出来ました。出来上がったtoFlashディレクトリ内のファイルをEdisonに転送し、Edison上で"reboot ota"で再起動すると、Xenomaiカーネルで起動するはずです。さいごに
現状、以下の課題が残っています。いつになるか分かりませんが、少しずつやっていこうと思います。 何か情報がありましたら、教えていただけるとありがたいです。 ではでは。
- Xenomai用のプログラムを作成するためのビルド環境を整える
- Bluetoothモジュールが不安定なので、修正が必要。
- WiFiモジュールを動作できるよう、修正が必要。