2010年09月02日
Androidで他のARM Linuxのバイナリを動かす
実はARM Ubuntu 10.04の実行ファイルのバイナリをAndroidにコピーしたらそのまま動きました。ただし必要なファイルを全てコピーする必要があります。
(ARM Ubuntu 10.04はarmv7用に最適化されています。今回AndroidはKZM-CA9-01ボードで動かしています。)
bashをコピーして動かす
Ubuntuの/bin/bashはダイナミックリンクされています。このファイルを起動するためには以下のダイナミックリンクライブラリが必要です。
ARMのUbuntuで以下を実行します。
user@arm-lucid:~$ ldd /bin/bash libncurses.so.5 => /lib/libncurses.so.5 (0x40006000) libdl.so.2 => /lib/libdl.so.2 (0x40039000) libgcc_s.so.1 => /lib/libgcc_s.so.1 (0x40045000) libc.so.6 => /lib/libc.so.6 (0x40057000) /lib/ld-linux.so.3 (0x2a000000) user@arm-lucid:~$
これらのファイルを全てコピーします。ディレクトリを変えずにそのままコピーします。
私の場合はAndroidもUbuntuもどちらもルートファイルシステムごとNFSマウントして動かしています。
Androidのルートは /export/android/root
Ubuntuのルートは /export/ubuntu_lucid_armel/root
NFSサーバ側で以下のようにコピーしました。
$ cd /export/android/root $ sudo mkdir lib $ cd lib $ sudo cp ../../../ubuntu_lucid_armel/root/lib/ld-linux.so.3 . $ sudo cp ../../../ubuntu_lucid_armel/root/lib/libc.so.6 . $ sudo cp ../../../ubuntu_lucid_armel/root/lib/libgcc_s.so.1 . $ sudo cp ../../../ubuntu_lucid_armel/root/lib/libdl.so.2 . $ sudo cp ../../../ubuntu_lucid_armel/root/lib/libncurses.so.5 . $ cd .. $ sudo mkdir bin $ cd bin $ sudo cp ../../../ubuntu_lucid_armel/root/bin/bash .
Androidを起動して、adb shellのプロンプトからbashを動かしてみます。
# /bin/bash bash-4.1#
あっさり動きました。
rubyをコピーして動かす。
まず、ARM Ubuntu上でrubyをインストールします。
arm-lucid:~$ sudo apt-get install ruby
そして、さっきと同様に必要なダイナミックリンクライブラリを確認します。
arm-lucid:~$ which ruby /usr/bin/ruby arm-lucid:~$ ldd /usr/bin/ruby libruby1.8.so.1.8 => /usr/lib/libruby1.8.so.1.8 (0x40006000) libpthread.so.0 => /lib/libpthread.so.0 (0x400b5000) librt.so.1 => /lib/librt.so.1 (0x400d2000) libdl.so.2 => /lib/libdl.so.2 (0x400e0000) libcrypt.so.1 => /lib/libcrypt.so.1 (0x400eb000) libm.so.6 => /lib/libm.so.6 (0x40122000) libc.so.6 => /lib/libc.so.6 (0x4018e000) libgcc_s.so.1 => /lib/libgcc_s.so.1 (0x40278000) /lib/ld-linux.so.3 (0x2a000000) arm-lucid:~$
これらのファイルと /usr/bin/ruby*と /usr/lib/rubyの下の全てのファイルをAndroidにコピーします。
Android上でrubyを実行してみます。
bash-4.1# /usr/bin/ruby --version ruby 1.8.7 (2010-01-10 patchlevel 249) [arm-linux-eabi] bash-4.1#
前回と同様に簡単なHTTPサーバを動かしてみます。
先頭の一行だけ変更しました。
#!/usr/bin/ruby require 'webrick' include WEBrick s = HTTPServer.new( :Port => 8001, # :DocumentRoot => File.join(Dir::pwd, "public_html") :DocumentRoot => File.join("/data/local/exp", "public_html") ) trap("INT"){ s.shutdown } s.start
Android上で実行します。
# ./httpserver2.rb [1970-01-01 04:35:37] INFO WEBrick 1.3.1 [1970-01-01 04:35:37] INFO ruby 1.8.7 (2010-01-10) [arm-linux-eabi] [1970-01-01 04:35:37] INFO WEBrick::HTTPServer#start: pid=311 port=8001 192.168.1.26 - - [01/Jan/1970:04:36:09 UTC] "GET / HTTP/1.1" 304 0 - -> /
動きました。
なぜ問題なく動くのか
ARM UbuntuとAndroidはどちらも同じABIです。(EABI)
Androidのディレクトリ構成は通常のLinuxとは大きく違っていて、/bin, /lib, /usr のディレクトリがありません。
そのため、ここで紹介したように必要なダイナミックリンクライブラリを全てコピーしてきても、既存のものと衝突することがありません。
実行ファイルの中には/etcディレクトリ以下のファイルが必要なものもあります。その場合、もしかしたら既存のAndroidのファイルと衝突する可能性があるので注意する必要があります。その場合でもchrootを使えば回避できそうです。