Files
MeowOS-For-R3P2/scripts/build/README.md
T
AskaEth 0d1b2d4c19 fix(fw): M51 r2 — 重编脚本开箱可用、自证门禁不再假绿、归因与 desc 纠正
r2 评审 p2-6items 六条全部处理;**产物字节未变**(5 件 md5 与 31d4c22 完全一致)。

P2-1/P2-4 归因纠正(31d4c22 提交说明里那两行是错的,以本条为准):
  - bootmenu 的 +1728 **不是**工具链代差,是 M23 源码(m2.29→m2.30)。证据:旧件
    `readelf -p .comment` 已是 clang 22.1.8(与新件同代);旧件版本串 `0.1.0-m2.29-takeover`,
    而钉值 commit 884d4c4 的源码已是 m2.30;用 6364498(m2.29 树)+ 今天的工具链重编得
    157108/0507739d,与旧钉值件逐字节相同。
  - launcherd 的 −512 也不是编译器:新旧 .comment 集合一致(那道 21.1.8 来自 meow_ui.a 里的
    meow_font.o),真实原因是 SDK 静态库从 86800633 换成 cc0ed49b——用 58cdb73 源码 +
    86800633 的 .a 重编得 894940/cea0a735,与旧钉值件逐字节相同。
  - 因此**只有 meow_audiod 真有工具链代差**(旧 clang/LLD 21.1.8 → 新 22.1.8)。

P2-2 主 checkout 定位:`git rev-parse --git-common-dir` 给的是主仓库 .git 的**绝对**路径,
  父目录才是主 checkout;旧版把绝对路径当相对路径拼到 $ROOT 下,`cd` 失败被 `set -e`
  直接终止 → 干净 worktree 里静默 exit 1。现为 `cd "$_gcd/.."` + 全部 `|| true`,
  找不到 meow_ui.a 时**先**打印诊断(缺什么、试过哪些路径、怎么覆盖)再退出。

P2-3 .tools 兜底层级:旧版把 $COMPAT_HOME/Project/R3ProII 指向 ROOT,脚本里的
  `$HOME/Project/R3ProII/.tools` 就落到 `<checkout>/.tools`(干净 worktree 不存在 → 127)。
  现在造一个真目录,只放 `.tools -> ~/.tools` 与 `patch_v2 -> $ROOT/patch_v2`;
  零手工准备即可开箱重编。README 措辞同步改准。

P2-5 门禁假绿:test_time32_abi.sh 的退出码现计入 FAIL,脚本缺失也记 FAIL。
  失败桩自证:`PASS=33 FAIL=1`、exit 1(原为 PASS=33 FAIL=0 / exit 0)。

P2-6 desc:meow_audio 的 `volume` → 真实子命令 `status / tone / route / vol / output / monitor`
  (并避开 `|`,否则破坏清单 4 字段格式);bootmenu 的读取键改为 display.brightness
  (display.brightness_min 只是下限 clamp);netmgrd 去掉「以太网连接」的夸大说法。
2026-11-11 21:02:09 +08:00

159 lines
9.7 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` → `fw_apps/devkit/`。与固件打包无关,独立跑。详见 `DEVKIT.md`。 |
| `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 /home/Aska/Project/R3ProII
# 用默认配置打包,版本号 0.7.68,输出 r3proii_m2_73.upt
bash scripts/build/build_fw_apps.sh -v 0.7.68 -o r3proii_m2_73.upt
# 用指定配置(并存多套调试/场景配置时)
bash scripts/build/build_fw_apps.sh -c scripts/build/fw_content.conf -v 0.7.68 -o r3proii_m2_73.upt
# 指定基线目录(默认 fw_ssh/squashfs-root)
bash scripts/build/build_fw_apps.sh -v 0.7.68 -o r3proii_m2_73.upt -b fw_ssh/squashfs-root
```
### 参数
| 参数 | 必填 | 说明 |
|---|---|---|
| `-c, --config` | 否 | 清单路径,默认 `scripts/build/fw_content.conf`。传别的路径即用另一套配置(互不覆盖)。 |
| `-v, --version` | **是** | 版本号(如 `0.7.68`),写入固件 `/etc/meowos_version`。 |
| `-o, --out` | **是** | 输出 `.upt` 路径(如 `r3proii_m2_73.upt`)。若指向仓库内 `fw_apps/` 下(非 `out/`),自动并入 `fw_apps/out/` 归档。 |
| `-b, --base` | 否 | 基线根文件系统目录,默认 `fw_ssh/squashfs-root`。 |
### 产物去哪
- **工作区(每次清理重建)**:`fw_apps/build/` —— 组装 squashfs-root 树,用后即弃。
- **产物归档(不受清理影响)**:`fw_apps/out/` —— 打包好的 `.upt` 固定放这,多次打包互不覆盖、不会误删。
> **重要**:`-o` 给相对路径时按"文件命名"即可(如 `-o r3proii_m2_73.upt`),脚本会自动归档到 `fw_apps/out/r3proii_m2_73.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`,负责关机时显示该图)。二者不同,别混。
---
## 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` 已 `git add -f` 入库**(这几个是仓库侧应保留的脚本/配置/说明);其余(`fw_apps/` 产物、devkit 编译树等)不入库。
---
## 6. 每次打固件的最小步骤
```bash
# 1. 确认要进的组件 md5 无变化(若改了源码先更新 fw_content.conf)
md5sum patch_v2/meow_launcherd/meow_launcherd patch_v2/meow_svc_power/meow_svc_power
# 2. 打包(版本号 + 输出名)
bash scripts/build/build_fw_apps.sh -v 0.7.68 -o r3proii_m2_73.upt
# 3. 看结果:0 diff、体积 ≤ 上限、最终固件 md5
# 产物在 fw_apps/out/r3proii_m2_73.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`。