问小白 wenxiaobai
资讯
历史
科技
环境与自然
成长
游戏
财经
文学与艺术
美食
健康
家居
文化
情感
汽车
三农
军事
旅行
运动
教育
生活
星座命理

玩转Termux | 10.内部实现

创作时间:
作者:
@小白创作中心

玩转Termux | 10.内部实现

引用
1
来源
1.
https://ticktechman.tech/series/play-with-termux/inside/

Termux是一个在Android设备上运行Linux环境的实用工具,它能够在不获取root权限的情况下,为用户提供一个完整的Linux终端环境。本文将深入探讨Termux的内部实现原理,包括其系统架构、关键技术和具体实现过程。

系统架构

整个系统包含两部分内容:

  • 客户端软件

  • 一个前端模拟器,用于实现一个终端命令行界面

  • 一个根文件系统,这里包含一个最小系统,类似于Linux发行版的live CD,里面包含了最基础的系统命令,通过这些命令,可以下载更大的系统。

  • 服务器软件

  • 一套包管理系统,类似Ubuntu的apt

  • 三方软件包

我们重点放在客户端软件上。

实现

我们通过几个典型问题来了解Termux的一些内部实现逻辑。

为什么不需要root权限?

要实现一套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。

一个典型的最小根文件系统目录结构是这样的:

.
├── SYMLINKS.txt   # 符号连接配置项,首次启动APP的时候用到
├── bin            # 系统命令
├── etc            # 系统配置
├── include        # 系统库头文件
├── lib            # 系统库文件
├── libexec
├── share
├── tmp
└── var

如何将一个根文件系统装进APK的?

这个项目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汇编代码中:

.global blob
.global blob_size
.section .rodata
blob:
#if defined __i686__
.incbin "bootstrap-i686.zip"
#elif defined __x86_64__
.incbin "bootstrap-x86_64.zip"
#elif defined __aarch64__
.incbin "bootstrap-aarch64.zip"
#elif defined __arm__
.incbin "bootstrap-arm.zip"
#else
# error Unsupported arch
#endif
1:
blob_size:
.int 1b - blob

上面的代码非常简单,有用的就是两个变量:

  • blob:存储者压缩包的起始地址
  • blob-size:存储压缩包大小

有了这两个变量,就可以解压缩了。这里的.incbin指令负责将压缩包打包到so中

APP首次启动流程是什么?

  • 启动activity:
  • TermuxActivity::onCreate()
  • 解压缩bootstrap压缩包到/data/data/com.termux/files/下:
  • TermuxInstaller::setupBootstrapIfNeeded()
  • 启动命令行$PREFIX/bin/login
  • TermuxTerminalSessionActivityClient::addNewSession()
  • TermuxService::createTermuxSession()
  • TermuxSession.execute()
  • 启动$PREFIX/bin/bash
    $PREFIX/bin/login脚本负责调用bash,接收终端用户输入。

参考

© 2023 北京元石科技有限公司 ◎ 京公网安备 11010802042949号