Files
MeowOS-For-R3P2/scripts/build/README.md
T

199 lines
13 KiB
Markdown
Raw 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.
# MeowOS 固件打包脚本使用说明(scripts/build/)
> 本目录是 MeowOS 固件打包的**唯一入口**。核心思想:**只改配置文件,不改脚本**。
> 新增/更新固件内容 → 改 `fw_content.conf`;打包 → 跑 `build_fw_apps.sh`。
> 本文档防遗忘,覆盖常见场景与踩坑记录。
---
## 1. 文件一览
| 文件 | 作用 |
|---|---|
| `build_fw_apps.sh` | **通用打包脚本**(配置驱动)。读清单 → 组树 → repack → 校验 → 出固件。**不要改它的逻辑**,除非打包流程本身要变。 |
| `fw_content.conf` | **固件内容清单**(默认配置)。每行一条 `<src>|<dst>|<md5>|<desc>`,声明"哪个本地文件装到固件哪里"。**改固件内容只改这里。** |
| `build_devkit.sh` | **TF 卡调试工具集**交叉编译脚本(zig → 静态 MIPS32r2):`vmstat/slabtop/free/ps/pmap/sysctl/lsof`(上游包)+ `timeout`(本仓 `devkit-src/` 本地源码)→ `fw_apps/devkit/`。与固件打包无关,独立跑。详见 `DEVKIT.md`。 |
| `devkit-src/` | devkit 的**本地源码**(Apache-2.0,本仓自有):`timeout.c`。`build_devkit.sh` 的 `build_local` 路径编译它,不下载、不 patch、不混入上游流程。 |
| `rebuild_binaries.sh` | **进固件的那批组件重编驱动**:`bash scripts/build/rebuild_binaries.sh [bootmenu netmgrd audiod audio launcherd]`。在干净 checkout / git worktree 里**开箱可跑**:兼容 HOME 里补 `.tools`(zig 工具链)与 `patch_v2`,`meow_ui.a` 自动从主 checkout 取(取不到会报错列出试过的路径),产物就地写回 `patch_v2/<组件>/`。 |
| `verify_fingerprints.sh` | **产物语义指纹自证**:`bash scripts/build/verify_fingerprints.sh`(`--self-test` 自检判据非空)。重编后 md5 必变,能证明「产物含哪些源码改动」的是字符串/动态段/4263 反汇编判据;time32 门禁的退出码计入 FAIL,不会假绿。 |
| `test_build_devkit.sh` | `build_devkit.sh` 的回归测试(不重编;热缓存约 15s,冷启动需先重建基线 1–2 分钟):stamp 命中时 `--with-sources` 必须产出完整 `src/`;`licenses`/`README` 被删要能恢复、`--verify-only` 必须拒绝;MANIFEST 漂移检测。 |
| `DEVKIT.md` | devkit 的产物清单、许可证留痕(GPLv2 §3 / LGPL-2.1 §6)、可行性实测、time64 限制、上卡 PATH/busybox 关系。 |
| `README.md` | 本说明。 |
> 曾有一批独立脚本 `build_fw_apps_m2xx.sh`(每版复制一个、内部硬编码 md5),**已清理删除**,不再使用。它们的问题:需每版改脚本、且共享 `fw_apps/` 目录互相清空。现统一走"一个通用脚本 + 一个配置文件"。
---
## 2. 用法
```bash
cd <仓库根> # 例:cd /path/to/MeowOS-For-R3P2
# 示例:版本号 0.8.49(以本次要发的版本为准),产物直接写进归档目录 fw_apps/out/
bash scripts/build/build_fw_apps.sh -v 0.8.49 -o fw_apps/out/r3proii_0.8.49.upt
# 用指定配置(并存多套调试/场景配置时)
bash scripts/build/build_fw_apps.sh -c scripts/build/fw_content.conf -v 0.8.49 -o fw_apps/out/r3proii_0.8.49.upt
# 指定基线目录(默认 fw_ssh/squashfs-root)
bash scripts/build/build_fw_apps.sh -v 0.8.49 -o fw_apps/out/r3proii_0.8.49.upt -b fw_ssh/squashfs-root
# 注意:-o 只给文件名(如 r3proii_0.8.49.upt)时产物落在**仓库根**,不会进 fw_apps/out/(见下)
```
### 参数
| 参数 | 必填 | 说明 |
|---|---|---|
| `-c, --config` | 否 | 清单路径,默认 `scripts/build/fw_content.conf`。传别的路径即用另一套配置(互不覆盖)。 |
| `-v, --version` | **是** | 版本号(如 `0.8.49`,以本次要发的版本为准),写入固件 `/etc/meowos_version`。 |
| `-o, --out` | **是** | 输出 `.upt` 路径(如 `fw_apps/out/r3proii_0.8.49.upt`)。归档只在路径落在仓库 `fw_apps/` 下(`out/` 之外)时发生,规则见下节。 |
| `-b, --base` | 否 | 基线根文件系统目录,默认 `fw_ssh/squashfs-root`。 |
### 产物去哪
- **工作区(每次清理重建)**:`fw_apps/build/` —— 组装 squashfs-root 树,用后即弃。
- **产物归档(不受清理影响)**:`fw_apps/out/` —— 想归档的 `.upt` 放这,多次打包互不覆盖、不会误删。
`-o` 的实际落地位置(`build_fw_apps.sh:69-76`):
1. 相对路径先拼仓库根:`-o r3proii_0.8.49.upt` → `$ROOT/r3proii_0.8.49.upt`,即**落在仓库根,不会自动进 `out/`**。
2. 再按最终路径匹配(`case` 两条分支 + 默认原样):
- 已在 `$ROOT/fw_apps/out/` 下 → 原样保留;
- 落在 `$ROOT/fw_apps/` 下但不在 `out/` → 并入 `$ROOT/fw_apps/out/<basename>`;
- 其它路径(仓库根、仓库外的 `/tmp/x.upt` 等)→ **原地不动**。
> **所以想归档就显式写进 `out/`**(`-o fw_apps/out/<name>.upt`,或至少 `-o fw_apps/<name>.upt`)。只给文件名会留在仓库根,刷机前需自己挪到卡根。
---
## 3. 修改固件内容(只改配置)
固件里加/换一个组件,只需在 `fw_content.conf` 加/改一行:
```
<src>|<dst>|<md5>|<desc>
```
- `<src>`:仓库内相对路径(相对项目根 `ROOT`),如 `patch_v2/meow_launcherd/meow_launcherd`。
- `<dst>`:目标绝对路径(装入固件),如 `/usr/bin/meow_launcherd` 或 `/etc/init.d/S90meow_bootmenu`。
- `<md5>`:**可空 = 不校验**;填了 = 打包前对 `<src>` 做强校验,不一致即 `exit 1`(防呆:源被改/路径错)。**改了源码后要更新这里的 md5**(`md5sum <src>`)。
- `<desc>`:注释说明(可省略,出现会保留)。
规则:
- `#` 开头为注释,空行忽略。
- 目标目录自动创建;**每条**条目装入后一律 `chmod 755`(`usr/bin` / `etc/init.d` / `etc/profile.d` 之外同理,例如 udhcpc 钩子 `usr/share/udhcpc/default.script.d/*` 必须可执行才会被调用)。
- 多重配置并存:复制 `fw_content.conf` 改名,用 `-c` 指定,互不干扰。
### 覆盖基线已有文件(清单 `<dst>` 与基线同名)
清单条目对目标目录是**无条件 `cp -f` 覆盖**:不校验基线原文件的 md5、也不跳过「已存在」的文件,只要
`<dst>` 命中就行。脚本里唯一的基线校验是第 2 步的 `usr/bin/hiby_player`(stock a73f2c49…),与清单条目无关。
因此覆盖类条目要自己在 `<desc>` 里写清「覆盖基线 xxx(基线 md5 …)」,便于复盘对照基线。例(M21 开机亮度链):
```
patch_v2/bootmenu/S11jpeg_display_shell|/etc/init.d/S11jpeg_display_shell|<md5>|覆盖基线 S11(基线 md5 249220f2…)…
patch_v2/bootmenu/S22brightness|/etc/init.d/S22brightness|<md5>|新增:…(S21mount_ubifs 之后按用户设置恢复背光)
```
> 覆盖基线 init 脚本时,顺序仍由**文件名**决定(`rcS` 按 `/etc/init.d/S??*` 自然序执行),不能靠清单顺序。
### 常见:更新某个二进制后改 md5
```bash
md5sum patch_v2/meow_launcherd/meow_launcherd
# → 9ca4c5e8a919f59cb2cdd6326da23065
```
把 `fw_content.conf` 里对应行 md5 替换成新值即可。
---
## 4. 打包流程做了哪些事(通用步骤)
脚本读清单之外,还会自动做这些固定动作(**无需在清单里声明**):
1. 建树:复制基线 `$BASE` → `fw_apps/build/squashfs-root`。
2. 校验基线:`usr/bin/hiby_player` 必须是 stock(md5 `a73f2c49…`),否则中止(防 stock 被改坏)。
3. 解析清单:逐条(md5 若有则强校验)→ `cp -f` → `chmod 755`,目录自动建。
4. 写版本:`echo $VERSION > $DST/etc/meowos_version`(单点版本号来源)。
5. 外围 CLI 瘦身:从 `/usr/bin` 移除白名单工具(`curl socat tmux jq rsync nano htop ncdu file xxd`——已迁 TF 卡 `MeowOS/opt/bin/`)。
6. 启动图/背包/关机 logo:从 `bootlogos/` 拷 `logo_new→logo.jpeg`、`logo1_new→logo1`、`logo2_new→logo2`、`boot_anim_0.png→etc/boot_animation/0.png`、`shutdown_logo.jpeg→etc/`。
7. `S99ssh` → `S84ssh`:改名(内容不变),校验一致后删 `S99ssh`(清单不含 S84)。
8. repack:`hiby_os_crack/scripts/repack.sh -i $DST -k unpacked_v14/xImage -o $OUT`。
9. 体积核对:rootfs 分区 ≤ **45,088,768** 字节,超限中止。
10. unpack 回验:把打包产物解回到官方 squashfs,与 `$DST` 比对 **0 diff**,发现差异即中止并打印 diff。
### 清单里**不要**加的东西(通用步骤已处理)
- `/etc/meowos_version`(由 `-v` 写入)
- `/etc/logo*`、`/etc/boot_animation/0.png`、`/etc/shutdown_logo.jpeg`(由 bootlogos/ 拷贝)
- `/etc/init.d/S84ssh`(由基线 `S99ssh` 改名而来)
- `usr/bin` 外围 CLI 瘦身(按白名单移除)
> **易混淆**:`/etc/shutdown_logo.jpeg` 是**图片**(通用步骤从 `bootlogos/shutdown_logo.jpeg` 拷);`/etc/init.d/S95shutdown_logo` 是**启动/停止脚本**(清单里单独一条 `S95shutdown_logo`,负责关机时显示该图)。二者不同,别混。
---
## 4.1 devkit 本地源码(`timeout`)与「设备禁裸跑」纪律
`build_devkit.sh` 有两条互不干扰的编译路径:
| 路径 | 输入 | 流程 |
|---|---|---|
| A. 上游包 | ncurses / procps-ng / lsof 的 tarball | 固定版本 + sha256 → configure/make(缓存命中不联网) |
| B. 本地源码 | `scripts/build/devkit-src/*.c` | 一次 `zigcc -O2 -static`(无下载、无 patch、不进上游流程) |
`timeout` 走 B 路径:**本仓 Apache-2.0 独立实现**(`devkit-src/timeout.c`),
不是 busybox 的 GPL 代码。产物 `fw_apps/devkit/bin/timeout` 与其它工具一起自检
(static / ELF32 / MIPS32r2 / 0 NEEDED)、写进 `MANIFEST.txt`(Apache-2.0 行)、
`licenses/meowos-timeout-LICENSE` 附 Apache-2.0 原文;`--with-sources` 会把
`timeout.c` 一起放进 `src/`。新增本地小工具只需往 `devkit-src/` 丢一个 `.c`。
**为什么要有它(别跳过这段)**:2026-11-11 18:44,设备因为**裸跑会挂在硬件上的外部命令**
(`bluetoothctl`,累积 55 个挂死客户端)耗尽进程表:18:44:13 launcher 最后日志、
18:44:14 sshd 最后 child 退出,之后 11 分钟 `ssh.log` 一行都没有(fork 失效),
只能重启。完整时间线与纪律见 **`DEVKIT.md` §1.1**。最短版本:
```sh
timeout 8 bluetoothctl connect <MAC> # 设备侧禁止裸跑,一律加超时并封顶重试次数
timeout 5 sh -c 'sleep 100 & sleep 100 & wait' # 孙进程也必须死
```
设备上没有 `timeout(1)`(busybox 1.31 也无此 applet),所以这个工具是那条纪律的可执行形态。
---
## 5. 踩坑记录(重要)
- **脚本共享目录互相清空**:早期每个版本一个脚本、都 `rm -rf fw_apps`,并行跑会删掉彼此的 `.upt` 产物。→ 已改为 `fw_apps/build/`(工作区)+ `fw_apps/out/`(归档)分离,且删光独立脚本。
- **改源码忘更新 md5**:清单里 md5 是强校验,源变了但 md5 没改 → 打包直接失败。**凡是动了清单里列的源文件,先 `md5sum` 更新对应行。**
- **SDK 库(`meow_ui.a`)不入固件**:它由 APP(如 hello)链接,走 TF 卡 `MeowAPPs/` 热更新,**不要**加进清单。
- **`fw_apps/` 被 gitignore**:固件产物与组装树都是构建产物,勿提交。
- **`scripts/build/` 根目录 gitignore**:构建产物与组装树勿提交。但本目录的 **`README.md`/`build_fw_apps.sh`/`fw_content.conf`/`build_devkit.sh`/`test_build_devkit.sh`/`DEVKIT.md`/`devkit-src/*.c`/`rebuild_binaries.sh`/`verify_fingerprints.sh` 已 `git add -f` 入库**(这几个是仓库侧应保留的脚本/配置/说明/本地源码,与 `git ls-files scripts/build` 一致);其余(`fw_apps/` 产物、devkit 编译树等)不入库。新增 `devkit-src/*.c` 后记得同样 `git add -f`。
---
## 6. 每次打固件的最小步骤
```bash
# 1. 确认要进的组件 md5 无变化(若改了源码先更新 fw_content.conf)
md5sum patch_v2/meow_launcherd/meow_launcherd patch_v2/meow_svc_power/meow_svc_power
# 2. 打包(版本号 + 输出名;示例版本 0.8.49,-o 显式写进 out/ 才会归档)
bash scripts/build/build_fw_apps.sh -v 0.8.49 -o fw_apps/out/r3proii_0.8.49.upt
# 3. 看结果:0 diff、体积 ≤ 上限、最终固件 md5
# 产物在 fw_apps/out/r3proii_0.8.49.upt
# 4. 推卡升级:scp 到设备卡根 /usr/data/mnt/sd_0/r3proii.upt(先备份当前为 prevNx)
```
---
## 7. 相关权威文档
- 固件/升级细节:`docs/MEOWOS_SPEC_REF.md`(版本单点 `/etc/meowos_version`、rootfs 上限 45088768、mtd 分区、升级=写 mtd5)。
- 组件来源:`patch_v2/`(launcher/bootmenu/svcd/sysui/mdns/nyai/svc_power/svc_perf 等)。
- 专项服务/电源 CLI:`devdocs/plan/SYSTEM_FRAMEWORK_SERVICES.md`。