Debian noroot 環境の動作原理について

# はじめに

[Debian noroot][DBNR] とは、 [Android OS][ANDR] 上において root 権限を取ることなく [Debian 環境][DEBI]を構築するためのアプリケーションです。
CPU の性能とメモリ容量が潤沢にある Android 端末であれば、 [Debian noroot][DBNR] の導入によって Android 端末上で非常に軽快な [Debian 環境][DEBI]を実現することができます。

[Debian noroot 環境][DBNR]は [Android OS][ANDR] 上で動作する X Windows System サーバアプリである [Xserver XSDL][XSDL] と、 root 権限を取得すること無く chroot 環境の構築と ``mount --bind`` の実現等を行うソフトウェアである [proot][PROT] を用いて実現されています。

また、 [Android OS][ANDR] から [Debian noroot 環境][DBNR]を起動するまでの過程を [Debian noroot アプリ][DBNR]及び [Xserver XSDL アプリ][XSDL]のソースコード等を参照して調査した結果、最初に [Xserver XSDL サーバ][XSDL]が起動された後、 [Android OS][ANDR] ネイティブ環境下において、 [Debian noroot 環境][DBNR]において使用する chroot 環境を構築するシェルスクリプトである proot.sh が実行され、続いて、 proot.sh シェルスクリプトで構築した chroot 環境下において、デスクトップマネージャの起動等を行うシェルスクリプトである startx.sh が実行されることにより、 [Debian noroot 環境][DBNR]が起動されることが判明しました。

本稿では、 [Debian noroot 環境][DBNR]を実現するソフトウェア及び [Debian noroot 環境][DBNR]の一連の動作過程を通じて、 [Debian noroot 環境][DBNR]の動作原理について記述します。

本稿では最初に、 "[Debian noroot 環境に関連する各種ソフトウェアの概要][CHAP01]" の章において、 [Debian noroot 環境][DBNR]を実現するために使用されている各種ソフトウェアに関する概要について述べます。

次に "[Debian noroot 環境の起動過程][CHAP02]" の章において、 [Android OS][ANDR] 上より [Debian noroot アプリ][DBNR]を起動してから、 [Debian noroot 環境][DBNR]上のウィンドウマネージャが起動されるまでの一連の起動過程について述べます。

最後に、 "[結論][CHAP03]" の章において、本稿の結論について述べます。

# Debian noroot 環境に関連する各種ソフトウェアの概要

本章では、 [Debian noroot 環境][DBNR]を実現するために使用されているソフトウェアである [Xserver XSDL][XSDL] 及び [proot][PROT] の概要について述べます。

本章では最初に、 "[Xserver XSDL について][SEC0101]" の節において、 [Android OS][ANDR] 上の X Windows System サーバアプリケーションである [Xserver XSDL][XSDL] の概要について述べます。
次に、 "[proot について][SEC0102]" の節において、 [Android OS][ANDR] 及び Linux をカーネルとする各種ディストリビューションにおいて、 root 権限を取ること無く chroot 環境の構築と ```mount --bind``` の実現等を行うソフトウェアである [proot][PROT] の概要について述べます。

## Xserver XSDL について

[Xserver XSDL][XSDL] とは、 [Debian noroot アプリ][DBNR]の開発者である [pelya 氏][PELY]によって開発された [Android OS][ANDR] 上において動作する X Windows System のサーバアプリケーションです。

[Xserver XSDL][XSDL] は、 X Windows System の完全な互換性を持つ実装であるので、 [X.Org][XORG] の様な他の UNIX 互換 OS で動作する X Windows System サーバプログラムと同様に、リモートの Linux PC 端末や [Xserver XSDL アプリ][XSDL]がインストールされている [Android OS][ANDR] 端末自身等で動作する X Windows System クライアントプログラムの GUI を画面上に表示させることが可能です。

[Xserver XSDL][XSDL] は、 [Android OS][ANDR] 上に移植された画像描画や音声再生の API を持つマルチメディアライブラリである [SDL][LSDL] を使用して実装されています。

ここで、 [Android OS][ANDR] 端末より [Xserver XSDL アプリ][XSDL]を起動すると、以下の画像のように、 [Xserver XSDL アプリ][XSDL]の起動画面が表示されます。

![(Xserver XSDL...)][IMG1]

次に、以下の画像のように画面の解像度等の変更を促す画面が表示されます。ここで解像度等を変更する必要が無ければ、  3 秒後に X Windows System サーバの画面が自動的に表示されます。

![(Tap the screen change...)][IMG2]

最後に、以下の画像のような X Windows System サーバの画面が表示されます。

![(Launch these commands on your Linux PC...)][IMG3]

ここで [Android OS][ANDR] 端末に上記の画面が表示されている状態から、リモートで動作する Linux PC 端末上で以下のコマンドを実行すると、上記の画像で示した X Windows system サーバ画面上に X Windows system で動作するターミナルエミュレータである [xterm][XTRM] が表示されます。

```shell-session
 $ env DISPLAY=192.168.20.33:0 xterm
```

また、[Android OS][ANDR] 端末の別のアプリケーション上に chroot 環境で動作する Linux ディストリビューションが構築されている場合、 Linux ディストリビューション上から以下のコマンドを実行すると、上記の画像で示した X Windows system サーバ画面上に、軽量ウィンドウマネージャである twm が動作します。

```shell-session
 $ env DISPLAY=:0 twm
```

なお本稿では、以降特に断りのない限り、 [Xserver XSDL アプリ][XSDL]によって起動する X Windows system サーバを "[Xserver XSDL サーバ][XSDL]" と記述します。

## proot について

[proot][PROT] とは、 [Android OS][ANDR] 及び Linux をカーネルとする各種ディストリビューションにおいて、 root 権限を取ること無く chroot 環境や ```mount --bind``` コマンドに基づくディレクトリのバインド及び [QEMU][QEMU] のユーザモードを利用した ```binfmt_misc``` を擬似的に実現するプログラムです。

[proot][PROT] は、 chroot 環境等の実現に、プロセスの監視とシステムコールのトレース等を行うための Linux のシステムコールである [```ptrace(2)```][PTRC] を使用しています。

[proot][PROT] は、 [proot][PROT] の子プロセスの実行中において、ファイルのアクセス関連のシステムコールが発生すると、 [```ptrace(2)```][PTRC] を用いてこれらのシステムコームをフックします。そして、ファイルのアクセス先のパス名を適切なものに書き換えることにより、擬似的な chroot 環境等の実現を行います。

ここで、 ```proot``` コマンドに ```-h``` オプションをつけて起動すると、以下のようなヘルプドキュメントが表示されます。

```shell-session
 $ proot -h
proot v5.0.0-24-gf393b4da-dirty: chroot, mount --bind, and binfmt_misc without privilege/setup.

Usage:
  proot [option] ... [command]


Regular options:
  -r *path*, --rootfs=*path*
	Use *path* as the new guest root file-system, default is /.
...(略)...
  -b *path*, --bind=*path*, -m *path*, --mount=*path*
	Make the content of *path* accessible in the guest rootfs.
...(略)...
  -w *path*, --pwd=*path*, --cwd=*path*
	Set the initial working directory to *path*.
...(略)...

 $
```

以上のヘルプドキュメントの内容より、 ```proot``` コマンドが取る主なコマンドオプションは以下の通りであることが判ります。

- ```-r``` … -r オプションで示されたパス以下をルートディレクトリとして chroot 環境を構築する。
- ```-b``` … -b オプションで示されたパス以下を chroot 環境のディレクトリにバインドし、 chroot 環境から参照できるようにする。
- ```-w``` … chroot 環境の構築後のカレントディレクトリを指定する。
- ```[command]``` … chroot 環境の構築後の実行コマンドを指定する。

例えば、ディレクトリ ```/mnt/img``` 以下をルートディレクトリとして chroot 環境を構築し、 bash シェルコマンドを実行する場合は以下のコマンドを起動します。

```shell-session
 $ proot -r /mnt/img /bin/bash
 user@localhost:~$
```

また、 ```/mnt/img``` 以下をルートディレクトリとして chroot 環境を構築し、 chroot 環境の構築後はカレントディレクトリを ```/root``` に移動する場合は以下のコマンドを起動します。

```shell-session
 $ proot -r /mnt/img -w /root /bin/bash
 user@localhost:/root$ pwd
 /root
 user@localhost:/root$
```

そして、 ```/mnt/img``` 以下をルートディレクトリとして chroot 環境を構築し、ディレクトリ ```/dev``` 及び ```/proc``` を chroot 環境のルートディレクトリにバインドして chroot 環境から参照できるようにする場合は以下のコマンドを実行します。

```shell-session
 $ proot -r /mnt/img -b /dev -b /proc /bin/bash
 user@localhost:~$ ls /dev
...
shmem               ptyp5  ptyyf                ttya5    ttytf
binder              ptyp6  ptyz0                ttya6    ttyu0
block               ptyp7  ptyz1                ttya7    ttyu1
...
 user@localhost:~$ 
```

以上のように、 ```proot``` コマンドを用いることにより、 [Android OS][ANDR] 及び Linux をカーネルとする各種ディストリビューションにおいて root 権限を取得すること無く、 ```chroot``` コマンド及び ```mount --bind``` コマンドに基づいた chroot 環境を擬似的に構築することが可能になります。

# Debian noroot 環境の起動過程

本章では、 [Android OS][ANDR] 上より [Debian noroot アプリ][DBNR]を起動してから、 [Debian noroot 環境][DBNR]に関する各種初期化を行い、 [Debian noroot 環境][DBNR]上のウィンドウマネージャが起動されるまでの一連の起動過程について述べます。

本章では最初に、 "[Xserver XSDL サーバの起動][SEC0201]" の節において、 [Android OS][ANDR] 上からの [Debian noroot アプリ][DBNR]の起動時における [Xserver XSDL サーバ][XSDL]の起動過程について述べます。

次に、 "[proot.sh スクリプトの実行][SEC0202]" の節において、 [Android OS][ANDR] ネイティブ環境上から [Debian noroot 環境][DBNR]において使用する各種環境設定等と [Debian noroot 環境][DBNR]の起動のための chroot 環境の構築を行うシェルスクリプトである ```proot.sh``` の実行過程について述べます。

最後に、 "[startx.sh スクリプトの実行][SEC0203]" の節において、 proot.sh スクリプトにおいて構築された chroot 環境上から、 [Debian noroot 環境][DBNR]において使用するデスクトップマネージャを起動するためのシェルスクリプトである ```startx.sh``` の実行過程について述べます。

## Xserver XSDL サーバの起動

本節では、 [Debian noroot アプリ][DBNR]の起動時における [Xserver XSDL サーバ][XSDL]の起動コマンドラインの解析を通じて、 [Xserver XSDL サーバ][XSDL]の一連の起動過程について述べます。

本節では最初に、 "[Xserver XSDL サーバの起動コマンドラインを表示する][SUBSEC020101]" の項において、[Android OS][ANDR] より [Debian noroot アプリ][DBNR]を起動した時に [Xserver XSDL サーバ][XSDL]の起動コマンドラインを表示させる手法について述べます。

次に、 "[Xserver XSDL サーバの起動コマンドラインの引数の概要][SUBSEC020102]" の項において、 Debian noroot のソースコード等の解析等と通じて、 [Xserver XSDL サーバ][XSDL]の起動コマンドラインの取るオプション及び引数の概要について述べます。

最後に、 "[Xserver XSDL サーバの起動過程][SUBSEC020103]" の項において、 [Android OS][ANDR] から [Debian noroot アプリ][DBNR]を起動した時の [Xserver XSDL サーバ][XSDL]の一連の起動過程について述べます。

### Xserver XSDL サーバの起動コマンドラインを表示する

最初に [Android OS][ANDR] より [Debian noroot アプリ][DBNR]を起動すると、以下の画像のように [Debian noroot アプリ][DBNR]の起動画面が表示されます。

![(Debian noroot...)][IMG4]

この状態から、**[Debian noroot アプリ][DBNR]の起動画面が表示された直後に画面上部の "Change device config" ボタンをクリックすると、**以下の画像のような "Device configuration" なるタイトルのメニューが表示されます。

なお、 "Device configurtion" メニューから、 [Debian noroot 環境][DBNR]において使用する [Xserver XSDL サーバ][XSDL]に関する各種設定を行うことが出来ます。

![(Device configuration)][IMG5]

次に、この状態から **"Device Configuration" メニューより "Data installation location" を選択すると、**以下の画像のように "Data installation location" メニューが表示されます。

![(Data installation location)][IMG6]

そして、この状態から **"Data install location" メニューより "Specify directory" を選択すると、**以下の画像のように "Specify directory" メニューが表示され、ディレクトリの変更を促されますが、**このまま何もせずに "OK" ボタンを押します。**

![(Specify directory)][IMG7]

すると、以下の画像のように **"Specify command line parameters" メニューとコマンドラインが表示されます。**

![(Specify command line parameter)][IMG8]

### Xserver XSDL サーバの起動コマンドラインの引数の概要

ここで、 [Debian noroot アプリのソースコード][SRC0]より、 "Specify command line parameters" メニューが実装されている箇所を調査すると、 "Specify command line parameters" メニューの実装は [CommandlineConfig クラス][SRC1]に存在し、 "Specify command line parameters" メニューにおいて設定されるコマンドラインは [Globals クラスのメンバ変数 Globals.CommandLine][SRC2] に格納されることが判ります。

また、 Globals.CommandLine の値は、[DemoRenderer クラスのメソッド nativeInit()][SRC3] を介して [Android OS ネイティブ環境上の関数 main()][SRC4] に渡され、この関数より android_main() 関数を介して [Xserver XSDL サーバ][XSDL]のコマンドである ```XSDL``` が起動されているので、 "Specify command line parameters" メニューで設定されるコマンドラインが [Xserver XSDL サーバ][XSDL]のコマンド ```XSDL``` に渡されるオプション及び引数であることが判ります。

ここで、 [Debian noroot アプリ][DBNR]における関数 main() 及び [Xserver XSDL サーバのコマンド XSDL のソースコード][SRC5]を参照すると、 "Specify command line parameters" メニューのコマンドラインが取る主なオプションの意味は以下の通りであると判ります。

- ```-nohelp``` … [Xserver XSDL サーバ][XSDL]画面起動後にヘルプ画面を表示せず、全体を黒い画面のままにする。
- ```-screenbuttons``` … [Xserver XSDL サーバ][XSDL]画面上に "Ctrl", "Shift", "Alt" キーの働きをするボタンを表示する。
- ```-warndiskspacemb [n]``` … [Debian noroot 環境][DBNR]の最初の起動時において、ストレージ領域の残りが \[n\] MB 以下の状態ならば警告を表示する。
- ```-exec``` … ```-exec``` オプション以降の引数を [Xserver XSDL サーバ][XSDL]の子プロセスとして実行する。

また、 [Debian noroot アプリ][DBNR]のソースコードより、 "Data installation location" メニュー及び "Specify directory" メニューが実装されている箇所を調査すると、 "Data installation location" メニュー及び "Specify directory" メニューの設定値が [Globals クラスのメンバ変数 Globals.DataDir][SRC6] に格納されているが判ります。

上記のことと、[Settings クラスの setEnvVars() メソッドの内容][SRC7]から、環境変数 ```UNSECURE_STORAGE_DIR, SECURE_STORAGE_DIR``` の値はそれぞれ、 Globals クラスのメンバ変数 Globals.DataDir の値 (通常は ```/sdcard/Android/data/com.cuntubuntu/files```) 及び [Debian noroot アプリ][DBNR]内データの永続化領域の絶対パス (通常は ```/data/data/com.cuntubuntu/files```) であることも判ります。

### Xserver XSDL サーバの起動過程

以上のことより、 [Android OS][ANDR] 上から [Debian noroot アプリ][DBNR]を起動すると、 [Xserver XSDL サーバ][XSDL]のヘルプ画面の表示を抑止し、 [Xserver XSDL サーバ][XSDL]の画面上に "Ctrl", "Shift", "Alt" キーの働きをするボタンを表示した状態で [Xserver XSDL サーバ][XSDL]を起動することが判りました。

そして、 [Xserver XSDL サーバ][XSDL]を起動した後は、 [Xserver XSDL サーバ][XSDL]の画面中央に "Loading Please wait This may take up to one minute." と書かれた画像を表示し、最後に、 [Android OS][ANDR] のネイティブ環境上において、シェルスクリプト ```/data/data/com.cuntubuntu/files/img/proot.sh``` を ```./startx.sh``` を引数にして実行する事が判りました。

## proot.sh スクリプトの実行

本節では、 [Android OS][ANDR] のネイティブ環境において、 [Debian noroot 環境][DBNR]上での各種環境の初期設定及び [Debian noroot 環境][DBNR]の起動のための chroot 環境の構築を行うシェルスクリプトである ```proot.sh``` の一連の実行過程について述べます。

[前節][SEC0201]の "[Xserver XSDL サーバの起動過程][SUBSEC020103]" の項において述べたとおり、シェルスクリプト proot.sh の実体は、 ```/data/data/com.cuntubuntu/files/img/proot.sh``` に存在し、 [Debian noroot 環境][DBNR]上においては、 ```/proot.sh``` に存在しています。ここで、 ```/proot.sh``` の内容は以下の通りです。

```sh:/proot.sh
#!/system/bin/sh

case x$SDCARD in x ) SDCARD=/sdcard;; esac

case x$SECURE_STORAGE_DIR in x ) echo > /dev/null;; * ) cd $SECURE_STORAGE_DIR/img;; esac

case x$SDCARD in x ) export SDCARD=$EXTERNAL_STORAGE;; esac

SDCARD=`../busybox realpath $SDCARD`
STORAGE="-b $SDCARD"
for F in 0 1 2 3 4 5 6 7 8 9; do
	DIR=`eval echo \\$UNSECURE_STORAGE_DIR_$F`
	case x$DIR in x ) echo > /dev/null;; * ) STORAGE="$STORAGE -b $DIR" ; mkdir -p $DIR ;; esac
done
echo "STORAGE $STORAGE"

export HOME=/home/$USER
export SHELL=/bin/bash
export LD_LIBRARY_PATH=
# Java doesn't work in PRoot when started from /usr/bin/java symlink, so we have to put a path to java binary into PATH, and Java 6 fails on Samsung devices
JAVA_PATH=/usr/lib/jvm/default-java/jre/bin:/usr/lib/jvm/default-java/bin
ls usr/lib/jvm/java-7-openjdk-*/bin > /dev/null 2>&1 && JAVA_PATH=/`echo usr/lib/jvm/java-7-openjdk-*/jre/bin`:/`echo usr/lib/jvm/java-7-openjdk-*/bin`
export PATH=/usr/local/sbin:/usr/local/bin:$JAVA_PATH:/usr/sbin:/usr/bin:/sbin:/bin
export "LD_PRELOAD=/libdisableselinux.so /libandroid-shmem.so"
export PROOT_TMPDIR=`pwd`/tmp
export PROOT_TMP_DIR=$PROOT_TMPDIR
export TZ="`getprop persist.sys.timezone`"
./proot -r `pwd` -w / -b /dev -b /proc -b /sys -b /system $STORAGE "$@"
```

ここで、 [前節][SEC0201]の "[Xserver XSDL サーバの起動コマンドラインの引数の概要][SUBSEC020103]" の項より、[Settings クラスの setEnvVars() メソッドの内容][SRC7]から、環境変数 ```SDCARD``` の値は,  [Android OS][ANDR] 端末の外部ストレージ領域の絶対パスであり、環境変数 ```UNSECURE_STORAGE_DIR_[0-9]``` の値は、 [Debian noroot アプリ][DBNR]固有の外部ストレージ領域の絶対パスであることが判ります。

また、環境変数 ```USER, EXTERNAL_STORAGE``` はそれぞれ、 [Android OS][ANDR] 上のネイティブ環境においてそれぞれ [Debian noroot アプリ][DBNR]でのユーザ名及び外部ストレージ領域のパス名であることが判ります。

以上のことから、シェルスクリプト ```proot.sh``` は、最初に [Android OS][ANDR] 端末の外部ストレージ領域の絶対パスを [Debian noroot 環境][DBNR]のための chroot 環境にバインドするためのオプションを生成して、 [Debian noroot 環境][DBNR]のルートディレクトリ (即ち、 ```$SECURE_STORAGE_DIR/img = /data/data/com.cuntubuntu/files/img```) にカレントディレクトリを移動していることが判りました。

次に、アプリ固有の外部ストレージ領域の絶対パスを chroot 環境にバインドするためのオプションを生成した後、 [Debian noroot 環境][DBNR]全体に関連する各種環境変数 ```HOME、SHELL, PATH, LD_PRELOAD``` 等の初期化を行っていることが判りました。

最後に、 ```proot``` コマンドを用いて、 ```/data/data/com.cuntubuntu/files/img``` をルートディレクトリとし、ルートディレクトリを chroot 環境における初期のカレントディレクトリとして、ルートディレクトリに [Android OS][ANDR] のネイティブ環境上の ```/dev, /proc, /sys, /system``` ディレクトリ及び [Android OS][ANDR] 端末の外部ストレージ領域と [Debian noroot アプリ][DBNR]固有の外部ストレージ領域の絶対パスをバインドした chroot 環境を構築し、 ```proot.sh``` に渡された引数である ```./startx.sh``` を実行することが判りました。

## startx.sh スクリプトの実行

本節では、[前節][SEC0202]で述べたシェルスクリプト ```proot.sh``` の実行によって構築された chroot 環境上から、 [Debian noroot 環境][DBNR]において使用するデスクトップマネージャを起動し、デスクトップマネージャの終了後にユーザプロセスの終了処理を行うためのシェルスクリプトである ```startx.sh``` の一連の実行過程について述べます。

[前節][SEC0202]で述べたシェルスクリプト ```proot.sh``` に引数として渡されるシェルスクリプト ```./startx.sh``` は、 [Debian noroot 環境][DBNR]では ```/startx.sh``` に存在しています。ここで、シェルスクリプト ```/startx.sh``` の内容は以下の通りです。

```sh:/startx.sh
#!/bin/sh

rm -f /var/run/dbus/pid
fakeroot-tcp /usr/bin/env PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin dbus-daemon --system

sleep 1
dbus-launch --exit-with-session sh -c 'xfce4-session ; setsid sh -c "cd /proc/ ; for f in [0-9]* ; do [ \$f = \$\$ ] || kill -9 \$f ; done"' &

wait
```

上記のシェルスクリプトの内容より、 ```startx.sh``` は最初に、 ```fakeroot-tcp``` コマンドを使用した fakeroot 権限に基づいて ```dbus-daemon``` デーモンを起動していることが判りました。

そして、 ```dbus-launch``` 経由で、デスクトップマネージャの起動コマンドである ```xfce4-session``` を実行して、軽量デスクトップマネージャである [xfce4][XFCE] を起動し、 [xfce4][XFCE] の GUI を [Xserver XSDL サーバ][XSDL]に表示させることで一連の [Debian noroot 環境][DBNR]の起動が完了することが判りました。

最後に、 [Debian noroot 環境][DBNR]をログアウトして [xfce4][XFCE] を終了した後は、 [Android OS][ANDR] 上で起動しているプロセスにシグナル ```SIGKILL``` を送信して [Debian noroot 環境][DBNR]の子プロセスを強制終了させて、 [Debian noroot アプリ][DBNR]を終了することが判りました。

# 結論

本稿では、[前々章][CHAP01]において、 [Debian noroot 環境][DBNR]は、 [Debian noroot アプリ][DBNR]の開発者である pelya 氏によって開発され、[Android OS][ANDR] 上に移植された画像描画や音声再生の API を持つマルチメディアライブラリである [SDL][LSDL] を用いて実装された完全な互換性を持つ X Windows System のサーバアプリケーションである [Xserver XSDL][XSDL] と、 [Android OS][ANDR] 及び Linux をカーネルとする各種ディストリビューションにおいて、 root 権限を取ること無く chroot 環境や ```mount --bind``` コマンドに基づくディレクトリのバインドを擬似的に実現するためのプログラムである [proot][PROT] によって実現されていることを述べました。

そして、[前章][CHAP02]において、 [Debian noroot アプリ][DBNR]及び [Xserver XSDL][XSDL] のソースコードの解析等を行った結果、 [Debian noroot 環境][DBNR]は以下に述べるプロセスに基づいて起動及び終了していることが判明しました。

- [Android OS][ANDR] より [Debian noroot アプリ][DBNR]を起動した時に、以下の設定に基づいて [Xserver XSDL サーバ][XSDL]を起動する。
    - [Xserver XSDL サーバ][XSDL]画面中央におけるヘルプメッセージの表示を抑止する。
    - [Xserver XSDL サーバ][XSDL]画面上に "Ctrl", "Shift", "Alt" キーの働きをするボタンを表示する。
- [Xserver XSDL サーバ][XSDL]の起動後に、画面中央に "Loading Please wait This may take up to one minute." のメッセージが書かれた画像を表示する。
- [Android OS][ANDR] のネイティブ環境下でシェルスクリプト ```/data/data/com.cuntubuntu/files/img/proot.sh``` を ```./startx.sh``` を引数にして実行し、以下の処理を行う。
    - [Android OS][ANDR] 端末の外部ストレージ領域及び [Debian noroot アプリ][DBNR]固有の外部ストレージ領域のバインドオプションの生成を行う。
    - [Debian noroot 環境][DBNR]全体に関連する主な環境変数 ```HOME, SHELL, PATH, LD_PRELOAD``` 等の設定を行う。
    - ```/data/data/com.cuntubuntu/files/img``` をルートディレクトリとして [Android OS][ANDR] のネイティブ環境上の ```/dev, /proc, /sys, /system``` ディレクトリ及び [Android OS][ANDR] 端末の外部ストレージ領域と [Debian noroot アプリ][DBNR]固有の外部ストレージ領域の絶対パスをバインドした chroot 環境を構築する。
    - シェルスクリプト ```proot.sh``` の引数として渡された ```./startx.sh``` を実行し、 chroot 環境におけるシェルスクリプト ```startx.sh``` に制御を移す。
- ```/data/data/com.cuntubuntu/files/img``` をルートディレクトリとした chroot 環境において ```/startx.sh``` を実行し、以下の処理を行う。
    - ```fakeroot-tcp``` コマンドを用いた fakeroot 権限で ```dbus-daemon``` を起動する。
    - ```dbus-launch``` 経由で、 ```xfce4-session``` コマンドを実行して軽量デスクトップマネージャである [xfce4][XFCE] を起動し、 [xfce4][XFCE] の GUI を [Xserver XSDL サーバ][XSDL]に表示させることで一連の [Debian noroot 環境][DBNR]の起動プロセスが完了する。
- [Debian noroot 環境][DBNR]をログアウトして [xfce4][XFCE] を終了した後は、 [Android OS][ANDR] 上で起動しているプロセスにシグナル ```SIGKILL``` を送信して [Debian noroot 環境][DBNR]の子プロセスを強制終了させて、 [Debian noroot アプリ][DBNR]を終了する。

以上のことから、 [Debian noroot 環境][DBNR]を実現するためのソフトウェアの概要及び [Debian noroot 環境][DBNR]の一連の動作過程の解析を通じて、 [Debian noroot 環境][DBNR]の動作原理が明らかになりました。

# 謝辞

本稿の記述に当たって、 [Android OS][ANDR] 端末上で非常に軽快な [Debian 環境][DEBI]を実現することを可能にした [Debian noroot 環境][DBNR]の開発者である [pelya 氏][PELY]に心より感謝致します。本稿における [Debian noroot 環境][DBNR]の起動過程の解析に当たっては、 [pelya 氏][PELY]の開発による [Debian noroot アプリのソースコード][SRC0]及び [Xserver XSDL サーバのコマンド XSDL のソースコード][SRC5]を参考にしました。

また、 [Xserver XSDL サーバ][XSDL]の起動過程及び proot.sh の実行過程の解析にあたっては、 [kakueki61 氏][KAKU]の投稿による "[[Android] データの永続化領域について -getFilesDir() vs getExternalFilesDirs()-（アプリ内で取得した画像の置き場所に迷ったので)][KAKQ]" も併せて参考にしました。 [kakueki61 氏][KAKU]に心より感謝致します。

最後に、 [Debian noroot 環境][DBNR]と [Android OS][ANDR] 及び [Debian 環境][DEBI]の全ての事に関わる全ての皆様に心より感謝致します。

<!-- 各章・各節及び各項へのリンク一覧 -->

[CHAP01]:#debian-noroot-環境に関連する各種ソフトウェアの概要
[CHAP02]:#debian-noroot-環境の起動過程
[CHAP03]:#結論
[SEC0101]:#xserver-xsdlについて
[SEC0102]:#proot-について
[SEC0201]:#xserver-xsdl-サーバの起動
[SEC0202]:#prootsh-スクリプトの実行
[SEC0203]:#startxsh-スクリプトの実行
[SUBSEC020101]:#xserver-xsdl-サーバの起動コマンドラインを表示する
[SUBSEC020102]:#xserver-xsdl-サーバの起動コマンドラインの引数の概要
[SUBSEC020103]:#xserver-xsdl-サーバの起動過程

<!-- 各章及び各節へのリンク一覧 -->

[DBNR]:https://play.google.com/store/apps/details?id=com.cuntubuntu&hl=ja
[ANDR]:https://www.android.com/intl/ja_jp/
[DEBI]:https://www.debian.org/index.ja.html
[XSDL]:https://play.google.com/store/apps/details?id=x.org.server&hl=ja
[PROT]:http://proot.me/
[PELY]:https://github.com/pelya
[LSDL]:https://www.libsdl.org/
[XORG]:https://www.x.org/wiki/
[IMG1]:https://qiita-image-store.s3.amazonaws.com/0/86258/672eab92-0373-2baa-5074-d01699c90283.jpeg
[IMG2]:https://qiita-image-store.s3.amazonaws.com/0/86258/b210277b-03da-61bf-e2a7-8339570ae569.jpeg
[IMG3]:https://qiita-image-store.s3.amazonaws.com/0/86258/f2aba5f6-9e01-adad-db44-fdceaeb04562.jpeg
[XTRM]:http://invisible-island.net/xterm/
[QEMU]:http://wiki.qemu.org/Main_Page
[PTRC]:http://man7.org/linux/man-pages/man2/ptrace.2.html
[IMG4]:https://qiita-image-store.s3.amazonaws.com/0/86258/0c90acd2-fe19-b72a-3910-5465e31e4c5e.jpeg
[IMG5]:https://qiita-image-store.s3.amazonaws.com/0/86258/b678b2fa-3e1a-765f-096d-d99f6110f47a.jpeg
[IMG6]:https://qiita-image-store.s3.amazonaws.com/0/86258/a5e7e82b-b99a-2437-a2f0-873173d00a45.jpeg
[IMG7]:https://qiita-image-store.s3.amazonaws.com/0/86258/918a4bb9-e0ca-f664-ddd8-60cf55e13d42.jpeg
[IMG8]:https://qiita-image-store.s3.amazonaws.com/0/86258/8ae0171b-9c3c-4f99-868e-f0930b8619d2.jpeg
[SRC0]:https://github.com/pelya/commandergenius
[SRC1]:https://github.com/pelya/commandergenius/blob/d1b9f16f93d0c9d843ac0af2056d91c1f88578ef/project/java/SettingsMenuMisc.java#L542
[SRC2]:https://github.com/pelya/commandergenius/blob/d1b9f16f93d0c9d843ac0af2056d91c1f88578ef/project/java/SettingsMenuMisc.java#L566
[SRC3]:https://github.com/pelya/commandergenius/blob/9d68ae4fcaa148f32d6f4b63f5fa8b5a43544628/project/java/Video.java#L712
[SRC4]:https://github.com/pelya/commandergenius/blob/aee68aefb3a4e820ec6d375df54d8d55e7f7cdf8/project/jni/application/xserver/main.c#L25
[SRC5]:https://github.com/pelya/xserver-xsdl
[SRC6]:https://github.com/pelya/commandergenius/blob/d1b9f16f93d0c9d843ac0af2056d91c1f88578ef/project/java/Settings.java#L330
[SRC7]:https://github.com/pelya/commandergenius/blob/d1b9f16f93d0c9d843ac0af2056d91c1f88578ef/project/java/Settings.java#L619
[XFCE]:https://xfce.org/
[KAKU]:http://qiita.com/kakueki61
[KAKQ]:http://qiita.com/kakueki61/items/fc97c434f22f9135b491