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 与其余六项正常。
This commit is contained in:
1 parent
0531603779
commit
adaed09f94
4 files changed
+195
-84
No files matched your search
+78
-55
@@ -2,14 +2,16 @@
|
||||
|
||||
TF 卡 `MeowOS/opt/devkit/bin/` 里那批静态二进制的构建说明、可行性实测、许可证留痕。
|
||||
构建入口:`bash scripts/build/build_devkit.sh`;回归测试:`bash scripts/build/test_build_devkit.sh`
|
||||
(产物在 `fw_apps/devkit/`,已被 `.gitignore` 的 `fw_apps/` 规则覆盖,不入库)。
|
||||
(热缓存约 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` 干脆没有。做内存分析时最缺的正是:
|
||||
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 无替代
|
||||
@@ -28,13 +30,14 @@ busybox 1.31.1,`free / ps / top / lsof` 都是 busybox 的软链
|
||||
| `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` 网络视图 |
|
||||
| | | **合计** | **1 993 580 ≈ 1.9 MB** | |
|
||||
| | | **合计** | **2 141 764 ≈ 2.1 MB** | |
|
||||
|
||||
同目录还有 `MANIFEST.txt`(每个二进制的 sha256 + 版本 + 许可证 + 体积)、
|
||||
`licenses/`(上游 COPYING / COPYING.LIB)、`README.txt`(上卡说明)。
|
||||
`--with-sources` 会额外生成 `src/`(三份源码包 + `build_devkit.sh` + 本文件)。
|
||||
`licenses/`(procps COPYING + COPYING.LIB、ncurses COPYING、lsof COPYING、**musl COPYRIGHT**)、
|
||||
`README.txt`(上卡说明)。`--with-sources` 会额外生成 `src/`(三份源码包 + `build_devkit.sh` + 本文件)。
|
||||
|
||||
## 3. 上卡后怎么用
|
||||
|
||||
@@ -51,11 +54,11 @@ fi
|
||||
|
||||
**与 busybox 同名命令的先后关系**(前插 PATH 时):
|
||||
|
||||
| 名字 | 现状(实测软链) | 前插后 |
|
||||
| 名字 | 现状(实测) | 前插后 |
|
||||
|---|---|---|
|
||||
| `free` `lsof` `top` | `/usr/bin/x -> ../../bin/busybox` | `free`/`lsof` 解析到 devkit 版;`top` 仍是 busybox(本工具集不提供) |
|
||||
| `ps` | `/bin/ps -> busybox` | 解析到 devkit 版 |
|
||||
| `vmstat` `slabtop` `pmap` | 不存在 | 新增 |
|
||||
| `vmstat` `slabtop` `pmap` `sysctl` | 不存在(busybox 无对应 applet) | 新增 |
|
||||
|
||||
要临时用回 busybox 版:`busybox free`、`busybox ps`、`busybox lsof`。
|
||||
不要覆盖 `/usr/bin`、`/bin` 里的软链:rootfs 是 ubifs,随固件回刷即被还原,而且这些软链是基线的一部分。
|
||||
@@ -75,40 +78,45 @@ fi
|
||||
|
||||
- **联网次数**:冷启动 **3 次**(ncurses / procps-ng / lsof 各一个 tarball,共 5.5 MB);
|
||||
源码包按 sha256 校验后落在 `$MEOW_DEVKIT_WORK/src/`,此后**重跑 0 次联网**。
|
||||
- **耗时**(8 核宿主实测):冷启动(含 3 次下载)**80 秒**(两次实测 80s / 86s);
|
||||
源码已缓存时全量重编约 **65–85 秒**;`stamp` 命中(脚本、版本、zig 版本都没变)**1–2 秒**;
|
||||
`--verify-only` 秒级,且只依赖 `file` / `readelf` / `sha256sum` / `awk`(不需要 zig、make、date、网络)。
|
||||
- **耗时**(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 完全相同**
|
||||
- **可复现(逐字节)**:在两个不同工作区各建一次,七个二进制 **sha256 完全相同**
|
||||
(`ps` 用 `-ffile-prefix-map` 抹掉绝对源码路径;`lsof` 用裸名 `CC=zigcc` + 相对源码路径,
|
||||
不再把工具链/构建目录写进 `LSOF_CC/LSOF_CCFLAGS`)。`MANIFEST.txt` 里的 sha256 与设备上
|
||||
`sha256sum` 的结果一致,可用来核对「跑的到底是哪个二进制」。
|
||||
- `--verify-only` 除了静态/架构/NEEDED,还会把 `bin/` 六个文件与 `MANIFEST.txt` 的 sha256/体积
|
||||
**逐条比对**(只查 static/MIPS 是看不出内容漂移的)。
|
||||
- **回归测试**:`bash scripts/build/test_build_devkit.sh`(12 项,秒级,不重编)覆盖:
|
||||
stamp 命中时 `--with-sources` 必须产出完整 `src/`(r1 P1 的回归点)、src/ 缺文件/被改坏能自愈、
|
||||
`--verify-only` 能拒绝被篡改的 MANIFEST。
|
||||
- **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` **静态链接**了它 → LGPL-2.1 §6 另有要求,见下 |
|
||||
| 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 的义务外还必须
|
||||
「显著提示使用了该库 + 附许可证副本 + 三选一」:(a) 随作品提供该库的完整源码(含修改);
|
||||
(b) 改用共享库机制(静态交付做不到);(c) 书面要约(≥3 年)提供 (a) 的材料。
|
||||
本工具集走 **(a)**:`src/procps-ng-4.0.4.tar.xz` 里含 `library/` 全量源码,
|
||||
**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`(当前**未做**,属可选加固)。
|
||||
若想更保守(收卡人不想自己重编),可再额外提供可重链接的 `.o`(当前**未做**,属可选加固)。
|
||||
|
||||
**musl(MIT)**:MIT 要求在副本中保留版权与许可声明,因此 `licenses/musl-COPYRIGHT` 是必需项
|
||||
(构建脚本从 `zig env` 的 `lib_dir/libc/musl/COPYRIGHT` 取,取不到直接失败)。
|
||||
|
||||
**结论**:内部自用不触发分发义务;但既然这批二进制可能被拷来拷去,建议一律
|
||||
`--with-sources` 上卡。`licenses/` 只是声明留痕,**不能替代源码义务**。
|
||||
@@ -118,12 +126,17 @@ fi
|
||||
| 候选 | 结论 | 原因 |
|
||||
|---|---|---|
|
||||
| `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)。**且我此前只量了体积、没做运行时验证** —— 它会继承 §9 的 time64 问题(`htop -d 5`(0.5s)这类亚秒刷新会退化成忙等空转),所以「加个 build_htop() 即可」的说法不成立 |
|
||||
| `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`/`pkill` | 不构建 | busybox 已有;procps 版各 260 KB(链接整份 libproc) |
|
||||
| `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` 在本机无调试价值 |
|
||||
| `sysctl` | 不构建 | busybox 已有 `sysctl`(读写 `/proc/sys` 足够) |
|
||||
| `perf` / `valgrind` / `gdb` / `ltrace` / `sysstat` / `smem` | 不可行 | 见 §8 |
|
||||
| `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` **存在**,
|
||||
@@ -134,7 +147,7 @@ fi
|
||||
宿主:Termux/Android aarch64,zig 0.17.0(自带 musl libc 与头文件),`make`、`curl`、`pkg-config`。
|
||||
**没有** autoconf/automake/libtool,**没有**目标内核头,sysroot 里只有 zlib(本工具集不需要它)。
|
||||
|
||||
- **procps-ng 4.0.4** ✅ 可编。三个必须处理的坑:
|
||||
- **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)` 运行期探测无法执行,不缓存
|
||||
@@ -155,21 +168,16 @@ fi
|
||||
状态宏,`dsock.c` 会编不过 → 脚本里 `-D` 补齐(值取自 `linux/tcp.h`)。
|
||||
4. zig cc **不带 `-O` 时按 Debug 编**,会插入 UBSan 桩(`__ubsan_handle_negate_overflow`)
|
||||
导致链接失败 → 所有编译都显式 `-O2`。
|
||||
- **htop 3.5.3** ✅ 可编(用自编 ncursesw,`--disable-hwloc/sensors/delayacct`),strip 后 756 908 B ——
|
||||
比卡上现有版本大,且未做运行时验证(见 §7、§9),故不交付。
|
||||
- **perf** ❌ 不可行:依赖目标内核源码树(`tools/perf` 要按内核版本配 `perf_event_attr`),
|
||||
且设备内核未必开了相关选项;没有内核头也是硬阻塞。
|
||||
- **valgrind** ❌ 不可行:**没有 MIPS32 后端**(官方只支持 x86/amd64/arm/aarch64/ppc/s390),
|
||||
不是交叉编译问题。
|
||||
- **gdb** ❌ 不建议:设备已带 `gdbserver`,宿主侧可用交叉 gdb 连;在 56 MB 单核设备上跑 gdb 本体收益极低、体积巨大。
|
||||
- **ltrace** ❌ 不可行:需要 libelf + 复杂 autoconf 探测,且本机程序多为静态/精简,投入产出不划算。
|
||||
- **sysstat(sar/iostat/mpstat)** ❌ 未做:autoconf 探测多、依赖 `gettext`/`libsensors` 等,
|
||||
且本机单核、`/proc/diskstats` 对 TF 卡意义有限。
|
||||
- **smem** ⚠️ 价值为零:依赖 `/proc/<pid>/smaps` 的 PSS,本机没有 smaps。
|
||||
- **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 评审独立定根因,
|
||||
**这不是 procps/htop 的 bug,是 zig 0.17 自带 musl 在 mipsel 上的 ABI 错配**(r1 评审定根因,
|
||||
我此前把 `top` 的表头问题误判成 procps bug,此处更正)。
|
||||
|
||||
机制(三段,均可复验):
|
||||
@@ -179,19 +187,27 @@ fi
|
||||
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 系统调用**:内核只写/只读前 8 字节,高 32 位保持未初始化。
|
||||
直接交给 **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,`strftime` 被跳过) | `vmstat` 核心的 3 组计数**正常**;只有时间戳列不可用 |
|
||||
| `top` 表头时钟 | 显示 `-1202590843:00` / `-343597384:00` 一类 | 这就是 §7 不交付 top 的原因 |
|
||||
| `usleep(0.5s)` ×10 | **实测 0 秒**(应为 5 秒):`sleep()` 走 32 位 syscall,内核把 `tv_sec` 高半字当 `tv_nsec`(恒 0),亚秒被抹平 | 亚秒轮询会退化成忙等/空转 |
|
||||
| `sleep(1)`(整秒) | 正常:`vmstat 1 3` 墙钟实测 2 秒 | 整秒采样周期不受影响 |
|
||||
| `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`/`free`/`pmap`/`lsof` | 不受影响 | 不显示墙钟 |
|
||||
| `slabtop`/`pmap`/`sysctl`/`lsof` | 不受影响 | 不显示墙钟、也不做亚秒等待 |
|
||||
|
||||
**能否复用仓里已有的修复?** 有。M16 的 `patch_v2/sdk/meow_ui_time.c`(文档 `patch_v2/sdk/CLOCK_ABI.md`)
|
||||
用「链接期强定义」接管了 `__clock_gettime` / `__clock_gettime64` / `__nanosleep_time64` /
|
||||
@@ -202,17 +218,17 @@ fi
|
||||
未定义符号只有 5 个 libc 符号(`__errno_location`、`__pthread_setcancelstate`、`__syscall_cp`、
|
||||
`__udivdi3`、`syscall`),不依赖 SDK 其它目标文件。
|
||||
- **代价**:必须把该 `.o` 放在 libc 之前参与链接(才会盖掉 libc 里那份),要给两套构建系统分别注入:
|
||||
procps 走 libtool 的 `LDADD`、lsof 是手写 Makefile 的固定链接行;然后六个二进制全部重新真机验证。
|
||||
procps 走 libtool 的 `LDADD`、lsof 是手写 Makefile 的固定链接行;然后七个二进制全部重新真机验证。
|
||||
估计 1–2 小时(含设备回归),产物每个 +几 KB。
|
||||
- **本轮为什么不做**:收益只有 `vmstat -t` 一列(`top` 不交付、`ps` 本来正常、其余不打时间),
|
||||
而这个改动会动到 libc 的取时/睡眠入口,风险面比收益大。**结论:可复用,但需要单独一条 mission
|
||||
做「接入 + 全量回归」**,不适合塞进这次修 P1 的补丁里。
|
||||
- **本轮为什么不做**:收益是 `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`(其余五个产物没有宿主路径)。
|
||||
`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` 抹掉)。
|
||||
|
||||
@@ -260,6 +276,12 @@ Swap: 0 0 0
|
||||
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)
|
||||
@@ -268,16 +290,17 @@ 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)。
|
||||
- 七个二进制 `--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 对账:`bash scripts/build/build_devkit.sh --verify-only`。
|
||||
- 宿主侧静态/架构自检、MANIFEST 对账、licenses 完整性:`bash scripts/build/build_devkit.sh --verify-only`。
|
||||
|
||||
## 12. 其它已知限制
|
||||
|
||||
- `pmap -x` 无 PSS(无 smaps),只有 maps 级别的段/文件信息。
|
||||
- 不提供 `top`(§7/§9);需要交互式总览请用卡上已有的 `htop`(注意其时钟/亚秒刷新同样受 §9 影响)。
|
||||
- 不提供 `top`(§7/§9);需要交互式总览请用卡上已有的 `htop`(其时钟显示同样受 §9 影响,亚秒刷新走 `select()` 大概率正常)。
|
||||
- 二进制按设备内核 4.4.94 编 `LINUXV`;该宏只影响 `lsof -v` 显示,换内核不影响运行。
|
||||
- 产物是 32 位 MIPS32r2(o32 ABI),只适用于 X1600 这类 MIPS32r2 目标。
|
||||
- 卡上 `src/` 是 `--with-sources` 的**生成目录**(每次整理会整体重建),不要往里手放文件。
|
||||
Reference in new issue
Block a user