关于Debian noroot环境的运作原理
首先Debian noroot 是一款在 Android 操作系统上构建 Debian 环境而无需获取 root 权限的应用程序。
如果 Android 设备具备充足的 CPU 性能和内存容量,则可通过安装 Debian noroot 在 Android 设备上实现非常流畅的 Debian 环境。
Debian noroot环境使用Android操作系统上的X Windows System服务器应用程序Xserver XSDL,以及使用proot软件实现构建chroot环境和实现mount –bind等功能,无需获取root权限。
此外,經過參考 Debian noroot 和 Xserver XSDL 應用程式的原始碼等資料,我們得出以下結論:在 Android OS 系統下,首先啟動 Xserver XSDL 伺服器,接著在 Android OS 本機環境中執行 proot.sh 腳本以建立用於 Debian noroot 環境的 chroot 環境,隨後在 proot.sh 腳本所建立的 chroot 環境中執行 startx.sh 腳本,負責啟動桌面管理器等操作,進而啟動 Debian noroot 環境。
在本文中,我们将通过介绍实现Debian无需根权限环境的软件以及Debian无需根权限环境的一系列操作过程来描述Debian无需根权限环境的工作原理。
在本文中首先介绍了“Debian noroot 环境相关软件概况”的章节,详述了实现 Debian noroot 环境所使用的各种软件的概要。
在接下来的”Debian noroot 环境的启动过程”章节中,我们将介绍在 Android 操作系统上启动 Debian noroot 应用程序,以及启动 Debian noroot 环境中的窗口管理器的连续启动过程。
最后,在“结论”一章中,我将讨论本文的结论。
关于Debian无需root环境相关软件的概要本章将介绍用于实现Debian的noroot环境的软件Xserver XSDL和proot的概述。
在本章中,首先将介绍”关于Xserver XSDL”的部分,其中会讨论Xserver XSDL作为Android操作系统上的X Windows System服务器应用程序的概述。接下来,在”关于proot”的部分,会讨论proot作为一款在Android操作系统和Linux内核上使用的各种发行版中,无需获取root权限即可构建chroot环境和实现mount –bind等操作的软件的概述。
关于Xserver XSDLXserver XSDL 是由 Debian noroot 应用程序的开发者 pelya 先生开发的,在 Android 操作系统上运行的 X Windows System 服务器应用程序。
Xserver XSDL是一个具备完全兼容性的X Window System实现,因此可以在其他类似X.Org的UNIX兼容操作系统中与X Window System服务器程序一样,在远程的Linux个人电脑终端或已安装Xserver XSDL应用的Android操作系统终端上运行X Window System客户端程序,并将其GUI显示在屏幕上。
Xserver XSDL使用了基于Android操作系统移植的多媒体库SDL,该库包含了图像绘制和音频播放的API。
在这里,如果从Android操作系统设备启动Xserver XSDL应用程序,则会显示如下图片所示,即显示Xserver XSDL应用程序的启动界面。



$ env DISPLAY=192.168.20.33:0 xterm
如果在Android OS设备的另一个应用程序上构建了一个在chroot环境中运行的Linux发行版,那么在Linux发行版上执行以下命令时,将在上述图像中显示的X Windows系统服务器屏幕上运行轻量级窗口管理器twm。
$ env DISPLAY=:0 twm
除非另有特别说明,本文将使用”Xserver XSDL 服务器”一词来指代由Xserver XSDL应用程序启动的X Windows系统服务器。
关于proot的问题
proot是在Android操作系统和基于Linux内核的各种发行版中,以不获取root权限为前提,通过chroot环境、mount –bind命令来绑定目录,并利用QEMU的用户模式实现binfmt_misc的虚拟化程序。
proot 使用 ptrace(2) 这个 Linux 的系统调用来监视进程和追踪系统调用,以实现 chroot 环境等功能。
proot 使用 ptrace(2) 来跟踪 proot 子进程的执行过程中发生的涉及文件访问的系统调用。然后,通过将文件访问的目标路径名重写为适当的路径,实现类似 chroot 环境的伪装。
如果在这里通过proot命令加上-h选项启动,将显示如下的帮助文档。
$ 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命令的话,请使用以下命令启动。
$ proot -r /mnt/img /bin/bash
user@localhost:~$
另外,作为根目录的/mnt/img下搭建chroot环境,如果要在搭建好chroot环境后将当前目录移动到/root,则启动以下命令。
$ proot -r /mnt/img -w /root /bin/bash
user@localhost:/root$ pwd
/root
user@localhost:/root$
执行以下命令,将/mnt/img及其以下设置为根目录,构建chroot环境,并将/dev和/proc目录绑定到chroot环境的根目录,以便chroot环境可以访问它们。
$ 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操作系统和基于Linux内核的各种发行版中,可以在不获取root权限的情况下,基于chroot命令和mount –bind命令创建伪chroot环境。
Debian运行环境的启动过程在本章中,我们将从Android操作系统上启动Debian noroot应用程序,并进行Debian noroot环境的各种初始化操作,然后描述Debian noroot环境中窗口管理器启动的整个启动过程。
在本章中,首先在“启动Xserver XSDL服务器”部分中描述了在Android操作系统上启动Debian noroot应用程序时Xserver XSDL服务器的启动过程。
接下来,我们将对”proot.sh 脚本的执行”部分进行描述。该脚本用于在 Android 操作系统的原生环境中,为 Debian noroot 环境进行各种环境配置以及构建 chroot 环境,以启动 Debian noroot 环境。
最后,我们将讨论 “startx.sh 脚本的执行” 部分,该部分描述了在 proot.sh 脚本构建的 chroot 环境中启动用于 Debian noroot 环境的桌面管理器的 Shell 脚本 startx.sh 的执行过程。
启动 Xserver XSDL 服务器。通过解析Debian无根应用程序启动时Xserver XSDL服务器的启动命令行,本节将描述Xserver XSDL服务器的一系列启动过程。
在本节中,我们首先要讨论的是在启动Android OS上的Debian noroot应用程序时,如何通过显示Xserver XSDL服务器的启动命令行来实现。
接下来,在 “Xserver XSDL 服务器启动命令行参数概述” 部分中,通过分析Debian noroot的源代码等,对Xserver XSDL服务器启动命令行可选参数和参数的概要进行说明。
最后,在”Xserver XSDL服务器的启动流程”一节中,描述了从Android OS启动Debian noroot应用程序时的Xserver XSDL服务器的一系列启动过程。
显示Xserver XSDL服务器的启动命令行当您首次从Android操作系统启动Debian noroot应用程序时,将显示类似下图的Debian noroot应用程序启动界面。
从这个状态开始,在Debian noroot应用程序的启动界面上方点击“更改设备配置”按钮,将会显示如下图所示的名为“设备配置”的菜单。
另外,您可以在“设备配置”菜单中进行各种设置,以使用Debian noroot环境下的Xserver XSDL服务器。
接下来,从此状态中选择“设备配置”菜单中的“数据安装位置”,则会显示如下图所示的“数据安装位置”菜单。
然后,在此状态下通过“Data install location”菜单选择“Specify directory”,就会显示如下图所示的“Specify directory”菜单,并提示您更改目录,但您可以直接按下“确定”按钮,不做任何更改。
然后,会显示如下图所示的 “Specify command line parameters” 菜单和命令行。
Xserver XSDL 服务器启动命令行参数的概述
在这里,从Debian noroot应用程序的源代码中调查”Specify command line parameters”菜单被实现的位置,我们发现它是在CommandlineConfig类中实现的,通过”Specify command line parameters”菜单设置的命令行参数将存储在Globals类的成员变量Globals.CommandLine中。
另外,Globals.CommandLine 的值会通过 DemoRenderer 类的 nativeInit() 方法传递给 Android OS 的本地环境函数 main(),通过这个函数再通过 android_main() 函数启动 Xserver XSDL 服务器的命令 XSDL。因此,在“指定命令行参数”菜单中设置的命令行被识别为 Xserver XSDL 服务器命令 XSDL 的选项和参数。
在Debian noroot应用程序中,如果参考main()函数和Xserver XSDL服务器的XSDL命令源代码,可以了解”Specify command line parameters”菜单的命令行主要选项的含义如下。
-nohelp … Xserver XSDL サーバ画面起動後にヘルプ画面を表示せず、全体を黒い画面のままにする。
-screenbuttons … Xserver XSDL サーバ画面上に “Ctrl”, “Shift”, “Alt” キーの働きをするボタンを表示する。
-warndiskspacemb [n] … Debian noroot 環境の最初の起動時において、ストレージ領域の残りが [n] MB 以下の状態ならば警告を表示する。
-exec … -exec オプション以降の引数を Xserver XSDL サーバの子プロセスとして実行する。
此外,当调查Debian noroot应用程序的源代码时,可以找到实施”数据安装位置”菜单和”指定目录”菜单的部分。我们可以看到,”数据安装位置”菜单和”指定目录”菜单的设置值被存储在Globals类的成员变量Globals.DataDir中。
从上述内容和Settings类的setEnvVars()方法中可以看出,环境变量UNSECURE_STORAGE_DIR和SECURE_STORAGE_DIR的值分别是Globals类的成员变量Globals.DataDir的值(通常是/sdcard/Android/data/com.cuntubuntu/files)以及Debian noroot应用程序内数据的持久化区域的绝对路径(通常是/data/data/com.cuntubuntu/files)。
Xserver XSDL 服务器的启动过程通过以上事项,发现在Android操作系统上运行Debian noroot应用程序时,可以抑制Xserver XSDL服务器的帮助画面显示,并在Xserver XSDL服务器屏幕上显示具有“Ctrl”、“Shift”、“Alt”键功能的按钮,并启动Xserver XSDL服务器。
在启动Xserver XSDL服务器后,在Xserver XSDL服务器的屏幕中央显示一个画面,上面写着“加载中,请稍候,可能需要最多一分钟。”最后,在Android操作系统的本机环境中,发现要使用shell脚本/data/data/com.cuntubuntu/files/img/proot.sh以./startx.sh作为参数来运行。
执行proot.sh脚本
在本节中,我们将描述在Android操作系统的本机环境下,使用Debian noroot环境进行各种环境的初始设置以及创建用于启动Debian noroot环境的chroot环境的proot.sh脚本的一系列执行过程。
如前文中所述的,Shell脚本proot.sh的实际位置为/data/data/com.cuntubuntu/files/img/proot.sh,并且在Debian noroot环境中,它的位置为/proot.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 "$@"
从 “Xserver XSDL服务器启动命令行参数概述”一节中,根据Settings类中的setEnvVars()方法的内容,可以得知SDCARD环境变量的值是Android操作系统设备外部存储区域的绝对路径,而UNSECURE_STORAGE_DIR_[0-9]环境变量的值是Debian noroot应用程序特定的外部存储区域的绝对路径。
此外,在Android操作系统上的本地环境中,环境变量USER和EXTERNAL_STORAGE分别代表Debian noroot应用程序中的用户名和外部存储路径。
根据上述情况,我们发现Shell脚本proot.sh首先生成一个选项,用于将Android操作系统终端的外部存储路径绑定到Debian noroot环境的chroot环境。然后,该脚本将当前目录切换到Debian noroot环境的根目录(即$SECURE_STORAGE_DIR/img = /data/data/com.cuntubuntu/files/img)。
经过分析,我们注意到在生成用于将应用程序特定的外部存储路径绑定到 chroot 环境之后,还初始化了与整个 Debian noroot 环境相关的各种环境变量,包括 HOME、SHELL、PATH、LD_PRELOAD等。
最后,我发现可以使用proot命令,将/data/data/com.cuntubuntu/files/img设为根目录,并将根目录作为chroot环境的初始当前目录,在根目录中绑定Android操作系统原生环境中的/dev、/proc、/sys、/system目录,以及Android操作系统设备的外部存储空间和Debian noroot应用程序特定的外部存储空间的绝对路径,然后构建一个chroot环境。然后,我发现可以通过proot.sh传递的参数来运行./startx.sh。
执行startx.sh脚本
本节将描述一系列关于startx.sh脚本的执行过程。该脚本在chroot环境中使用由前节提到的shell脚本proot.sh创建的Debian noroot环境中启动桌面管理器,并在桌面管理器退出后执行用户进程的结束处理。
在前一节中提到的Shell脚本proot.sh传递给作为参数的Shell脚本./startx.sh,在Debian非root环境中位于/startx.sh。在这里,Shell脚本/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
从上述Shell脚本的内容中,我们可以得出结论,startx.sh首先使用fakeroot-tcp命令以fakeroot权限启动dbus-daemon守护进程。
然后通过 dbus-launch,在桌面管理器启动命令 xfce4-session 上执行,启动轻量级桌面管理器 xfce4,并将 xfce4 的 GUI 显示到 Xserver XSDL 服务器上,从而完成了一系列的 Debian noroot 环境启动。
在 Debian noroot 环境中注销并退出 xfce4 后,我发现可以发送 SIGKILL 信号给在 Android 操作系统上运行的进程,以强制终止 Debian noroot 环境的子进程并关闭 Debian noroot 应用。
結果在本文中,我提到了Debian noroot环境以及其相关的应用程序开发者pelya先生开发的Debian noroot应用程序。通过使用具有图像绘制和音频播放API的多媒体库SDL,在Android操作系统上实现了完全兼容的X Windows System服务器应用程序,即Xserver XSDL。此外,在基于Android操作系统和Linux内核的各种发行版中,通过proot程序实现了模拟chroot环境和基于mount —bind命令的目录绑定,无需获取root权限。
然后,在前一章中,经过对Debian noroot应用程序和Xserver XSDL源代码的分析,发现Debian noroot环境是通过以下过程启动和结束的。
Android OS より Debian noroot アプリを起動した時に、以下の設定に基づいて Xserver XSDL サーバを起動する。
Xserver XSDL サーバ画面中央におけるヘルプメッセージの表示を抑止する。
Xserver XSDL サーバ画面上に “Ctrl”, “Shift”, “Alt” キーの働きをするボタンを表示する。
Xserver XSDL サーバの起動後に、画面中央に “Loading Please wait This may take up to one minute.” のメッセージが書かれた画像を表示する。
Android OS のネイティブ環境下でシェルスクリプト /data/data/com.cuntubuntu/files/img/proot.sh を ./startx.sh を引数にして実行し、以下の処理を行う。
Android OS 端末の外部ストレージ領域及び Debian noroot アプリ固有の外部ストレージ領域のバインドオプションの生成を行う。
Debian noroot 環境全体に関連する主な環境変数 HOME, SHELL, PATH, LD_PRELOAD 等の設定を行う。
/data/data/com.cuntubuntu/files/img をルートディレクトリとして Android OS のネイティブ環境上の /dev, /proc, /sys, /system ディレクトリ及び Android OS 端末の外部ストレージ領域と Debian noroot アプリ固有の外部ストレージ領域の絶対パスをバインドした 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 を起動し、 xfce4 の GUI を Xserver XSDL サーバに表示させることで一連の Debian noroot 環境の起動プロセスが完了する。
Debian noroot 環境をログアウトして xfce4 を終了した後は、 Android OS 上で起動しているプロセスにシグナル SIGKILL を送信して Debian noroot 環境の子プロセスを強制終了させて、 Debian noroot アプリを終了する。
通过分析软件的概述以及 Debian noroot 环境的一系列操作过程,我们揭示了 Debian noroot 环境的运行原理。
感谢本文在分析Debian非root环境的启动过程时,我对pelya先生开发的Debian noroot应用程序的源代码以及Xserver XSDL服务器命令XSDL的源代码表示感谢。这些代码使得在Android操作系统设备上实现非常流畅的Debian环境成为可能。
此外,在分析Xserver XSDL服务器的启动过程和proot.sh的执行过程时,我们还参考了kakueki61的帖子”[Android] データの永続化領域について -getFilesDir() vs getExternalFilesDirs()-(アプリ内で取得した画像の置き場所に迷ったので)”,在此对kakueki61表示衷心的感谢。
最后,真诚感谢所有与Debian noroot环境、Android OS以及Debian环境相关的人士。

另外,您可以在“设备配置”菜单中进行各种设置,以使用Debian noroot环境下的Xserver XSDL服务器。




Xserver XSDL 服务器启动命令行参数的概述
在这里,从Debian noroot应用程序的源代码中调查”Specify command line parameters”菜单被实现的位置,我们发现它是在CommandlineConfig类中实现的,通过”Specify command line parameters”菜单设置的命令行参数将存储在Globals类的成员变量Globals.CommandLine中。
另外,Globals.CommandLine 的值会通过 DemoRenderer 类的 nativeInit() 方法传递给 Android OS 的本地环境函数 main(),通过这个函数再通过 android_main() 函数启动 Xserver XSDL 服务器的命令 XSDL。因此,在“指定命令行参数”菜单中设置的命令行被识别为 Xserver XSDL 服务器命令 XSDL 的选项和参数。
在Debian noroot应用程序中,如果参考main()函数和Xserver XSDL服务器的XSDL命令源代码,可以了解”Specify command line parameters”菜单的命令行主要选项的含义如下。
-nohelp … Xserver XSDL サーバ画面起動後にヘルプ画面を表示せず、全体を黒い画面のままにする。
-screenbuttons … Xserver XSDL サーバ画面上に “Ctrl”, “Shift”, “Alt” キーの働きをするボタンを表示する。
-warndiskspacemb [n] … Debian noroot 環境の最初の起動時において、ストレージ領域の残りが [n] MB 以下の状態ならば警告を表示する。
-exec … -exec オプション以降の引数を Xserver XSDL サーバの子プロセスとして実行する。
此外,当调查Debian noroot应用程序的源代码时,可以找到实施”数据安装位置”菜单和”指定目录”菜单的部分。我们可以看到,”数据安装位置”菜单和”指定目录”菜单的设置值被存储在Globals类的成员变量Globals.DataDir中。
从上述内容和Settings类的setEnvVars()方法中可以看出,环境变量UNSECURE_STORAGE_DIR和SECURE_STORAGE_DIR的值分别是Globals类的成员变量Globals.DataDir的值(通常是/sdcard/Android/data/com.cuntubuntu/files)以及Debian noroot应用程序内数据的持久化区域的绝对路径(通常是/data/data/com.cuntubuntu/files)。
Xserver XSDL 服务器的启动过程通过以上事项,发现在Android操作系统上运行Debian noroot应用程序时,可以抑制Xserver XSDL服务器的帮助画面显示,并在Xserver XSDL服务器屏幕上显示具有“Ctrl”、“Shift”、“Alt”键功能的按钮,并启动Xserver XSDL服务器。
在启动Xserver XSDL服务器后,在Xserver XSDL服务器的屏幕中央显示一个画面,上面写着“加载中,请稍候,可能需要最多一分钟。”最后,在Android操作系统的本机环境中,发现要使用shell脚本/data/data/com.cuntubuntu/files/img/proot.sh以./startx.sh作为参数来运行。
执行proot.sh脚本
在本节中,我们将描述在Android操作系统的本机环境下,使用Debian noroot环境进行各种环境的初始设置以及创建用于启动Debian noroot环境的chroot环境的proot.sh脚本的一系列执行过程。
如前文中所述的,Shell脚本proot.sh的实际位置为/data/data/com.cuntubuntu/files/img/proot.sh,并且在Debian noroot环境中,它的位置为/proot.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 "$@"
从 “Xserver XSDL服务器启动命令行参数概述”一节中,根据Settings类中的setEnvVars()方法的内容,可以得知SDCARD环境变量的值是Android操作系统设备外部存储区域的绝对路径,而UNSECURE_STORAGE_DIR_[0-9]环境变量的值是Debian noroot应用程序特定的外部存储区域的绝对路径。
此外,在Android操作系统上的本地环境中,环境变量USER和EXTERNAL_STORAGE分别代表Debian noroot应用程序中的用户名和外部存储路径。
根据上述情况,我们发现Shell脚本proot.sh首先生成一个选项,用于将Android操作系统终端的外部存储路径绑定到Debian noroot环境的chroot环境。然后,该脚本将当前目录切换到Debian noroot环境的根目录(即$SECURE_STORAGE_DIR/img = /data/data/com.cuntubuntu/files/img)。
经过分析,我们注意到在生成用于将应用程序特定的外部存储路径绑定到 chroot 环境之后,还初始化了与整个 Debian noroot 环境相关的各种环境变量,包括 HOME、SHELL、PATH、LD_PRELOAD等。
最后,我发现可以使用proot命令,将/data/data/com.cuntubuntu/files/img设为根目录,并将根目录作为chroot环境的初始当前目录,在根目录中绑定Android操作系统原生环境中的/dev、/proc、/sys、/system目录,以及Android操作系统设备的外部存储空间和Debian noroot应用程序特定的外部存储空间的绝对路径,然后构建一个chroot环境。然后,我发现可以通过proot.sh传递的参数来运行./startx.sh。
执行startx.sh脚本
本节将描述一系列关于startx.sh脚本的执行过程。该脚本在chroot环境中使用由前节提到的shell脚本proot.sh创建的Debian noroot环境中启动桌面管理器,并在桌面管理器退出后执行用户进程的结束处理。
在前一节中提到的Shell脚本proot.sh传递给作为参数的Shell脚本./startx.sh,在Debian非root环境中位于/startx.sh。在这里,Shell脚本/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
从上述Shell脚本的内容中,我们可以得出结论,startx.sh首先使用fakeroot-tcp命令以fakeroot权限启动dbus-daemon守护进程。
然后通过 dbus-launch,在桌面管理器启动命令 xfce4-session 上执行,启动轻量级桌面管理器 xfce4,并将 xfce4 的 GUI 显示到 Xserver XSDL 服务器上,从而完成了一系列的 Debian noroot 环境启动。
在 Debian noroot 环境中注销并退出 xfce4 后,我发现可以发送 SIGKILL 信号给在 Android 操作系统上运行的进程,以强制终止 Debian noroot 环境的子进程并关闭 Debian noroot 应用。
結果在本文中,我提到了Debian noroot环境以及其相关的应用程序开发者pelya先生开发的Debian noroot应用程序。通过使用具有图像绘制和音频播放API的多媒体库SDL,在Android操作系统上实现了完全兼容的X Windows System服务器应用程序,即Xserver XSDL。此外,在基于Android操作系统和Linux内核的各种发行版中,通过proot程序实现了模拟chroot环境和基于mount —bind命令的目录绑定,无需获取root权限。
然后,在前一章中,经过对Debian noroot应用程序和Xserver XSDL源代码的分析,发现Debian noroot环境是通过以下过程启动和结束的。
Android OS より Debian noroot アプリを起動した時に、以下の設定に基づいて Xserver XSDL サーバを起動する。
Xserver XSDL サーバ画面中央におけるヘルプメッセージの表示を抑止する。
Xserver XSDL サーバ画面上に “Ctrl”, “Shift”, “Alt” キーの働きをするボタンを表示する。
Xserver XSDL サーバの起動後に、画面中央に “Loading Please wait This may take up to one minute.” のメッセージが書かれた画像を表示する。
Android OS のネイティブ環境下でシェルスクリプト /data/data/com.cuntubuntu/files/img/proot.sh を ./startx.sh を引数にして実行し、以下の処理を行う。
Android OS 端末の外部ストレージ領域及び Debian noroot アプリ固有の外部ストレージ領域のバインドオプションの生成を行う。
Debian noroot 環境全体に関連する主な環境変数 HOME, SHELL, PATH, LD_PRELOAD 等の設定を行う。
/data/data/com.cuntubuntu/files/img をルートディレクトリとして Android OS のネイティブ環境上の /dev, /proc, /sys, /system ディレクトリ及び Android OS 端末の外部ストレージ領域と Debian noroot アプリ固有の外部ストレージ領域の絶対パスをバインドした 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 を起動し、 xfce4 の GUI を Xserver XSDL サーバに表示させることで一連の Debian noroot 環境の起動プロセスが完了する。
Debian noroot 環境をログアウトして xfce4 を終了した後は、 Android OS 上で起動しているプロセスにシグナル SIGKILL を送信して Debian noroot 環境の子プロセスを強制終了させて、 Debian noroot アプリを終了する。
通过分析软件的概述以及 Debian noroot 环境的一系列操作过程,我们揭示了 Debian noroot 环境的运行原理。
感谢本文在分析Debian非root环境的启动过程时,我对pelya先生开发的Debian noroot应用程序的源代码以及Xserver XSDL服务器命令XSDL的源代码表示感谢。这些代码使得在Android操作系统设备上实现非常流畅的Debian环境成为可能。
此外,在分析Xserver XSDL服务器的启动过程和proot.sh的执行过程时,我们还参考了kakueki61的帖子”[Android] データの永続化領域について -getFilesDir() vs getExternalFilesDirs()-(アプリ内で取得した画像の置き場所に迷ったので)”,在此对kakueki61表示衷心的感谢。
最后,真诚感谢所有与Debian noroot环境、Android OS以及Debian环境相关的人士。