linux on android

# Android端末でLinuxを使いたい。

Android端末に ubuntu12.04 をインストールしたときの備忘録です。

これは、GooglePlayに登録されているAndroidアプリ「ubuntu-installer for Android」のインストール方法を記したものです。

#注意事項とか

Android端末はroot権限が必要です。

Android端末側にandroid-vnc-viewerというアプリを入れることで、XやGnomeを起動させることも出来ますが、
実用的ではありませんので、この稿では、主にCUIのLinuxとして使用する前提で書いています。

#ubuntu12.04の入手

実はGooglePlayからではなく、パソコンを使ってsourceforgeから取得します。

http://sourceforge.net/projects/linuxonandroid/files/Ubuntu/12.04/

ここに、

Full

Small

Core

と、BootScriptがあります。
Coreパッケージは必要最低限のCUIのみで、GUIが使えません。
が、結論から言って、VNCを経由してのGUI操作は非常にストレスが溜まりますし、Androidのメモリー512MBではGNOMEを動かすほどの余裕もありませんので、ここはCoreパッケージを選択します。

# 走らせ方

ubuntu.imgとbootscript.shをsd-card等の同じディレクトリに置いて、

 # sh bootscript.sh

という風にスクリプトをただ走らせるだけです。 
http://sourceforge.net/projects/linuxonandroid/files/ にあるbootscript.shを使用します。

実行すると、そのままubuntuの中のshellになります。

apt-getも普通に使えます。
試しにjedというテキストエディタをaptでinstallして起動してみました。合格です。

# gccを使いたいなら、
 # apt-get update
 # apt-get install build-essential


### ここからは、端末の機種依存の情報になりますので、機種が違う場合はそれに合わせて読み替えてください。

# Linuxから外部のSD Cardを(Ext3で)mountしたい。

まず、あらかじめext3でフォーマット済のSD Cardを用意しておきます。Windows上のubuntu仮想マシンなどから、

 # fdisk /dev/sdb
  （SD Cardのサイズに等しいext3のパーティションを１個作成する）
 # mkfs.ext3 /dev/sdb1
 # sync
で作れます。

次に、AndroidのTerminal(ubuntuではないもの)をもう一枚起動して、

 $ su
 # cd /dev/block/vold
 # ls
 179:0        179:1         93:64        93:65
というふうなブロックデバイスが存在していることを確認します。

これらは、普通のLinuxでは /dev/直下にある
 sdb             sdb1          .....
と同じ働きをしているようです。試しに

 # fdisk 179:0
とやってみるとSD Cardのパーティションが覗けるはずです。

SD Cardをいろいろ抜き差ししていると、番号がどんどん増えていくので、どれが本物かの見極めは難しくなりますので、Androidを再起動して初期状態で見たほうが良いです。

では、こんどは、ubuntu上でこのデバイスノードを用意してみましょう。

 ubuntuが起動しているほうのAndroid Terminalから、
 
  # cd /dev 
  # mknod sdex  b 179  0
  # mknod sdex1 b 179  1

これで、 普通のsdb sdb1 のかわりのブロックデバイス sdex sdex1 が作れました。

マウントしてみます。

 # cd /mnt 
 # mkdir sdext
 # mount  /dev/sdex1   /mnt/sdext 
 # ls /mnt/sdext

#Ubuntuに日本語ロケールを追加したい
 # cd /var/lib/locales/supported.d
ここの local というテキストファイルを編集します。内容は

 en_GB.UTF-8 UTF-8
 ja_JP.UTF-8 UTF-8
 ja_JP.EUC-JP EUC-JP

の３行です。

同じく、jaというファイルを作成して編集します。内容は

 ja_JP.UTF-8 UTF-8
 ja_JP.EUC-JP EUC-JP

の2行です。

そして、

 # locale-gen
で作成されます。

利用するときは .bash_profile などに
 export LANG=ja_JP.UTF-8
のように書きます。

#UbuntuのタイムゾーンをUTCからJSTにする。
 # cp /usr/share/zoneinfo/Japan   /etc/localtime

#Ubuntuのユーザーを新規に作成する
 # adduser ユーザー名

ついでにsudo出来るようにしておきます。

 # vi /etc/sudoers
 root=ALL(ALL) ALL の後ろに

ユーザー名=ALL(ALL) ALL
を追加しておきます。

あとは、そのユーザーでssh-keygenして、 ~/.ssh/ にauthorized_keysを置いたりすれば外部のLinuxからsshで操作できるようになります。

#Ubuntuのユーザー権限でpingやtelnet出来ない

Android用にビルドされたLinuxカーネルでは tcp socketのパーミッションがユーザーに開放されていないので、上記の問題が発生します。これは、自分のユーザー名を /etc/groupの

 android_inet：x：3003:ubuntu

のようなgroupに連ねて追加することでなんとなく使えるようになるようです。（微妙にsｓｈだけだめなんですけど・・・外のLinuxにsshするとkeyが使えないエラーが出るようです）

 android_inet：x：3003:ubuntu,自分username
最悪 sudo ssh すれば外部に接続できます。

#Ubuntuのユーザー権限でrsyncやssh出来ない

これは.ssh/known_hostsの問題ではなく、 /dev/tty の権限がrootに限定されているかららしいです。

 ls -l /dev/tty
 crw------- 1 root root 5, 0 12月 28 10:13 /dev/tty

なので、
 # chmod go+w /dev/tty
することで、root権限でなくてもssh出来るようになります。

 

#IPアドレスをDHCPでなく固定化したい

ubuntuでないほうのAndroid Terminalから操作します。

 $ su
 # netcfg
 # ifconfig eth0 192.168.1.100 netmask 255.255.255.0
 # route add default gw 192.168.1.1 dev eth0  
 # setprop net.dns1 8.8.8.8
 # netcfg

ifconfigとかrouteコマンドはどうやらサブセットなのであまり融通が利かないようだ。
起動時に設定したいならば、 /init.sun4i.rc ファイルの on boot のどこかに追記しておくとそうなるのではないかと思います。

#UbuntuをWebサーバーにする
これは普通にapt-getで可能です。

 # apt-get update 
 # apt-get install apache2 php5
 # vi /etc/apache2/site-available/default

（Apacheの設定とか挙動を調整する）

 # service  apache2 start

#Ubuntuでテキストエディタを使いたい。
emacsでも良いのですが、軽いエディタ jedがお勧めです。

 # apt-get install jed
 $ jed file.txt

#Ubuntu起動バッチの在処とか置き場。

以下の説明はAndroidの特定の機種に強く依存した記述になっておりますので参考程度に留めて置いてください。

AndroidのTerminalを起動した直後の実行パスは、以下のようになっていました。

 $ echo $PATH
 /data/local/bin:/system/bin:/system/xbin

なので、起動バッチはAndroid:/data/local/bin/ に置くことにします。

ubuntuの1.5GBのimageなどは Android:/sdcard/ubuntu/ に置きました。

ubuntuが起動すると、まず最初に ubuntu:/root/init.sh が実行されますので、

ubuntuで初期化したいものがあれば、/root/ にシェルスクリプトを置いて、手動実行するか、init.sh から呼び出すようにします。


#もしroot権限のないAndroid端末でLinuxコマンドライン環境を使いたいのでアレバ・・・

別稿で説明しますが、KBOX2というfake-chrootなLinuxシェル環境があります。
http://kevinboone.net/kbox2.html
KBOX2はいわゆるBusyBox的なSmall Linux環境を libfakechrootという見せ掛けのchrootラッパーに載せたものらしいです。（これは古い情報です。現在はお勧めしません。下の追記を見てください）
[KBOX2にjed移植記事](http://qiita.com/iruka/items/7a803eed6deb70a2c38e)
---この稿は、以前wordpressに投稿したものを加筆修正いたしました。

----

# 2017年11月時点での追記：

ここまで書いていて、こう言うのもなんですけど・・・。

Android端末にLinux CUI環境が欲しいなら、現時点でお勧めは
GNURoot Debian一択です。（名前が紛らわしくてRoot権限が必要なDebianかと思って敬遠しておりました）

* Google Playから一発導入出来ます。
* Root 権限は要りません。
* apt-getを使用して、好きなソフトを思う存分導入することが出来ます。（自家ビルドは全く不要）
* CUI/GUIともサポート。

動作原理は proot を使用しているそうです。
お勧めです。

# 更に追記します：

GNURoot Debian に代わって、今ではUserLAndというのがあるそうです。
root権限不要です。
GooglePlayストアで配布されています。
(提供はUserLAnd Technologies, LLC)

同じくprootです。

# 最後に一言

Termuxはいいぞ。

prootは動作が遅いという欠点があります。

https://play.google.com/store/apps/details?id=com.termux&hl=ja

TermuxというAndroidアプリはBusyBoxなAndroid上のnon chroot Linuxコンソールです。
普通にsshやpingやtracerouteといったネットワークメンテンスをリモートから行いたい、といった用途であれば、これで十分ではないでしょうか。

Termuxの魅力は、動作速度だけではありません。
生のAndroid上のLinuxが体験できますし、それなりにパッケージも揃っていますし、prootを使用してArchLinuxやUbuntuのパッケージを動かすことさえできます。

こうして、最終的にはTermuxにたどり着きました。

別記事
- [DockerでTermuxのパッケージビルドを試す](https://qiita.com/iruka/items/8b7a50880139b60012cf)