Files
MeowOS-For-R3P2/scripts/build/DEVKIT.md
T
AskaEth adaed09f94 fix(devkit): M24 r2 评审 — 交付完整性闸门 + 补 sysctl + time64 文档更正
P2-1(与 P1 同类):licenses/ 与 README 缺失仍会假成功。
- 新增 meta_complete()/verify_meta():MANIFEST + README + 五份许可证副本
  (procps COPYING/COPYING.LIB、ncurses、lsof、musl-COPYRIGHT)缺一即不完整
- 纳入 skip 条件与 --verify-only;产物未变但 meta 缺失时就地 write_meta 补全(不重编),
  构建树不在则退回全量重建
- 回归测试新增 T6(删 licenses 后 --with-sources 必须恢复)、T7(--verify-only 必须拒绝)、
  T8(删 README 后恢复);共 20 项全过

P2-2:README.txt/MANIFEST.txt 的卡上路径全错(写成 ../src、scripts/build/…)。
- 全部改为卡内相对路径:src/、licenses/、MANIFEST.txt、src/DEVKIT.md、src/build_devkit.sh
- README 增加「目录内容」段并注明 src/ 是生成目录、勿手放文件

P2-3:valgrind 的排除理由(“无 MIPS32 后端”)是错的 —— 官方支持 MIPS32/Linux。
- 改为「未尝试」:交叉构建需 autotools + 目标 vDSO 细节、产物 10MB+,56MB 单核不实用

P2-4:busybox 1.31 实测有 pgrep/kill/killall,没有 pkill、没有 sysctl。
- 表格改准确;pgrep 保留(增量有限不交付);pkill 写明「busybox 无此 applet,
  killall 只能部分替代,本轮未做」
- 新增交付 sysctl(procps 4.0.4,148184 B,静态):MANIFEST/verify-only/真机
  (sysctl -a 428 键、kernel.hostname/panic 读取、-n)均已验证

P2-5:free -s <小数> 也受 time64 影响(usleep 亚秒被抹平),文档说反了。
- DEVKIT §9 增加一行(free -s 0.5 实测 0s、free -s 1 实测 1s);README 同步;
  “收益只有 vmstat -t 一列”改为包含 free -s

P3:
1. §9 机制改准:内核只写 8 字节 → tv_sec 高 32 位是内核写入的 nsec、offset 8 的
   tv_nsec 才是未初始化;nanosleep 是把 tv_sec 高半字当 nsec 读(0)
2. 删掉脚本里 top 的旧错误归因(时长溢出/59.4 GiB),与 DEVKIT 对齐
3. 测试耗时改为「热缓存约 15s,冷启动 1–2 分钟」(实测 28s 含多次构建/修复路径)
4. --verify-only 依赖清单写全(file/readelf/sha256sum/awk/sed/grep/wc/cut/basename)
5. licenses/ 增加 musl-COPYRIGHT(zig env → libc/musl/COPYRIGHT,取不到即失败),§6 补一行
6. htop 说明改准:亚秒刷新走 ncurses halfdelay()(select + 32 位 timeval),大概率不受
   time64 影响;受影响的是时钟显示与部分采样(仍注明未做运行时验证)
7. README/脚本注明 src/ 是生成目录
8. LGPL 摘要改为「源码(§6a) 或 共享库(§6b) 或 书面要约(§6c)」
9. ltrace/sysstat 从「不可行」改为「未做(成本高)」,与 perf 的硬阻塞区分

验证:test_build_devkit.sh 20/20;--verify-only 通过(7 个二进制 + MANIFEST + 5 份许可证);
独立工作区离线重建 64s/0 下载,七个 sha256 与前一次逐字节一致;设备实测 sysctl 与其余六项正常。
2026-11-06 19:53:45 +08:00

22 KiB
Raw Blame History

MeowOS devkit — 静态 MIPS32r2 调试工具集

TF 卡 MeowOS/opt/devkit/bin/ 里那批静态二进制的构建说明、可行性实测、许可证留痕。 构建入口:bash scripts/build/build_devkit.sh;回归测试:bash scripts/build/test_build_devkit.sh (热缓存约 15 秒;冷启动需先重建基线,1–2 分钟)。 产物在 fw_apps/devkit/,已被 .gitignore 的 fw_apps/ 规则覆盖,不入库。

1. 为什么要有这个

设备(HiBy R3 Pro II / Ingenic X1600 / MIPS32r2 / Linux 4.4.94+ / 单核 / 56 MB)自带 busybox 1.31.1:free / ps / top / lsof 是 busybox 的软链(实测 /bin/ps -> busybox、 /usr/bin/{free,lsof,top} -> ../../bin/busybox),字段残缺;vmstat、slabtop、pmap、 sysctl 没有对应 applet(busybox --list 实测:有 pgrep/kill/killall,无 pkill/sysctl)。 做内存分析时最缺的正是:

  • slabtop —— Slab 总量 ~11 MB 到底被谁占了(buffer_head / dentry / squashfs_inode…)
  • vmstat —— 系统级趋势(r/b、si/so、in/cs、us/sy/id/wa),busybox 无替代
  • 真版 lsof —— busybox lsof 只有 pid/fd/设备号,没有 SIZE/OFF、TCP 状态、NAME

所以本工具集只围绕「这台机器的真实调试痛点」,不做大而全。

2. 产物清单

全部:ELF 32-bit LSB executable, MIPS, MIPS32 rel2, statically linked, stripped, readelf -d 零 NEEDED(musl libc 静态链入),可直接从 exFAT 卡上跑。

工具 来源版本 许可证 体积(B) 用途 / 相对 busybox 的增量
slabtop procps-ng 4.0.4 GPL-2.0-or-later(依赖 libproc2 LGPL-2.1+) 394 408 Slab 明细;-o 一次性输出不需要 TTY/terminfo
vmstat procps-ng 4.0.4 同上 216 924 系统趋势;busybox 无;-t 时间戳列本工具链下为空,见 §9
ps procps-ng 4.0.4 同上 324 980 -eo pid,rss,vsz,comm --sort=-rss 等完整字段
pmap procps-ng 4.0.4 同上 173 460 地址空间映射(读 /proc/pid/maps);busybox 无
sysctl procps-ng 4.0.4 同上 148 184 读写 /proc/sys(-a 列出 428 个键);busybox 1.31 无此 applet
free procps-ng 4.0.4 同上 94 312 拆 buff/cache、available
lsof lsof 4.99.4 Purdue/BSD-style 789 496 SIZE/OFF、TCP 状态、NAME、-i 网络视图
合计 2 141 764 ≈ 2.1 MB

同目录还有 MANIFEST.txt(每个二进制的 sha256 + 版本 + 许可证 + 体积)、 licenses/(procps COPYING + COPYING.LIB、ncurses COPYING、lsof COPYING、musl COPYRIGHT)、 README.txt(上卡说明)。--with-sources 会额外生成 src/(三份源码包 + build_devkit.sh + 本文件)。

3. 上卡后怎么用

# 临时(SSH 会话)
export PATH=/usr/data/mnt/sd_0/MeowOS/opt/devkit/bin:$PATH

# 持久化:rootfs 的 /etc/profile.d/meow_card_path.sh 只前插了 MeowOS/opt/bin,
# devkit 是独立目录,需要再补一行(由塔/维护者决定是否进固件):
if [ -d /usr/data/mnt/sd_0/MeowOS/opt/devkit/bin ]; then
    export PATH="/usr/data/mnt/sd_0/MeowOS/opt/devkit/bin:$PATH"
fi

与 busybox 同名命令的先后关系(前插 PATH 时):

名字 现状(实测) 前插后
free lsof top /usr/bin/x -> ../../bin/busybox free/lsof 解析到 devkit 版;top 仍是 busybox(本工具集不提供)
ps /bin/ps -> busybox 解析到 devkit 版
vmstat slabtop pmap sysctl 不存在(busybox 无对应 applet) 新增

要临时用回 busybox 版:busybox free、busybox ps、busybox lsof。 不要覆盖 /usr/bin、/bin 里的软链:rootfs 是 ubifs,随固件回刷即被还原,而且这些软链是基线的一部分。

4. exFAT 语义(权限 / 软链)

设备挂载:/dev/mmcblk0 on /usr/data/mnt/sd_0 type exfat (rw, fmask=0022, dmask=0022, symlink=0, noexec 未设置)。

  • 无符号链接(symlink=0):本工具集全部是实体文件,不做 argv[0] 分派,也不提供 symlink (不像 busybox 那样一个多合一二进制 + 一堆软链)。
  • 无 Unix 权限位:fmask=0022 让卡上新文件恒为 0755,因此不需要 chmod—— 反过来说 chmod 在这里本身是 no-op;卡上也表达不了 setuid,任何需要 setuid 的工具都不适合放这。
  • 可执行性:挂载参数里没有 noexec,且卡上现有 MeowOS/opt/MeowPanel/meowpanel 就是 0755 直接执行的。 本轮真机验证是在设备 /tmp(同为 MIPS 目标、root 身份)做的,没有往卡上写过任何东西(约定:卡由塔推)。

5. 重跑代价与可复现性

  • 联网次数:冷启动 3 次(ncurses / procps-ng / lsof 各一个 tarball,共 5.5 MB); 源码包按 sha256 校验后落在 $MEOW_DEVKIT_WORK/src/,此后重跑 0 次联网。
  • 耗时(8 核宿主实测):冷启动(含 3 次下载)80–86 秒;源码已缓存时全量重编 60–85 秒; stamp 命中(脚本、版本、zig 版本都没变)2–3 秒;回归测试热缓存 约 15 秒(冷启动基线另算)。
  • --verify-only:只做静态/架构/NEEDED 检查 + MANIFEST 逐条 sha256/体积比对 + MANIFEST/README/licenses 完整性检查。不需要 zig、make、date、网络; 实际依赖 file、readelf、sha256sum、awk、sed、grep、wc、cut、basename。
  • stamp 内容:脚本 sha256 + zig 完整版本(0.17.0 / 0.17.1 会区分)+ target + 内核版本 + 三个上游版本。
  • 可复现(逐字节):在两个不同工作区各建一次,七个二进制 sha256 完全相同 (ps 用 -ffile-prefix-map 抹掉绝对源码路径;lsof 用裸名 CC=zigcc + 相对源码路径, 不再把工具链/构建目录写进 LSOF_CC/LSOF_CCFLAGS)。MANIFEST.txt 里的 sha256 与设备上 sha256sum 的结果一致,可用来核对「跑的到底是哪个二进制」。
  • skip 的完整条件:stamp 未变 且 七个 bin 通过静态/架构自检 且 MANIFEST 与 bin 逐条一致 且 MANIFEST/README/licenses 齐全。任一不满足就补(meta 缺失时直接重写 meta,不必重编)或重建。

6. 许可证与分发合规(重点)

上游 许可证 分发二进制时的义务
procps-ng 4.0.4(apps) GPL-2.0-or-later 提供完整对应源码(GPLv2 §3),含 "scripts used to control compilation and installation"
procps library/(libproc2) LGPL-2.1+ ps/vmstat/slabtop/free/pmap/sysctl 静态链接了它 → LGPL-2.1 §6 另有要求,见下
ncurses 6.5 MIT 风格(X11) 保留版权与许可声明;只静态链入 slabtop,不单独分发
lsof 4.99.4 Purdue Research Foundation 许可(BSD 风格 4 条) 文档与源码中保留作者/Purdue 署名;改过的版本要标注
musl(zig 0.17 自带) MIT 七个产物都静态链入了它 → 随副本保留版权与许可声明(licenses/musl-COPYRIGHT)

GPLv2 §3:build_devkit.sh 里的固定版本 + 下载 URL 不构成合规。URL 作者可能撤、 镜像可能消失,而且 GPL 要求的是分发者提供的源码或书面要约。因此 --with-sources 会把 三份源码包 + build_devkit.sh + 本文件一起放进 src/(合计约 5.6 MB)。少一样都不算完整: 没有构建脚本,收卡人拿不到本轮用的 configure/-D 参数(这正是 "corresponding source" 明确包含的)。

LGPL-2.1 §6(静态链接):六个 procps 工具静态链入 libproc2,除 GPL 义务外还必须 「显著提示使用了该库 + 附许可证副本 + 三选一」: (§6a) 随作品提供该库的完整源码(含修改); (§6b) 改用共享库机制(静态交付做不到); (§6c) 书面要约(≥3 年)提供 §6a 的材料。 本工具集走 §6a:src/procps-ng-4.0.4.tar.xz 含 library/ 全量源码, src/build_devkit.sh 是本轮的唯一构建描述,licenses/procps-ng-4.0.4-COPYING.LIB 是许可证副本。 若想更保守(收卡人不想自己重编),可再额外提供可重链接的 .o(当前未做,属可选加固)。

musl(MIT):MIT 要求在副本中保留版权与许可声明,因此 licenses/musl-COPYRIGHT 是必需项 (构建脚本从 zig env 的 lib_dir/libc/musl/COPYRIGHT 取,取不到直接失败)。

结论:内部自用不触发分发义务;但既然这批二进制可能被拷来拷去,建议一律 --with-sources 上卡。licenses/ 只是声明留痕,不能替代源码义务。

7. 未交付清单(以及为什么)

候选 结论 原因
top(procps 4.0.4) 不交付 表头时钟被工具链 time64 问题打坏(显示 -1202590843:00 一类),无 TTY 时还会静默 exit 1。不是 procps 的 bug(r1 评审已更正我此前的错误归因),根因见 §9。卡上已有 htop,top 属重复
htop 不构建 卡上 MeowOS/opt/bin/htop 已是 3.5.3(673 744 B)。实测用 zig + 自编 ncursesw 也能编出 3.5.3,但 strip 后 756 908 B,比现有版本更大(静态链 musl+ncurses)。未做运行时验证;按代码路径,它的亚秒刷新走 ncurses halfdelay()(内部 select() + 32 位 struct timeval),大概率不受 §9 的 time64 影响,真正会受影响的是时钟显示(localtime_r/clock_gettime)与部分采样
watch 不构建 busybox 1.31 已有 watch;procps 版 403 KB,收益不抵体积
pgrep 不构建 busybox 已有 pgrep;procps 版 260 KB(链接整份 libproc),增量有限
pkill 不构建 busybox 没有 pkill applet(只有 kill/killall,killall 只能部分替代);procps 版 260 KB,本轮未做
uptime/tload/pidof/pidwait/w 不构建 busybox 已有 uptime/pidof;tload/w 在本机无调试价值
perf 不可行 依赖目标内核源码树(tools/perf 要按内核版本配 perf_event_attr),没有内核头,属硬阻塞
valgrind 未尝试 valgrind 支持 MIPS32/Linux(官方平台页有 MIPS32/MIPS64),所以不是「无后端」;但交叉构建需 autotools 工具链 + 目标内核/vDSO 细节,产物通常 10 MB+,在 56 MB 单核设备上不实用。本轮未做可行性验证
ltrace 未做(成本高) 需要 libelf + 复杂 autoconf 探测,且本机程序多为静态/精简;属投入产出判断,不是「不可能」
sysstat(sar/iostat/mpstat) 未做(成本高) autoconf 探测多、依赖 gettext/libsensors 等;本机单核、/proc/diskstats 对 TF 卡意义有限
gdb 不建议 设备已带 gdbserver,宿主侧可用交叉 gdb 连;在 56 MB 单核设备上跑 gdb 本体收益极低、体积巨大
smem 价值为零 依赖 /proc/<pid>/smaps 的 PSS,本机没有 smaps

pmap 的低价值要说明白:本机 CONFIG_PROC_PAGE_MONITOR=n,/proc/<pid>/smaps 不存在, 所以 pmap -x 拿不到 PSS/私有脏页。它仍有用的一点是 /proc/<pid>/maps 存在, pmap <pid> 能列出地址段 + 映射文件名(busybox 没有等价物),排查「谁映射了这块内存」够用。

8. 可行性实测记录(编不出来的卡在哪)

宿主:Termux/Android aarch64,zig 0.17.0(自带 musl libc 与头文件),make、curl、pkg-config。 没有 autoconf/automake/libtool,没有目标内核头,sysroot 里只有 zlib(本工具集不需要它)。

  • procps-ng 4.0.4 ✅ 可编(vmstat/slabtop/free/ps/pmap/sysctl 全部产出)。三个必须处理的坑:
    1. slabtop(src/slabtop.c 直接 #include <ncurses.h>)硬依赖 ncurses; configure --without-ncurses 会把它整个跳过 → 要 slabtop 就必须先交叉编 ncurses。
    2. 交叉编译下 autoconf 的 malloc(0)/realloc(0) 运行期探测无法执行,不缓存 ac_cv_func_malloc_0_nonnull=yes ac_cv_func_realloc_0_nonnull=yes 会引入 rpl_malloc/rpl_realloc 未定义引用,链接失败。
    3. 必须把 PKG_CONFIG_LIBDIR 收紧到自编 prefix,否则会捡到宿主 aarch64 的 ncursesw.pc,结果是「musl 头 + bionic 头」混编(watch 直接编不过)。脚本里有事后断言。
  • ncurses 6.5 ✅ 可编(--without-shared --with-normal --enable-widec --without-progs 等)。 必须 --with-default-terminfo-dir=/usr/share/terminfo --with-terminfo-dirs=...: 否则交互式 slabtop 会 Error opening terminal: xterm.(默认值是编译期 prefix,设备上不存在)。 体积代价:libncursesw.a 3.3 MB(未 strip,不单独分发),链进 slabtop 后只增加约 100 KB。
  • lsof 4.99.4 ✅ 可编。坑:
    1. 4.99 源码包不带 configure(autotools),但带老式 Configure 脚本,./Configure -n linux 可用。
    2. 版本探测读宿主 /usr/include/linux/version.h + uname,交叉时拿不到 4.4.94, 会退化成 LINUXV=00000 / LSOF_VSTR="0.0.0"(Configure 打 "unsupported dialect or version")。 这两个宏在 linux dialect 里只影响 lsof -v 显示,仍用 -DLINUXV/LSOF_VSTR 覆盖成 4.4.94。
    3. zig 的 musl 头没有 glibc 侧经由 linux/tcp.h 间接带来的 TCP_ESTABLISHED 等 11 个 状态宏,dsock.c 会编不过 → 脚本里 -D 补齐(值取自 linux/tcp.h)。
    4. zig cc 不带 -O 时按 Debug 编,会插入 UBSan 桩(__ubsan_handle_negate_overflow) 导致链接失败 → 所有编译都显式 -O2。
  • htop 3.5.3 ✅ 可编(用自编 ncursesw),strip 后 756 908 B —— 比卡上现有版本大, 且未做运行时验证,故不交付(见 §7)。
  • perf ❌ 不可行:依赖目标内核源码树/头文件。
  • valgrind ⚠️ 未尝试(支持 MIPS32/Linux,但交叉构建与体积/内存代价不划算;见 §7)。
  • ltrace / sysstat ⚠️ 未做(成本高,见 §7)。
  • smem ⚠️ 价值为零:依赖 smaps,本机没有。

9. 已知限制:工具链的 time64 在 4.4 内核上不可用

这不是 procps/htop 的 bug,是 zig 0.17 自带 musl 在 mipsel 上的 ABI 错配(r1 评审定根因, 我此前把 top 的表头问题误判成 procps bug,此处更正)。

机制(三段,均可复验):

  1. zig 0.17 的 mipsel-linux-musleabi 是 time64:sizeof(time_t)=8、sizeof(long)=4, struct timespec 16 字节;同时 clang 前端给 mips o32 预定义了 __ILP32__。

  2. zig 自带 musl(libc/musl/src/time/clock_gettime.c、time/clock_nanosleep.c 等)的守卫写成 #if defined(SYS_*_time64) && !defined(__ILP32__);上游 musl 1.2.5 没有这个 !defined(__ILP32__)。

  3. MIPS o32 是 ILP32、内核 4.4 又没有 time64 syscall → 走 #else 分支,把 16 字节的 time64 结构 直接交给 32 位 time32 系统调用。内核按 {int32 tv_sec; int32 tv_nsec} 解释这 16 字节:

    • clock_gettime:内核只写前 8 字节 → 调用者的 tv_sec(offset 0..7)= sec | (nsec << 32), 高 32 位是内核写入的 nsec;而 offset 8 的 tv_nsec 完全没被写,保持未初始化 (评审 memset 0xAA 实测读到 nsec=0xAAAAAAAA)。
    • gettimeofday 同理:tv_sec 高半字是内核写入的 usec,offset 8 的 tv_usec 未初始化。
    • nanosleep:内核把 tv_sec 的高半字当 nsec 读(小秒数时为 0),调用者真正的 tv_nsec (offset 8)被忽略 → 亚秒被抹平、整秒正常。

真机实测(本轮):

现象 结果 影响
clock_gettime / time() / gettimeofday() rc=0 但值是垃圾(评审另测:sec=2823213556008072608,localtime_r 返回 NULL) 任何按墙钟格式化时间的功能
vmstat -t 表头有 -----timestamp-----,数据行该列整列为空(localtime() 返回 NULL) vmstat 核心的 3 组计数正常;只有时间戳列不可用
free -s 0.5 -c 2 实测 0 秒(应约 0.5 秒):free.c 用 usleep(interval),亚秒被抹平 小数间隔失效;free -s 1 -c 2 实测 1 秒,正常
top 表头时钟 显示 -1202590843:00 一类 §7 不交付 top 的原因
usleep(0.5s) ×10(独立探针) 实测 0 秒(应 5 秒) 亚秒轮询会退化成空转
sleep(1)(整秒) 正常:vmstat 1 3 墙钟实测 2 秒、vmstat 1 2 实测 1 秒 整秒采样周期不受影响
ps -eo lstart 正常 时间来自 /proc/stat 的 btime + jiffies,不走 libc 取时
slabtop/pmap/sysctl/lsof 不受影响 不显示墙钟、也不做亚秒等待

能否复用仓里已有的修复? 有。M16 的 patch_v2/sdk/meow_ui_time.c(文档 patch_v2/sdk/CLOCK_ABI.md) 用「链接期强定义」接管了 __clock_gettime / __clock_gettime64 / __nanosleep_time64 / __clock_nanosleep(_time64) / __timedwait* / __timerfd_* / __clock_settime64, 内部按内核 o32 time32 ABI 取数再升成 64 位。

  • 可复用的证据(本轮实测):zigcc -O2 -I. -Iinclude -c patch_v2/sdk/meow_ui_time.c 单文件编译成功, 未定义符号只有 5 个 libc 符号(__errno_location、__pthread_setcancelstate、__syscall_cp、 __udivdi3、syscall),不依赖 SDK 其它目标文件。
  • 代价:必须把该 .o 放在 libc 之前参与链接(才会盖掉 libc 里那份),要给两套构建系统分别注入: procps 走 libtool 的 LDADD、lsof 是手写 Makefile 的固定链接行;然后七个二进制全部重新真机验证。 估计 1–2 小时(含设备回归),产物每个 +几 KB。
  • 本轮为什么不做:收益是 vmstat -t 时间戳列 + free -s <小数> 两处(top 不交付、ps 本来正常、 其余不打时间),而这个改动会动到 libc 的取时/睡眠入口,风险面比收益大。 结论:可复用,但需要单独一条 mission 做「接入 + 全量回归」,不适合塞进修 P2 的补丁里。
  • 不加 shim 的替代方案:给 zig 的 musl 打补丁(去掉 !defined(__ILP32__))或换上游 musl 工具链。 这不是加一个 -D 能修的:守卫在 libc 源码里,编译产物(libc.a)已经固定。

10. 路径清洁:lsof 里有一处宿主路径(工具链副作用)

strings lsof 有一处 /data/data/com.termux/files/usr/etc/resolv.conf(其余六个产物没有宿主路径)。 来源是 Termux 打包的 zig 自带 musl(libc/musl/src/network/resolvconf.c 被改成 Termux prefix), 不是 lsof 源码,也不是本脚本的路径泄漏(源码路径已用 -ffile-prefix-map 抹掉)。

  • 设备上该路径不存在 → 真正的 DNS 反查会失败;lsof -i 不带 -n 时会因此卡在超时(实测约 3 秒), 带 -nP 瞬时返回。
  • 端口名/本机名不受影响(来自 /etc/services、/etc/hosts):实测 lsof -i 仍显示 TCP *:ssh、UDP localhost:domain。
  • 结论:不改。换成非 Termux 的 zig/上游 musl 需要重装工具链并重做全部验证,代价大而收益仅「反向 DNS」; 文档与 README.txt 已写明用 lsof -nP。

11. 真机验证证据(2026-11-06,root@10.76.208.50)

产物拷到设备 /tmp(tmpfs)执行,验证完已删除;没有往 TF 卡写过任何东西。

# slabtop -o | head -6
 Active / Total Objects (% used)    : 55852 / 61357 (91.0%)
 Active / Total Slabs (% used)      : 2794 / 2794 (100.0%)
 Active / Total Caches (% used)     : 57 / 81 (70.4%)
 Active / Total Size (% used)       : 11024.86K / 11593.48K (95.1%)
 Minimum / Average / Maximum Object : 0.02K / 0.19K / 32768.00K
  OBJS ACTIVE  USE OBJ SIZE  SLABS OBJ/SLAB CACHE SIZE NAME
 12474  10746  86%    0.06K    198       63       792K buffer_head

# vmstat 1 3   (墙钟实测 2 秒,采样间隔正常)
procs -----------memory---------- ---swap-- -----io---- -system-- -------cpu-------
 r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa st gu
 1  0      0   2584   8764  19388    0    0     0     0  449    6  3  3 94  0  0  0
 0  0      0   2644   8764  19388    0    0     0     0  340  566  1  5 94  0  0  0
 0  0      0   2644   8764  19388    0    0     0     0  332  526  1  2 97  0  0  0

# free -m
               total        used        free      shared  buff/cache   available
Mem:              55          30           2           1          27          24
Swap:              0           0           0

# ps -eo pid,rss,vsz,comm --sort=-rss
  PID   RSS    VSZ COMMAND
 1368  4832  16516 meow_launcherd
 4241  1608   3012 sh
 ...

# pmap 1
1:   init
00400000    864K r-x-- busybox
004e8000      4K rw--- busybox
00969000    132K rwx--   [ anon ]

# sysctl -a | wc -l        → 428(键数)
# sysctl kernel.hostname kernel.panic
kernel.hostname = meowos
kernel.panic = 10
# sysctl -n kernel.ostype  → Linux

# lsof -nP -i        (瞬时;不带 -n 约 3 秒,见 §10)
COMMAND    PID USER FD   TYPE DEVICE SIZE/OFF NODE NAME
dropbear  1354 root 3u  inet   2196      0t0  TCP *:22 (LISTEN)
meow_netm 1372 root 5u  inet   2611      0t0  UDP 127.0.0.1:53
meow_mdns 1375 root 3u  inet   2906      0t0  UDP *:5353
meowpanel 1395 root 3u  inet   2587      0t0  TCP *:8080 (LISTEN)
  • 七个二进制 --help/-V 全部正常(lsof --help 不是合法选项,lsof -v 打印 4.99.4)。
  • 交互式 slabtop(无 -o)在 TERM=xterm 下正常初始化 curses(stdout 写出 1599 字节转义序列); 对照 TERM=bogus-term 报 Error opening terminal: bogus-term. —— 说明 terminfo 路径确实命中 /usr/share/terminfo,不是内嵌 fallback。
  • 设备上 sha256sum 与 MANIFEST.txt 逐条一致(测的就是交付的那份字节)。
  • 宿主侧静态/架构自检、MANIFEST 对账、licenses 完整性:bash scripts/build/build_devkit.sh --verify-only。

12. 其它已知限制

  • pmap -x 无 PSS(无 smaps),只有 maps 级别的段/文件信息。
  • 不提供 top(§7/§9);需要交互式总览请用卡上已有的 htop(其时钟显示同样受 §9 影响,亚秒刷新走 select() 大概率正常)。
  • 二进制按设备内核 4.4.94 编 LINUXV;该宏只影响 lsof -v 显示,换内核不影响运行。
  • 产物是 32 位 MIPS32r2(o32 ABI),只适用于 X1600 这类 MIPS32r2 目标。
  • 卡上 src/ 是 --with-sources 的生成目录(每次整理会整体重建),不要往里手放文件。