Files
2026-10-02 21:34:56 +08:00

140 lines
6.9 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
> 本文是当时的分析 / 交付存档,路径按当时的工作目录写。
> 本项目里的对应关系:tools 对应 _tools,inputs/target/vela_app.bin 对应 _x/vela_app.bin,
> inputs/source 对应 _s5,.work 对应 _out(产物),dist 对应 _out/faces。
# S5 图标包 → S4 eSIM 替换包
把 **Xiaomi Watch S5(q63, v4.101.020)** 的系统应用图标,写进 **Xiaomi Watch S4 eSIM(o62lte)**
的 `/dev/app` 分区。
## 文件
| 文件 | 说明 |
|---|---|
| `main.lua` | Lua 表盘入口(LVGL 界面 + dd 写入/校验状态机) |
| `payload.lua` | 负载清单:38 条记录(1 条超级块 canary + 37 个图标) |
| `payload/` | 逐条的图标字节,文件名与 `payload.lua` 对应 |
| `payload_rollback.lua` + `payload_rollback/` | 同样 38 条,内容为 S4 原厂字节(回滚用) |
| `flash.sh` / `rollback.sh` | **不需要表盘**:有 nsh shell 时直接跑这两条脚本 |
| `payload.json` / `manifest.json` | 机器可读的明细(偏移、长度、格式、来源) |
| `README.md` | 本文件 |
## 机制:走官方 OTA 同一条路
Lua 表盘无法"设置图标"。系统图标住在 `/dev/app` 这个 265 MB 的 ROMFS 分区镜像里
(`/resource/app/<应用>/launcher.bin`),必须**写入分区 + 重启**才会生效。
关键发现来自 [`docs-shell`](../../):设备侧有 `dd` / `cmp` / `md5` / `reboot`,
而 Lua 里 **`os.execute` 可用**(`io.popen` 不可用)。固件自带的 `ota.sh` 正是这么写分区的:
```sh
dd if=/ota/vela_app.bin of=/dev/app bs=32768 verify
```
所以本包对每条记录执行三步,全程只用官方存在的命令:
```sh
dd if=payload/NNN.bin of=/dev/app bs=4 seek=<offset/4> count=<length/4>
dd if=/dev/app of=/tmp/chk.bin bs=4 skip=<offset/4> count=<length/4>
cmp /tmp/chk.bin payload/NNN.bin # 退出码 0 = 一致
```
**为什么 `bs=4`**:所有目标偏移都是 512 对齐,且每条的长度都是 4 的倍数
(82956 / 21772 / 32 都能被 4 整除),所以 `bs=4` 正好写满目标区间、
**不会多写一个字节到相邻文件里**,也不会产生不完整的尾块。
最后 `reboot` 让只读挂载重新读取分区 —— 这就是"点一下、稍等片刻、手表重启、替换成功"
那条链路。
## 关于"打包方法"
我把 `docs-lua` 全部 68 个文件读完了:**里面没有表盘打包/安装的说明。** 它给出的是**运行时契约**:
| 事实 | 出处 |
|---|---|
| 内建表盘源码就在 `/watchface/lua/<名字>/`(circle, clearheart, complexzone, corona, daynight) | `lvgl/modules/fs.md` |
| 表盘资源 `/watchface/`(`resource.bin`、`aod`) | 同上 |
| **已安装表盘在 `/data/app/watchface/`(builtin / market)** | 同上 |
| 资源用绝对路径引用,如 `/watchface/lua/corona/image/sec.bin` | `lvgl/widgets/analogtime.md` |
| 入口:`init(style)` 返回根对象;全局 `pageOnPause` / `pageOnResume` | `activity/overview.md` |
| `/data` fatfs 可读写;`/tmp` tmpfs 可读写(重启清空);其余系统目录 romfs **只读** | `docs-shell/syntax-and-environment.md` |
| `pm install <包名\|rpk>` / `am start <包名>` 是**快应用**的包管理器 | `docs-shell/runtimes-and-media.md` |
也就是说:**Lua 表盘本身就是一个目录**(`.lua` + 资源),没有专用打包格式;
真正没被文档覆盖的是"怎么把这个目录推上手表、怎么在 `watchface.db` 里注册"。
这一步取决于你所用的工具(AstroBox / 表盘自定义工具等)。
**好消息是这一步对本项目不是必需的** —— 见下面两条替代路线。
## 三条路线(按推荐顺序)
### 路线 A:`flash.sh`(最简单,只要能拿到一次 shell)
把 `flash.sh`、`payload/` 复制到手表 `/data/s5icons/`,然后:
```sh
sh /data/s5icons/flash.sh
reboot
```
不需要表盘、不需要打包、不依赖表盘宿主权限。回滚用 `rollback.sh`。
### 路线 B:Lua 表盘(`main.lua`)
按你需要的形态提供。界面三个按钮 + 回滚:
1. **① 只读检查**(不写任何字节):`dd` 读出分区头,确认 magic 是 `-rom1fs-`、
卷名是 `app`;再逐条确认负载文件都在、长度正确。**只有检查通过,② 才解锁。**
2. **② 写入并校验**:逐条 `dd` 写入 → `dd` 读回 → `cmp` 比对,带进度条。
3. **③ 重启**:`sync` + `reboot`。
4. **回滚**:用 `payload_rollback` 走同一套流程。
分片执行(定时器每 40 ms 一条),界面不会卡死;每条失败都会计数并在结束时报告。
### 路线 C:直接刷整分区(最稳)
```
_out/s4_from_s5/vela_app_s5icons.bin 已改好图标的 vela_app.bin(265 MB)
```
用你已有的刷机通道写进 `/dev/app`。完全绕开设备侧脚本。
## 替换内容
S4 有 40 个 launcher 图标槽位:
- **37 个真正被改写**(字节有差异)
- **2 个字节完全相同,已从负载中剔除**:`voice_alexa`、`wxpay`
- **1 个 S4 独有、S5 没有**:`walkie_talkie`,保持原厂
- S5 独有的 12 个(`launcher_*` 第三方图标、`temperature`、`calorie_management` 等)按约定跳过
编码策略:S5 文件长度 == S4 槽位长度 → 原样拷贝;否则解码 S5 图标后按 **S4 槽位的色彩格式**
重新编码,确保长度逐字节相等。结果:**8090 条目录项、inode 表、superblock 逐位不变**。
验证过的等价性:把这些负载按偏移重放进原厂镜像,得到的文件与我逐字节验证过的
`vela_app_s5icons.bin` **完全相同(sha256 一致)**。
观感差异:10 个视觉上无变化,29 个有可见差异,多数是重新配色/描边
(例如 `barometer` 的底盘由蓝变白、`activities` 的渐变换了)。
## ⚠ 未验证项
我**无法在真机上测试**,以下三点请自行确认:
1. **`os.execute` 是否在表盘宿主里真的可用** —— `docs-lua/intro/overview.md` 标为 ✅,
但那是模拟器环境的结论;`docs-lua/intro/conventions.md` 也写明"接口通过逆向分析获得,
不同设备可用性不一致"。
2. **`SCRIPT_PATH` 是否注入、值是什么** —— 这是 LoXe 文档的约定,不在本仓库文档里。
`main.lua` 里已有兜底常量,若加载失败请改成实际路径。
3. **写入 `dd` 的权限** —— 表盘宿主进程是否有权写 `/dev/app`。`docs-shell` 只说明命令存在,
不代表当前进程有权限。
**第一次请只按「① 只读检查」**,看清输出再决定是否写入。或者直接走路线 A/C。
## 风险
- 往分区节点写数据是危险操作,写错位置可能导致无法开机。
- 系统 OTA 升级会整分区覆盖 `vela_app.bin`,图标会回到原厂(等于自动还原)。
- 修改系统资源分区可能影响保修;请自行确认设备所有权与当地法律。
- **动手前请确认你能刷回原厂 `vela_app.bin`**(路线 C 那份镜像,或官方固件包里的同名文件)。