#!/bin/bash # build_fw_apps_m260.sh — 组装并打包 fw_apps 固件(M2.67:meow_svcd status 美化 agent-117; # launcher 含之前全部(字体索引/字重两级/全屏滑条)+ 按钮样式/滑条黑残快照 agent-118 侧(SDK/APP); # bootmenu/watchdog/mdns 复用未变;SDK meow_ui.a 不入固件;版本 0.7.54 → 0.7.62) # 基线: fw_ssh(stock v1.4 + SSH 工具集),相对 M2.59 r3proii_m2_59.upt: # - usr/bin/meow_bootmenu (M2.56,md5 536434c9:右下角版本读 /etc/meowos_version = 单点) # - usr/bin/meow_launcherd (最新,md5 a2b1c096:字体索引 index 写入 + 查列表降级+日志 + 字重两级 + 全屏滑条) # - usr/bin/meow_watchdog (M2.24,md5 ed711cc1,未变) # - usr/bin/meow_svcd (最新,md5 fb2d608b,status 配色美化 agent-117) # - usr/bin/meow_mdns (自研 IPv4-only mDNS 应答器,md5 b23de7ce,未变;agent-116 拆入 bins/) # - etc/init.d/S89meow_svcd <- 开机自启 svcd(-f 前台 + 重挂循环,失败不死);置于 S84ssh 后、S90 前。 # - etc/meowos_version = 0.7.62 # 注意:SDK 的全局状态栏 / 全局左缘返回 / 通知 IPC(meow_notify_ipc)在 meow_ui.a(patch_v2/sdk/)侧, # 由 APP 链接;固件不含 SDK 库,只含框架(launcher/bootmenu/watchdog/svcd/mdns)。SDK 不入固件。 # hello 等 SDK APP 走卡 MeowAPPs/ 热更新(build 惯例:不注入 usr/bin;搜索全部 m2xx 无 hello 拷贝)。 # 内容(相对 fw_ssh): # - usr/bin/meow_bootmenu <- 静态 MIPS 开机引导选单(M2.56,md5 536434c9…;链入 meow_touch.c) # - usr/bin/meow_launcherd <- MeowOS 主屏(最新,md5 a2b1c096…;静态链接 meow_touch.c + meow_settings.c + meow_ui.a/libz.a) # - usr/bin/meow_watchdog <- 应用看门狗(M2.24,md5 ed711cc1,全面按键接管,未变) # - usr/bin/meow_svcd <- 服务管理器(最新,md5 fb2d608b,status 配色美化) # - usr/bin/meow_mdns <- 自研 mDNS 应答器(md5 b23de7ce…) # - etc/meowos_version <- 版本号同源(0.7.62) # - etc/profile.d/meow_card_path.sh <- SSH 会话工具 PATH(M2.12 起) # - etc/init.d/S89meow_svcd / S90meow_bootmenu / S84ssh / S92_03_start_music_player / S95shutdown_logo # - etc/logo*.jpeg + etc/boot_animation/0.png + etc/shutdown_logo.jpeg(M2.1 补回) # 字库(font.png+font.idx,1.22MiB):放 TF 卡 MeowOS/fonts/(不动 rootfs)。固件不含字库。 # 明确: 无 S90meow_launcherd;S99ssh 已(改名 S84ssh);stock hiby_player 校验 a73f2c49。 # 外围 CLI 已迁至卡 MeowOS/opt/bin/(本固件不含;卡不在时工具不可用,框架不受影响)。 # 产物: fw_apps/r3proii_m2_67.upt set -e ROOT="$HOME/Project/R3ProII" SRC="$ROOT/fw_ssh/squashfs-root" DST="$ROOT/fw_apps/squashfs-root" BOOTMENU="$ROOT/patch_v2/bootmenu/meow_bootmenu" S90="$ROOT/patch_v2/bootmenu/S90meow_bootmenu" S92="$ROOT/patch_v2/bootmenu/S92_03_start_music_player" S95LOGO="$ROOT/patch_v2/bootmenu/S95shutdown_logo" LOGO_DIR="$ROOT/bootlogos" LAUNCHER="$ROOT/patch_v2/meow_launcherd/meow_launcherd" WATCHDOG="$ROOT/patch_v2/meow_watchdog/meow_watchdog" SVCD="$ROOT/patch_v2/meow_svcd/meow_svcd" MDNS="$ROOT/mips-repo/bins/meow_mdns/bin/meow_mdns" S89="$ROOT/patch_v2/meow_svcd/S89meow_svcd" SYSUI="$ROOT/patch_v2/meow_sysui/meow_sysui" NYAI="$ROOT/patch_v2/meowpkg/nyai" S70="$ROOT/patch_v2/meow_sysui/S70meow_sysui" CARD_PATH="$ROOT/patch_v2/meow_launcherd/meow_card_path.sh" OUT="$ROOT/fw_apps/r3proii_m2_67.upt" # 外围 CLI(自 rootfs /usr/bin 移除;已迁 TF 卡 MeowOS/opt/bin/) MIGRATE_TOOLS="curl socat tmux jq rsync nano htop ncdu file xxd" echo "==> 建树(复制 fw_ssh)" rm -rf "$ROOT/fw_apps" mkdir -p "$ROOT/fw_apps" cp -a "$SRC" "$DST" echo "==> 校验基线 player 为 stock" BASE_MD5=$(md5sum "$DST/usr/bin/hiby_player" | cut -d' ' -f1) [ "$BASE_MD5" = "a73f2c49a655659ef14db3bf6acecd78" ] || { echo "!!! hiby_player 不是 stock(a73f2c49): $BASE_MD5"; exit 1; } echo "==> 校验 launcher / bootmenu / watchdog(当前最新) + svcd/mdns" LM=$(md5sum "$LAUNCHER" | cut -d' ' -f1) WM=$(md5sum "$WATCHDOG" | cut -d' ' -f1) BM=$(md5sum "$BOOTMENU" | cut -d" " -f1) SM=$(md5sum "$SVCD" | cut -d' ' -f1) MM=$(md5sum "$MDNS" | cut -d' ' -f1) [ "$LM" = "a2b1c0962be3848c76f418f906721c03" ] || { echo "!!! launcher 非最新(a2b1c096): $LM"; exit 1; } [ "$WM" = "ed711cc192b9f770ed84b380b429afc6" ] || { echo "!!! watchdog 非 M2.24(ed711cc1): $WM"; exit 1; } [ "$BM" = "536434c9faa89a697d7e3da1c3657605" ] || { echo "!!! bootmenu 非 M2.56(536434c9, 版本读/etc/meowos_version): $BM"; exit 1; } [ "$SM" = "fb2d608b37b20fd000fddcac91e1c4a1" ] || { echo "!!! meow_svcd 非最新(fb2d608b, status 配色美化): $SM"; exit 1; } [ "$MM" = "b23de7ce54873e926e7601a3b21b66a9" ] || { echo "!!! meow_mdns 非 b23de7ce(自研 IPv4-only): $MM"; exit 1; } SS=$(md5sum "$SYSUI" | cut -d' ' -f1) NY=$(md5sum "$NYAI" | cut -d' ' -f1) [ "$SS" = "173013cc8f0899b3001d0b894ac0d9e6" ] || { echo "!!! meow_sysui 非 173013cc: $SS"; exit 1; } [ "$NY" = "e55149299a9a2763b974b53b0c093160" ] || { echo "!!! nyai 非 e5514929: $NY"; exit 1; } echo " launcher=$LM watchdog=$WM bootmenu=$BM svcd=$SM mdns=$MM sysui=$SS nyai=$NY ✓" echo "==> 新增/替换文件" cp -f "$BOOTMENU" "$DST/usr/bin/meow_bootmenu"; chmod 755 "$DST/usr/bin/meow_bootmenu" cp -f "$LAUNCHER" "$DST/usr/bin/meow_launcherd"; chmod 755 "$DST/usr/bin/meow_launcherd" cp -f "$WATCHDOG" "$DST/usr/bin/meow_watchdog"; chmod 755 "$DST/usr/bin/meow_watchdog" cp -f "$SVCD" "$DST/usr/bin/meow_svcd"; chmod 755 "$DST/usr/bin/meow_svcd" cp -f "$MDNS" "$DST/usr/bin/meow_mdns"; chmod 755 "$DST/usr/bin/meow_mdns" cp -f "$SYSUI" "$DST/usr/bin/meow_sysui"; chmod 755 "$DST/usr/bin/meow_sysui" cp -f "$NYAI" "$DST/usr/bin/nyai"; chmod 755 "$DST/usr/bin/nyai" echo "0.7.62" > "$DST/etc/meowos_version" cp -f "$S70" "$DST/etc/init.d/S70meow_sysui"; chmod 755 "$DST/etc/init.d/S70meow_sysui" cp -f "$S90" "$DST/etc/init.d/S90meow_bootmenu"; chmod 755 "$DST/etc/init.d/S90meow_bootmenu" cp -f "$S92" "$DST/etc/init.d/S92_03_start_music_player"; chmod 755 "$DST/etc/init.d/S92_03_start_music_player" cp -f "$S89" "$DST/etc/init.d/S89meow_svcd"; chmod 755 "$DST/etc/init.d/S89meow_svcd" # S99ssh -> S84ssh(内容不变,仅改名) cp -f "$SRC/etc/init.d/S99ssh" "$DST/etc/init.d/S84ssh"; chmod 755 "$DST/etc/init.d/S84ssh" rm -f "$DST/etc/init.d/S99ssh" echo "==> SSH 工具 PATH(profile.d,新增)" mkdir -p "$DST/etc/profile.d" cp -f "$CARD_PATH" "$DST/etc/profile.d/meow_card_path.sh"; chmod 755 "$DST/etc/profile.d/meow_card_path.sh" echo " meow_card_path.sh ✓" echo "==> rootfs 瘦身:移除外围 CLI(已迁卡)" for t in $MIGRATE_TOOLS; do if [ -e "$DST/usr/bin/$t" ]; then rm -f "$DST/usr/bin/$t"; echo " removed /usr/bin/$t"; fi done echo "==> 校验 S84ssh 与 S99ssh 原内容一致" diff -q "$SRC/etc/init.d/S99ssh" "$DST/etc/init.d/S84ssh" >/dev/null 2>&1 \ && echo " S84ssh == 原 S99ssh ✓" || { echo " !!! S84ssh 与 S99ssh 不一致"; exit 1; } [ ! -e "$DST/etc/init.d/S99ssh" ] && echo " S99ssh 已移除 ✓" || { echo " !!! S99ssh 仍存在"; exit 1; } echo "==> 启动图补回(M2.1):用户自定义 logo*.jpeg(覆盖 stock)+ boot_animation/0.png" cp -f "$LOGO_DIR/logo_new.jpeg" "$DST/etc/logo.jpeg"; chmod 755 "$DST/etc/logo.jpeg" cp -f "$LOGO_DIR/logo1_new.jpeg" "$DST/etc/logo1.jpeg"; chmod 755 "$DST/etc/logo1.jpeg" cp -f "$LOGO_DIR/logo2_new.jpeg" "$DST/etc/logo2.jpeg"; chmod 755 "$DST/etc/logo2.jpeg" mkdir -p "$DST/etc/boot_animation" cp -f "$LOGO_DIR/boot_anim_0.png" "$DST/etc/boot_animation/0.png"; chmod 644 "$DST/etc/boot_animation/0.png" echo " logo.jpeg/logo1.jpeg/logo2.jpeg + boot_animation/0.png ✓" echo "==> 关机 logo(M2.1):/etc/shutdown_logo.jpeg + S95shutdown_logo(rcK 停机制,待验证)" cp -f "$LOGO_DIR/shutdown_logo.jpeg" "$DST/etc/shutdown_logo.jpeg"; chmod 755 "$DST/etc/shutdown_logo.jpeg" cp -f "$S95LOGO" "$DST/etc/init.d/S95shutdown_logo"; chmod 755 "$DST/etc/init.d/S95shutdown_logo" [ -f "$DST/etc/shutdown_logo.jpeg" ] && echo " shutdown_logo.jpeg ✓" echo "==> 校验(新增文件)" md5sum "$DST/usr/bin/meow_bootmenu" "$DST/usr/bin/meow_launcherd" "$DST/usr/bin/meow_watchdog" \ "$DST/usr/bin/meow_svcd" "$DST/usr/bin/meow_mdns" \ "$DST/etc/meowos_version" "$DST/etc/init.d/S89meow_svcd" "$DST/etc/init.d/S90meow_bootmenu" \ "$DST/etc/init.d/S92_03_start_music_player" "$DST/etc/init.d/S84ssh" \ "$DST/etc/profile.d/meow_card_path.sh" \ "$DST/etc/logo.jpeg" "$DST/etc/logo1.jpeg" "$DST/etc/logo2.jpeg" \ "$DST/etc/boot_animation/0.png" "$DST/etc/shutdown_logo.jpeg" "$DST/etc/init.d/S95shutdown_logo" file "$DST/usr/bin/meow_bootmenu" "$DST/usr/bin/meow_svcd" "$DST/usr/bin/meow_mdns" echo "==> 工具移除核对(应无迁移目标残留)" for t in $MIGRATE_TOOLS; do [ -e "$DST/usr/bin/$t" ] && { echo " !!! 残留 $t"; exit 1; } || true done echo " ✓ 全部移除" echo "==> 保留核对(SSH/调试三件套)" for t in /usr/sbin/dropbear /usr/sbin/dropbearkey /usr/libexec/sftp-server /usr/bin/gdbserver /usr/bin/strace /usr/bin/sqlite3; do [ -e "$DST$t" ] && echo " ✓ $t" || { echo " !!! 缺失 $t"; exit 1; } done echo "==> init.d 启动链顺序 (S8/S9)" ls "$DST/etc/init.d/" | grep -E '^S(8|9)' | sort echo "==> repack" "$ROOT/hiby_os_crack/scripts/repack.sh" \ -i "$DST" \ -k "$ROOT/unpacked_v14/xImage" \ -o "$OUT" < /dev/null echo "==> 体积核对(rootfs 分区, 上限 45,088,768)" mkdir -p /tmp/fw_apps_chk && cd /tmp/fw_apps_chk rm -rf ota_v0 ota_update.in rootfs.squashfs 7z x -y "$OUT" ota_v0/ota_update.in > /dev/null 2>&1 RFSZ=$(grep -A1 'img_name=rootfs' ota_v0/ota_update.in | grep img_size | cut -d= -f2) echo "rootfs.squashfs = $RFSZ bytes (M2.11 为 44343296)" if [ "$RFSZ" -le 45088768 ]; then echo "OK <= 上限"; else echo "!!! 超上限"; exit 1; fi echo "==> rootfs.img md5" grep -A3 'img_name=rootfs' ota_v0/ota_update.in | grep img_md5 | cut -d= -f2 echo "==> unpack 回验(0 diff)" mkdir -p /tmp/fw_apps_rt && cd /tmp/fw_apps_rt rm -rf ota_v0 ota_config.in squashfs-root rootfs.squashfs rootfs.squashfs.* 7z x -y "$OUT" > /dev/null 2>&1 find . -name "rootfs.squashfs.*" | sort -V | xargs cat > rootfs.squashfs 2>/dev/null unsquashfs -no-progress -d squashfs-root rootfs.squashfs > /dev/null 2>&1 || true if diff -rq --no-dereference "$DST" squashfs-root > /tmp/fw_apps_rt_diff.log 2>&1; then echo "0 diff ✓" else echo "!!! diff found:"; head -20 /tmp/fw_apps_rt_diff.log exit 1 fi echo "==> 最终固件 md5" md5sum "$OUT" ls -la "$OUT"