用户原话:「开关都存在显示问题 我都不能判断它是不是真的开启还是关闭(包括 WiFi 页也是)」。
根因不是「没读到硬件态」,而是「读到/没读到都被拿去当用户意图的装饰」:
- bt_page.c:103 开关初值来自 settings 布尔;:112-114 下发后立刻 g_sys.bt_on = on(显示意图);
:129 c->bt_on = nm_bt_powered() 赋值后全文无人引用(M45 也独立发现)。
- wifi_page.c:40 读不到 settings 时默认 1(显示已开)。
- netmgrd 的 bt/wifi 查询本身把「问不到」塌缩成 0(nm_bt_powered/nm_wifi_connected)。
本单只解「状态可信」,不碰扫描/配对/音频(另有 M45/M46 单)。
1) 真实态三态(-1 未知 / 0 关 / 1 开)
- net.c 新增 net_bt_power_probe()(hciconfig hci0 UP/DOWN;无输出=未知)与
net_wifi_power_probe()(rfkill wlan soft/hard 汇总,回退 wlan0 IFF_UP;读不到=未知)。
- netmgr_ipc.c 新增 nm_bt_power_state()(daemon bt status 的 available/powered 权威,不可达
回退直连探测)与 nm_wifi_power_state()(netmgrd 的 wifi status 只有 wpa_state、不报射频态,
故取本地 rfkill——daemon 的 wifi on/off 改的就是同一份内核状态)。
- 两个子页的 top_sw/rows 只读这两个函数;settings 布尔降级为「意图持久化」,不再决定外观。
- 「读不到默认 1」删除:未知就是未知。
2) 点击 → 待确认 → 真实态定稿
- 纯函数 meow_toggle_{display,pending,rollback,error}(bt_page.c,无 I/O/UI):
只有 probe 确认才算收敛;probe 未知继续等,绝不因 last_real 恰好等于意图就宣布成功。
- 页面:落盘意图 → 下发 → 250ms 轮询(BT 上限 4s、WiFi 上限 5s;hciconfig 0.3~2s、
wifi_up.sh 起 supplicant/DHCP 更慢,故不用 20ms 级忙轮询)→ 真实态定稿;失败/超时把
settings 回滚到已确认真实态 + s_dd_modal 可见报错,不静默、不乐观。
- subpage.c:切换前先画「正在开启/关闭…(等待设备确认)」条(待确认态与稳定态可区分);
切换后回读 top_sw 定稿(取消原「点了就翻面」),live tick 也回读,外部改动驻留期间可见。
3) 第三态呈现(未知 ≠ 已关)
- SDK meow_switch 只有两态:未知时开关停「关」并在左侧画灰色「?」;行内另有
「蓝牙状态未知 / WiFi 开关状态未知」文字说明。选「?」是因为它不占用开关控件本身、
且「关+?」不会被读成「已关」。
4) 顺带修 net.c 三条开关失真(塔追加的 M45 盘点,同一病根)
- s_net_toggle_bt() 补 rfkill soft(与 netmgrd 的 bt on/off 同一语义;开:先 unblock 再 up;
关:先 down 再 block)。此前只发 hciconfig → 「BT 页关过再从头开」会被 rfkill 拦下。
- s_net_sync_from_sys() WiFi 判据从 wlan_connected()(已关联)改为射频态;BT 用三态,
读不到不写(旧写法把「网卡 up 未关联」写成 0,把未知写成已关)。
- rfkill 同类多节点(本机 2 wlan + 2 bluetooth)按「任一 block 即 block」读、全部写入。
测试(`bash patch_v2/meow_launcherd/build_launcher.sh test`,新增 test 入口)
- test_bt_page.c:P4 三态与未知占位、P5 收敛四例(达成/下发失败/超时/未知)、P6 收敛矩阵
12 组(真实开/关 × 下发成功/失败/超时 × probe 未知),全 PASS(64 条断言)。
- test_netmgr_ipc.c:新增 nm_bt_power_state 解析(powered=1/0、available=0、缺字段→-1)、
nm_wifi_power_state 透传、不可达回退=未知、wifi_rows 未知态占位;并修掉两处既有测试缺陷
(行内 UI 桩缺失导致本文件此前根本链不过;直连连接桩统一返回 "0\n" 导致等满 10s 必失败)。
- 交叉编译 0 warning(-Wall -Wextra,逐文件单独编 + 整链);launcherd 899388 B
md5 1c88661a9410ac1a4139304362281cdd,同 commit 同步 scripts/build/fw_content.conf 钉值。
真机(10.58.215.50,仅只读自检,未替换 /usr/bin/meow_launcherd、未刷机)
- 二进制放 /usr/data/mnt/sd_0/MeowOS/tmp/ 跑 --sysdump:exit 0,输出 wifi_on=1 / bt_seen=1
bt_on=0,与设备现状一致(rfkill 全 0 + wlan0 up + hci0 DOWN + netmgrd powered=0)。
- 卡上 du -s /usr/data/mnt/sd_0/Music 前后恒 199164544;临时文件已删;settings 未改。
- launcherd 在 squashfs 里 → 本改动需刷机生效。
已知不在本单:输出目标只写 settings(audiod 仅启动读一次)→ M45 finding / M46;
netmgrd 侧四处失真(未知当关、up 与 unblock 顺序、rfkill 只写首节点、wifi status 无射频字段)
已报 finding;设置主页/通知中心的开关显示仍是 settings(另立单)。
MeowOS 固件打包脚本使用说明(scripts/build/)
本目录是 MeowOS 固件打包的唯一入口。核心思想:只改配置文件,不改脚本。 新增/更新固件内容 → 改
fw_content.conf;打包 → 跑build_fw_apps.sh。 本文档防遗忘,覆盖常见场景与踩坑记录。
1. 文件一览
| 文件 | 作用 |
|---|---|
build_fw_apps.sh |
通用打包脚本(配置驱动)。读清单 → 组树 → repack → 校验 → 出固件。不要改它的逻辑,除非打包流程本身要变。 |
fw_content.conf |
固件内容清单(默认配置)。每行一条 ` |
build_devkit.sh |
TF 卡调试工具集交叉编译脚本(zig → 静态 MIPS32r2):vmstat/slabtop/free/ps/pmap/sysctl/lsof → fw_apps/devkit/。与固件打包无关,独立跑。详见 DEVKIT.md。 |
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. 用法
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
md5sum patch_v2/meow_launcherd/meow_launcherd
# → 9ca4c5e8a919f59cb2cdd6326da23065
把 fw_content.conf 里对应行 md5 替换成新值即可。
4. 打包流程做了哪些事(通用步骤)
脚本读清单之外,还会自动做这些固定动作(无需在清单里声明):
- 建树:复制基线
$BASE→fw_apps/build/squashfs-root。 - 校验基线:
usr/bin/hiby_player必须是 stock(md5a73f2c49…),否则中止(防 stock 被改坏)。 - 解析清单:逐条(md5 若有则强校验)→
cp -f→chmod 755,目录自动建。 - 写版本:
echo $VERSION > $DST/etc/meowos_version(单点版本号来源)。 - 外围 CLI 瘦身:从
/usr/bin移除白名单工具(curl socat tmux jq rsync nano htop ncdu file xxd——已迁 TF 卡MeowOS/opt/bin/)。 - 启动图/背包/关机 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/。 S99ssh→S84ssh:改名(内容不变),校验一致后删S99ssh(清单不含 S84)。- repack:
hiby_os_crack/scripts/repack.sh -i $DST -k unpacked_v14/xImage -o $OUT。 - 体积核对:rootfs 分区 ≤ 45,088,768 字节,超限中止。
- 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. 每次打固件的最小步骤
# 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。