这是笔者的一个嗜好,喜欢研究软件的内部实现。今天我们就来扒一扒termux,看看它是如何做到在Android系统上搭建一套Linux系统的,关键还不需要root权限,只通过一个APP就做到了。
整个系统包含两部分内容:
我们重点放在客户端软件上。
我们通过几个典型问题来了解termux的一些内部实现逻辑。
要实现一套linux系统体验,需要三样东西,Linux内核、根文件系统、以及chroot命令,其中Linux内核是Android系统自带的,可以直接用。根文件系统是termux App提供的,chroot是一个系统命令,一般存在根文件系统中。但执行chroot需要root权限才行。termux是如何做到不需要root权限的呢?
答案就是:修改了所有软件的
PREFIX
到/data/data/com.termux/files/usr
,这样就不需要用到传统Linux的典型目录结构了(/etc, /bin /sbin
等),看上去是个笨方法,但非常有效。因此直接从其他开源仓库中下载的软件包时不能直接在termux上使用的,需要按照termux的规则重新编译和修改相关路径才可以。
通过这个子项目:termux-packages(https://github.com/termux/termux-packages),这里有全部三方软件包的编译脚本和patch,它不但可以编译生成一个最小根文件系统,还能生成所有三方软件包,共计1000+个。
这个项目中也有编译好的最小根文件系统压缩包:bootstrap-xxx.zip,在这个地址可以找到 https://github.com/termux/termux-packages/releases。
一个典型的最小根文件系统目录结构是这样的:
这个项目termux-app (https://github.com/termux/termux-app)负责生成我们用到的termux.apk,在这个项目中,app/src/main/cpp
目录负责将上面的bootstrap-xxx.zip打包为libtermux-bootstrap.so动态库给APK使用,实现的代码在一个termux-bootstrap-zip.S汇编代码中:
上面的代码非常简单,有用的就是两个变量:
有了这两个变量,就可以解压缩了。
这里的
.incbin
指令负责将压缩包打包到so中
TermuxActivity::onCreate()
/data/data/com.termux/files/
下:
TermuxInstaller::setupBootstrapIfNeeded()
$PREFIX/bin/login
:
TermuxTerminalSessionActivityClient::addNewSession()
TermuxService::createTermuxSession()
TermuxSession.execute()
$PREFIX/bin/bash
:$PREFIX/bin/login
脚本负责调用bash,接收终端用户输入。【文章不错,鼓励一下】