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
@@ -8,7 +8,7 @@
|
||||
# musl 交叉编出完全静态的二进制,放进 TF 卡供开发调试。
|
||||
#
|
||||
# 产物(全部静态链接、strip 过、无 NEEDED):
|
||||
# fw_apps/devkit/bin/{vmstat,slabtop,free,ps,pmap,lsof}
|
||||
# fw_apps/devkit/bin/{vmstat,slabtop,free,ps,pmap,sysctl,lsof}
|
||||
# fw_apps/devkit/MANIFEST.txt 版本/许可证/体积/校验摘要
|
||||
# fw_apps/devkit/licenses/ 各上游 COPYING(分发留痕)
|
||||
# fw_apps/devkit/README.txt 上卡后怎么加 PATH、和 busybox 的同名关系
|
||||
@@ -26,7 +26,7 @@
|
||||
# 许可证(二进制将来随卡分发时请保留此节):
|
||||
# procps-ng 4.0.4 GPL-2.0-or-later(COPYING=GPLv2)
|
||||
# *** 分发二进制必须提供对应源码(GPLv2 §3,含构建脚本)***
|
||||
# procps library/ LGPL-2.1+:ps/vmstat/slabtop/free/pmap 静态链接 libproc2,
|
||||
# procps library/ LGPL-2.1+:ps/vmstat/slabtop/free/pmap/sysctl 静态链接 libproc2,
|
||||
# LGPL-2.1 §6 要求提供可重链接 object code 或书面要约(见 DEVKIT.md §6)
|
||||
# ncurses 6.5 MIT 风格(X11 许可),保留版权声明即可
|
||||
# lsof 4.99.4 Purdue Research Foundation 许可(BSD 风格 4 条),
|
||||
@@ -83,7 +83,12 @@ SRC_LSOF="lsof-${LSOF_VER}.tar.xz|https://deb.debian.org/debian/pool/main/l/lsof
|
||||
SRC_STAGE_LIST="ncurses-${NCURSES_VER}.tar.gz procps-ng-${PROCPS_VER}.tar.xz lsof-${LSOF_VER}.tar.xz build_devkit.sh DEVKIT.md"
|
||||
|
||||
# 交付的工具——验证、MANIFEST 比对、stamp 自检都从这里取,避免多处手写漂移
|
||||
TOOL_NAMES="vmstat slabtop free ps pmap lsof"
|
||||
TOOL_NAMES="vmstat slabtop free ps pmap sysctl lsof"
|
||||
|
||||
# licenses/ 下必须存在的许可证副本(缺一个都算交付不完整):
|
||||
# procps 是 GPL-2.0+(COPYING)且 library/ 是 LGPL-2.1+(COPYING.LIB),
|
||||
# ncurses/lsof 是 MIT 风格 / Purdue,musl 是 MIT 且七个产物都静态链入了它。
|
||||
LICENSE_FILES="procps-ng-${PROCPS_VER}-COPYING procps-ng-${PROCPS_VER}-COPYING.LIB ncurses-${NCURSES_VER}-COPYING lsof-${LSOF_VER}-COPYING musl-COPYRIGHT"
|
||||
|
||||
FORCE=0
|
||||
CLEAN=0
|
||||
@@ -137,6 +142,13 @@ EOF
|
||||
ZIGCC="zigcc"
|
||||
info "zig $ZIG_VERSION → $WRAP_DIR/zigcc"
|
||||
|
||||
# 七个产物都静态链入了 zig 自带 musl(MIT),其 COPYRIGHT 要求随副本保留,
|
||||
# 所以构建时必须能拿到它,拿不到就明确失败(不能交付“缺许可证”的包)。
|
||||
ZIG_LIB_DIR="$("$zig_bin" env 2>/dev/null | sed -n 's/.*\.lib_dir *= *"\(.*\)".*/\1/p')"
|
||||
MUSL_COPYRIGHT="${ZIG_LIB_DIR}/libc/musl/COPYRIGHT"
|
||||
[ -s "$MUSL_COPYRIGHT" ] || die "找不到 musl 的 COPYRIGHT(zig lib_dir=$ZIG_LIB_DIR),无法留痕许可证"
|
||||
info "musl COPYRIGHT → $MUSL_COPYRIGHT"
|
||||
|
||||
for t in make curl tar sha256sum file readelf; do
|
||||
command -v "$t" >/dev/null 2>&1 || die "缺宿主工具: $t"
|
||||
done
|
||||
@@ -334,16 +346,17 @@ build_lsof() {
|
||||
# ---------------------------------------------------------------------------
|
||||
# 产出清单:<源路径>|<目标名>|<出处>|<许可证>
|
||||
# 只放「真机实测能跑且真有价值」的:vmstat/slabtop(busybox 没有)、
|
||||
# free/ps/pmap(busybox 版字段残缺)、lsof(busybox 版只有 pid/fd)。
|
||||
# 不交付 top:本机(32 位 MIPS + 4.4.94)上 procps 4.0.4 的 top 表头/内存单位
|
||||
# 输出明显错误(时长字段溢出、Mem 显示 59.4 GiB 而 MemTotal 只有 55 MB),
|
||||
# 且卡上已有 htop 3.5.3(673KB),top 属重复且不可信 → 见 DEVKIT.md「未交付清单」。
|
||||
# free/ps/pmap(busybox 版字段残缺)、sysctl(busybox 1.31 没有此 applet)、
|
||||
# lsof(busybox 版只有 pid/fd)。
|
||||
# 不交付 top:表头时钟被工具链 time64 打坏(不是 procps 的 bug,见 DEVKIT.md §9),
|
||||
# 且卡上已有 htop 3.5.3(673KB)→ 属重复且不可信。
|
||||
TOOLS="
|
||||
$BUILD_DIR/procps/src/vmstat|vmstat|procps-ng $PROCPS_VER|GPL-2.0-or-later
|
||||
$BUILD_DIR/procps/src/slabtop|slabtop|procps-ng $PROCPS_VER|GPL-2.0-or-later
|
||||
$BUILD_DIR/procps/src/free|free|procps-ng $PROCPS_VER|GPL-2.0-or-later
|
||||
$BUILD_DIR/procps/src/ps/pscommand|ps|procps-ng $PROCPS_VER|GPL-2.0-or-later
|
||||
$BUILD_DIR/procps/src/pmap|pmap|procps-ng $PROCPS_VER|GPL-2.0-or-later
|
||||
$BUILD_DIR/procps/src/sysctl|sysctl|procps-ng $PROCPS_VER|GPL-2.0-or-later
|
||||
$BUILD_DIR/lsof/lsof|lsof|lsof $LSOF_VER|Purdue/BSD-style
|
||||
"
|
||||
|
||||
@@ -404,6 +417,9 @@ write_meta() {
|
||||
|| die "复制许可证失败: ncurses COPYING"
|
||||
cp "$BUILD_DIR/lsof/COPYING" "$OUT_DIR/licenses/lsof-${LSOF_VER}-COPYING" \
|
||||
|| die "复制许可证失败: lsof COPYING"
|
||||
# musl:七个 procps/lsof 产物都静态链入了 zig 自带 musl(MIT),必须随副本留声明
|
||||
cp "$MUSL_COPYRIGHT" "$OUT_DIR/licenses/musl-COPYRIGHT" \
|
||||
|| die "复制许可证失败: musl COPYRIGHT($MUSL_COPYRIGHT)"
|
||||
|
||||
{
|
||||
echo "MeowOS devkit — 静态 MIPS32r2 调试工具集"
|
||||
@@ -423,14 +439,16 @@ EOF
|
||||
echo " ncurses $NCURSES_VER MIT-style sha256 $(printf '%s' "$SRC_NCURSES" | awk -F'|' '{print $3}')"
|
||||
echo " procps-ng $PROCPS_VER GPL-2.0+ / library=LGPL-2.1+ sha256 $(printf '%s' "$SRC_PROCPS" | awk -F'|' '{print $3}')"
|
||||
echo " lsof $LSOF_VER Purdue/BSD sha256 $(printf '%s' "$SRC_LSOF" | awk -F'|' '{print $3}')"
|
||||
echo " musl zig $ZIG_VERSION 自带(MIT) 许可证原文见 licenses/musl-COPYRIGHT"
|
||||
echo " (--with-sources 时)src/ 内还有 build_devkit.sh + DEVKIT.md(构建控制脚本,GPLv2 §3 要求)"
|
||||
echo " 下载地址与重编方法: scripts/build/build_devkit.sh(--with-sources 把上述文件放进 src/)"
|
||||
echo " 重编方法: src/build_devkit.sh(卡上路径;仓库里是 scripts/build/build_devkit.sh)"
|
||||
echo " 许可证原文: licenses/*-COPYING / licenses/*-COPYRIGHT;说明见 src/DEVKIT.md"
|
||||
echo
|
||||
echo "注意: procps-ng 是 GPL-2.0-or-later。把本目录随卡交付给第三方时,"
|
||||
echo " GPLv2 §3 要求提供对应源码(含构建脚本)—— 请用 --with-sources 带上 src/,"
|
||||
echo " 或随卡附书面要约(有效期 ≥3 年)。仅给出下载 URL 不构成合规。"
|
||||
echo " 另外 ps/vmstat/slabtop/free/pmap 静态链接了 LGPL-2.1+ 的 libproc2:"
|
||||
echo " LGPL-2.1 §6 要求提供可重链接的 object code 或书面要约,详见 DEVKIT.md §6。"
|
||||
echo " 另外 ps/vmstat/slabtop/free/pmap/sysctl 静态链接了 LGPL-2.1+ 的 libproc2:"
|
||||
echo " LGPL-2.1 §6 要求「源码(§6a) 或 共享库(§6b) 或 书面要约(§6c)」三选一,详见 DEVKIT.md §6。"
|
||||
} > "$OUT_DIR/MANIFEST.txt"
|
||||
|
||||
cat > "$OUT_DIR/README.txt" <<'EOS'
|
||||
@@ -446,9 +464,13 @@ MeowOS devkit — 设备端调试工具(静态 MIPS32r2)
|
||||
export PATH="/usr/data/mnt/sd_0/MeowOS/opt/devkit/bin:$PATH"
|
||||
fi
|
||||
|
||||
源码与许可证:
|
||||
若随卡分发了源码:源码(含构建脚本 build_devkit.sh、DEVKIT.md)在 ../src/;
|
||||
各上游许可证原文在 ../licenses/;版本/体积/sha256 见 ../MANIFEST.txt。
|
||||
目录内容(本文件所在目录就是 devkit 根):
|
||||
bin/ 可执行文件(实体文件,非软链)
|
||||
MANIFEST.txt 版本 / 许可证 / 体积 / sha256
|
||||
licenses/ 上游许可证原文(procps GPLv2 + LGPL-2.1、ncurses、lsof、musl)
|
||||
src/ 仅当随卡附带了源码(--with-sources)时存在:三份源码包 +
|
||||
build_devkit.sh + DEVKIT.md。**src/ 是生成目录,请勿手放文件。**
|
||||
说明文档:src/DEVKIT.md(若本源码未随附,见仓库 scripts/build/DEVKIT.md)
|
||||
|
||||
exFAT 没有 Unix 权限位(挂载 fmask=0022 → 新文件一律 0755),也没有符号链接。
|
||||
本目录里都是实体可执行文件,拷到卡上即可执行,无需 chmod,也不能用软链。
|
||||
@@ -456,8 +478,8 @@ exFAT 没有 Unix 权限位(挂载 fmask=0022 → 新文件一律 0755),
|
||||
而不是反复 chmod —— fmask=0022 下 chmod 本身是 no-op。
|
||||
|
||||
与 busybox 同名命令的关系(devkit/bin 前插 PATH 时生效):
|
||||
free ps lsof → 会被本目录版本覆盖(procps/lsof 字段更全)
|
||||
vmstat slabtop pmap → busybox 没有,直接新增
|
||||
free ps lsof → 会被本目录版本覆盖(procps/lsof 字段更全)
|
||||
vmstat slabtop pmap sysctl → busybox 1.31 没有这些 applet,直接新增
|
||||
要临时用回 busybox 版:busybox free / busybox ps / busybox lsof
|
||||
注意:/bin/ps -> busybox,/usr/bin/{free,lsof,top} -> ../../bin/busybox,
|
||||
所以“前插 devkit/bin”是唯一让新版本生效的方式(不要覆盖这些软链:
|
||||
@@ -469,15 +491,16 @@ rootfs 是 ubifs,随固件回刷会被还原,而且 busybox 软链是基线
|
||||
- slabtop -o(一次性输出)不需要 terminfo,也不要求 TTY;
|
||||
交互模式走 /usr/share/terminfo(设备已有 xterm 等条目;已编进 ncurses)。
|
||||
- 本工具链(zig 0.17 musl)在 4.4 内核上是 time64 ABI 错配:
|
||||
`vmstat -t` 的时间戳列会是**空**(localtime 返回 NULL)。
|
||||
vmstat 采样间隔、ps 的 lstart、slabtop/free/pmap/lsof 均正常。
|
||||
原因与后续修法见 ../src/DEVKIT.md「已知限制:工具链 time64」。
|
||||
* `vmstat -t` 的时间戳列会是**空**(localtime 返回 NULL)
|
||||
* `free -s 0.5`(小数间隔)会**立即返回**(亚秒等待被抹平);
|
||||
`free -s 1` 与 `vmstat 1 N` 的整秒间隔正常
|
||||
* ps 的 lstart、slabtop/pmap/sysctl 不受影响
|
||||
原因与后续修法见 src/DEVKIT.md「已知限制:工具链 time64」。
|
||||
- lsof 不带 -n 时会尝试反向解析(编译进 musl 的 resolv.conf 路径是构建机的,
|
||||
设备上不存在)→ 实测 `lsof -i` 约 3s 超时;请用 `lsof -nP`。
|
||||
- 不提供 top:见 ../src/DEVKIT.md(同样是 time64 问题,表头时钟溢出)。
|
||||
- 不提供 top:见 src/DEVKIT.md(同样是 time64 问题:表头时钟不可信)。
|
||||
EOS
|
||||
}
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# 主流程
|
||||
# ---------------------------------------------------------------------------
|
||||
@@ -518,16 +541,29 @@ main() {
|
||||
old_stamp=""
|
||||
fi
|
||||
|
||||
local bin_ok=1 mf_ok=0 n
|
||||
local bin_ok=1 mf_ok=0 meta_ok=0 n
|
||||
for n in $TOOL_NAMES; do
|
||||
[ -f "$BIN_DIR/$n" ] && verify_binary "$BIN_DIR/$n" >/dev/null 2>&1 || bin_ok=0
|
||||
done
|
||||
# 交付完整性也要一并作为 skip 条件:MANIFEST 缺失或与 bin 不符时宁可重建
|
||||
# 交付完整性也要一并作为 skip 条件:MANIFEST/许可证/README 缺失或与 bin 不符时
|
||||
# 宁可重建(与 P1 同类——不能因为“跳过编译”就让合规材料静默消失)。
|
||||
if [ -f "$OUT_DIR/MANIFEST.txt" ] && verify_manifest >/dev/null 2>&1; then
|
||||
mf_ok=1
|
||||
fi
|
||||
meta_complete && meta_ok=1
|
||||
|
||||
if [ "$FORCE" = 0 ] && [ "$cur_stamp" = "$old_stamp" ] && [ "$bin_ok" = 1 ] && [ "$mf_ok" = 1 ]; then
|
||||
# 产物本身没问题、只是 MANIFEST/README/licenses 被删:就地补,不必重编
|
||||
if [ "$FORCE" = 0 ] && [ "$cur_stamp" = "$old_stamp" ] && [ "$bin_ok" = 1 ] \
|
||||
&& { [ "$mf_ok" = 0 ] || [ "$meta_ok" = 0 ]; } \
|
||||
&& [ -d "$BUILD_DIR/procps-src" ] && [ -d "$BUILD_DIR/ncurses-src" ] && [ -d "$BUILD_DIR/lsof" ]; then
|
||||
log "产物未变,但 MANIFEST/README/licenses 不全 → 就地补全"
|
||||
write_meta
|
||||
if verify_manifest >/dev/null 2>&1; then mf_ok=1; else mf_ok=0; fi
|
||||
if meta_complete; then meta_ok=1; else meta_ok=0; fi
|
||||
fi
|
||||
|
||||
if [ "$FORCE" = 0 ] && [ "$cur_stamp" = "$old_stamp" ] && [ "$bin_ok" = 1 ] \
|
||||
&& [ "$mf_ok" = 1 ] && [ "$meta_ok" = 1 ]; then
|
||||
# P1 回归点:--with-sources 必须在这里就兑现,不能因为“跳过编译”而漏掉源码。
|
||||
# (曾经把这段放在 return 之后,结果 stamp 命中时静默不产出 src/,退出码仍是 0。)
|
||||
if [ "$WITH_SOURCES" = 1 ]; then
|
||||
@@ -588,6 +624,7 @@ collect_verify_existing() {
|
||||
verify_binary "$BIN_DIR/$n" && info "OK $n $(wc -c < "$BIN_DIR/$n") B" || bad=$((bad + 1))
|
||||
done
|
||||
verify_manifest || bad=$((bad + 1))
|
||||
verify_meta || bad=$((bad + 1))
|
||||
FAIL=$bad
|
||||
}
|
||||
|
||||
@@ -615,7 +652,30 @@ verify_manifest() {
|
||||
info "FAIL $n 体积与 MANIFEST 不一致($got_size vs $(wc -c < "$BIN_DIR/$n"))"; bad=$((bad + 1))
|
||||
fi
|
||||
done
|
||||
[ "$bad" = 0 ] && info "OK MANIFEST.txt 与 bin/ 六项 sha256/体积逐条一致"
|
||||
[ "$bad" = 0 ] && info "OK MANIFEST.txt 与 bin/ 逐条 sha256/体积一致"
|
||||
return $((bad > 0))
|
||||
}
|
||||
|
||||
# 交付完整性:MANIFEST + README + 五份许可证副本,缺一个都算不完整
|
||||
# (和 P1 同类:这些是合规/可用性的一部分,不能因为“跳过编译”就静默缺失)
|
||||
meta_complete() {
|
||||
local f
|
||||
[ -s "$OUT_DIR/MANIFEST.txt" ] || return 1
|
||||
[ -s "$OUT_DIR/README.txt" ] || return 1
|
||||
for f in $LICENSE_FILES; do
|
||||
[ -s "$OUT_DIR/licenses/$f" ] || return 1
|
||||
done
|
||||
return 0
|
||||
}
|
||||
|
||||
verify_meta() {
|
||||
local f bad=0
|
||||
[ -s "$OUT_DIR/MANIFEST.txt" ] || { info "FAIL 缺 MANIFEST.txt(版本/许可证/sha 无从核对)"; bad=$((bad + 1)); }
|
||||
[ -s "$OUT_DIR/README.txt" ] || { info "FAIL 缺 README.txt(上卡说明)"; bad=$((bad + 1)); }
|
||||
for f in $LICENSE_FILES; do
|
||||
[ -s "$OUT_DIR/licenses/$f" ] || { info "FAIL 缺 licenses/$f(许可证留痕)"; bad=$((bad + 1)); }
|
||||
done
|
||||
[ "$bad" = 0 ] && info "OK MANIFEST/README/licenses($(printf '%s' "$LICENSE_FILES" | wc -w) 份)齐全"
|
||||
return $((bad > 0))
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user