-
Notifications
You must be signed in to change notification settings - Fork 2
Ubuntu Rootfs
AceGuru-mjh edited this page Oct 1, 2026
·
4 revisions
📑 本页目录
从"应用内下载安装"转向"构建期内置、开箱即用"(T83)。本页讲清楚这条可审计链的 构建期一半(脚本)与运行时一半(代码),以及三处指纹一致性为什么是硬约束。
| 旧方案(运行时下载安装) | 新方案(内置交付,v1.2.0 起) |
|---|---|
| 首次使用要下数百 MB,体验差 | 装完 APK 直接可跑 Ubuntu |
| 依赖镜像源可用性(墙 / 源挂) | 归档随 APK 分发,完全离线 |
| 安装过程易中断、难排错 | 安装器负责解压放入原生库目录 |
| 难以证明"这个 rootfs 没被换过" | 构建期固定 SHA-256 指纹,三处交叉校验 |
思路借鉴:Operit 的内置 rootfs 风格 + 自有创新 —— 构建期固定指纹的可审计链。
flowchart LR
A["官方 cdimage<br/>ubuntu-base 24.04.4"] -->|curl 下载| B["scripts/fetch_rootfs.sh"]
B --> C{"双重校验<br/>① 脚本内固定 sha256<br/>② rootfs-bundle.sha256 清单"}
C -->|不一致| X["exit 1:宁可构建失败,<br/>不可静默打包指纹不符的 rootfs"]
C -->|一致| D["暂存到<br/>platform/terminal/src/main/jniLibs/<abi>/libubuntu-rootfs.so"]
D --> E["gradle assemble<br/>(useLegacyPackaging + keepDebugSymbols)"]
E --> F["APK 安装时系统把 .so<br/>解出到 nativeLibraryDir"]
F --> G["BundledRootfsSource<br/>resolve:长度校验 + 本地拷贝 SHA-256 复验"]
G --> H["PRoot ubuntu(session) 供 Agent 使用"]
| 用法 | 行为 |
|---|---|
scripts/fetch_rootfs.sh |
拉取全部 3 ABI + 双重校验 + 暂存(幂等:已就绪即跳过) |
scripts/fetch_rootfs.sh --check |
只校验已暂存档案,不下载(CI 快速路径) |
scripts/fetch_rootfs.sh --clean |
删除暂存档案 |
- 来源:
https://cdimage.ubuntu.com/ubuntu-base/releases/24.04/release,点版本24.04.4; - 依赖:
curl+sha256sum;缺依赖或校验失败一律 exit 1; - 架构元组
<android abi> <ubuntu arch> <sha256> <size>:
| Android ABI | Ubuntu arch | 归档大小 | SHA-256(前 16 位) |
|---|---|---|---|
arm64-v8a |
arm64 | 29,870,567 | 04207713ece899c3… |
x86_64 |
amd64 | 29,989,394 | c1e67ef7b17a6300… |
armeabi-v7a |
armhf | 27,088,043 | 991520b47f6586f3… |
Important
同一份 sha256 必须在三处保持一致:
① scripts/fetch_rootfs.sh 的 ARTIFACTS 表;② platform/terminal/rootfs-bundle.sha256
清单;③ BundledRootfsSource.kt 的注册表。
由 BundledRootfsSourceTest 交叉校验 —— 任一处漂移,测试与 --check 都会红。
| 配置 | 位置 | 为什么 |
|---|---|---|
useLegacyPackaging = true |
platform/terminal/build.gradle.kts + app/build.gradle.kts
|
必须让归档被解压缩到 nativeLibraryDir,否则无法 exec/include 读取 |
keepDebugSymbols += "**/libubuntu-rootfs.so" |
同上 | 跳过 llvm-strip,避免归档被"瘦身"损坏 |
ndk.abiFilters |
terminal 模块 |
arm64-v8a / armeabi-v7a / x86_64
|
伪装成 .so
|
jniLibs 目录约定 | 复用 Android 原生库分发机制(不是真正的 ELF 库,加载器不会 dlopen 它) |
-
resolve():从nativeLibraryDir找到libubuntu-rootfs.so,先校验长度与期望字节数一致; - copy 到本地工作区后再做一次 SHA-256 复验;
- 通过后交给
RootfsProvisionerImpl供应给 PRoot 会话; - 内置的 additionally 参与的还有
RootfsHealthCheck(健康检查)与UbuntuSourcesList(换源)。
| 组件 | 职责 |
|---|---|
UbuntuBootstrapManager |
首次引导流程(解压 / 配置 / 基础包清单) |
UbuntuLifecycleCoordinator |
统一生命周期状态:ensure / status,暴露 terminal.ubuntu.ensure / terminal.ubuntu.status
|
AdaptiveProvisionLoop + DiagnosticRules
|
执行 → 观察 → 诊断 → 自动修复(带 ResolverCache 防重复 repair) |
RootfsMetadataStore |
记录已安装版本、指纹、时间,用于幂等与升级判断 |
UbuntuSourcesList |
写 sources.list(可换国内镜像加速 apt) |
| 现象 | 处理 |
|---|---|
| CI 报 "manifest disagreement" | 脚本表与 rootfs-bundle.sha256 漂移 —— 改了一处就要改三处 |
--check 报 digest mismatch |
暂存档案损坏或被替换,删掉重跑(或 --clean 后重拉) |
| Ubuntu 新点版本发布想升级 | 更新 POINT_VERSION + 三处 sha256(含 size),跑 --clean 后重新暂存 |
| 只想本地验证不打完整包 |
scripts/fetch_rootfs.sh --check 即可验证指纹一致性 |
| APK 体积暴涨 | 每个 ABI 约 30MB 归档;发布单 ABI 用 -PapexAbi=arm64-v8a
|
-
MCP 生态总览
新 - (沙箱 MCP · 官方 Hub · 逆向 Host · 门控语义)
- 终端运行时
- 终端 API 契约
- SDK 边界
- Termux 能力矩阵
- Ubuntu rootfs 供给
- Ubuntu 生命周期
- PRoot 二进制溯源
- VT100/ANSI 模拟器
- 终端性能
- 终端迁移
- 原生层 C++/JNI