2010年09月02日

Androidで他のARM Linuxのバイナリを動かす

前回はAndroid用にrubyをビルドする方法を紹介しましたが、実はビルドしなくても済む方法もあります。今回はそれを紹介します。



実は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を使えば回避できそうです。



トラックバックURL

トラックバック一覧

1. KZM-CA9-01ボードのリンク集  [ KMC Staff Blog ]   2010年09月16日 10:44
4コアのCortex-A9のKZM-CA9-01ボードを使って実験したことを書いたページをまとめてみました。

コメントする

名前
 
  絵文字
 
 
記事検索
最新コメント
アクセスカウンター
  • 今日:
  • 昨日:
  • 累計:

QRコード
QRコード