読者です 読者をやめる 読者になる 読者になる

ARMプロセッサでMono 2.4を動かしてみた

最近、マイコン上でもJavaC#を使って効率的に開発できないかなぁ、と思って調べているのですが、その過程でARMプロセッサ上でMonoを動かしてみました。

環境

ターゲットは、アットマークテクノ社のArmadillo-500 FXを使いました。

ここの製品は、日本語のマニュアルが整っているし、開発環境もcoLinuxVMwareなどいくつか用意されているので、開発の敷居は低いのではないかと思います。

今回は開発環境にAtmark Techno Development Environment(ATDE)を利用しました。
これはVMware仮想マシンのイメージで、Linuxに開発環境一式がインストールされているので、ダウンロードしてすぐに使い始めることができます。
Monoのビルドに必要な、pkg-configやglib2もインストール済みです。

ビルド手順

  • 以下は、VMware上での操作になります。
  • まずは、Object not found!からmono-2.4.tar.bz2をダウンロードし、解凍します。
$ tar zxvf mono-2.4.tar.bz2
  • 次に mono-2.4/configure を少し書き換えます。
    • configureの中でコンパイラのバージョンをチェックするために"-V"を利用しているのですが、ARM用のクロスコンパイラでは"-V"オプションが利用できません。confiugreでエラーが発生する部分(3526、4730、7336行目など)の"$ac_compiler -V"を"$ac_compiler --version"に書き換えます。
    • configureの中でモジュールの動作確認をしているようなのですが、クロスコンパイラでビルドされたものを起動しているため、「configure error: cannot run test program while cross compiling」というエラーが発生します。ちょっと無理矢理ですが、configureでエラーが発生する部分(26230、30136行目など)の"$cross_compiling = yes"を"yes"から"no"に書き換えます。
  • 続いてconfigureを実行します。以下は複数行で書いていますが、1行で実行してください。
$ CC=arm-linux-gnu-gcc
  CXX=arm-linux-gnu-g++
  CFLAGS="-I/usr/arm-linux-gnu/include -DARM_FPU_FPA"
  CPPFLAGS="-I/usr/arm-linux-gnu/include -DARM_FPU_FPA"
  ./configure
    --prefix=/home/atmark/arm-mono
    --host=arm-linux-gnu
    --build=i486-linux
    --with-tls=pthread
    --disable-mcs-build
    --with-static_mono=yes
    --without-x
    --with-xen_opt=no
    --with-crosspkgdir=/usr/arm-linux-gnu/lib/pkgconfig/
  • configureで生成された mono-2.4/config.h の MONO_SIZEOF_SUNPATH の定義を 0 から 108 に変更します。(この定数が何なのか、ちゃんと調べてないのですが・・・)
#define MONO_SIZEOF_SUNPATH 108
  • 次にglibのライブラリへのリンクをARM用のものに切り替えます。(本当ならpkg-configでちゃんとパスを設定してくれるはずなんですが、なぜかarm-linux-gnuの方を見てくれません)
$ sudo ln -s /usr/arm-linux-gnu/lib/libglib-2.0.so /usr/lib/libglib-2.0.so
  • 次にmono/mini/jit-icall.cに以下の定義を追加します。(arm-linux-gnu/include/limits.h の中に定義してあるので大丈夫なはずなのですが、こちらもなぜかコンパイル時に見つからないと言われます)
#define ULLONG_MAX 18446744073709551615
  • そしてmakeします。
$make
$make install
  • 続いてクラスライブラリのビルドを行います。クラスライブラリは、クロスコンパイラでビルドする必要はないので、configureの書き換えなどなしに、以下のようにビルドできます。
$ ./configure --prefix=/usr/local --with-tls=pthread
$ make
$ sudo make install
  • 以上でビルドは完了したので、以下のディレクトリをARM側にコピーします。なお、/usr/local/lib/monoは、/home/atmark/arm-mono/lib/monoにコピーしてください。
    • /home/atmark/arm-mono
    • /usr/arm-linux-gnu/lib
    • /usr/local/lib/mono
  • ライブラリのファイルサイズは100MB以上になるので注意してください。Armadillo-500 FXでは1GBのSSDを搭載しているので大丈夫ですが、そういったストレージがない場合は、コンパクトフラッシュを利用したり、LinuxのHDDをマウントしたりするのが良いと思います。

動作確認

  • 以下はARM側での操作になります。
  • 環境変数の設定を行います。
    • PATHに、/home/atmark/arm-mono/bin をコピーしたディレクトリを追加します。
    • LD_LIBRARY_PATH に /usr/arm-linux-gnu/lib をコピーしたディレクトリを設定します。
  • mono -V とすると、monoのバージョン情報が表示されます。
  • 適当にHelloWorld.csなどのプログラムを作成し、mcs HelloWorld.cs でビルドして、mono HelloWorld.exe と実行します。

まとめ

  • ソケット通信やCodeDOMを使った自作のアプリを動かしてみましたが、だいたい動作しました。(たまーに落ちたりするのですが^^;)
  • 無理矢理ビルドを通しているところもあるので、もう少し調査をしようかと思います。
  • 起動はものすごく重いです。アプリが起動するまで30秒くらいかかったりします。
  • 組み込み系でもJavaとか.NETの環境が整って、開発効率が向上するとうれしいですね。

参考ページ