RustForge

foundry

Foundry OS: the operating system built on the Rustbelt kernel

foundry / scripts / compare-image.sh
3541 bytes ยท raw
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
#!/usr/bin/env bash
# M1 check: compare our image with the kernel's own disk.img, file by file.
# Both are GPT + FAT32; mtools reads the partition at byte offset 1 MiB
# (`-i image@@1M`), so nothing is mounted.
#
# Prints: the /bin program lists side by side (must be equal), the other
# files (must be equal, byte for byte), and for each program whether the
# bytes are identical. Rust programs built by Cargo are expected to differ
# in bytes from the kernel's single-file rustc builds (Cargo adds crate
# metadata), so only list equality and non-program files fail the check.
#
# Since M2 our image has more than the kernel's: Foundry OS's own programs
# (env FOUNDRY_BIN, left out of the list comparison), files of its own
# outside /bin (env FOUNDRY_FILES, paths relative to the image root, left
# out) and a "Foundry OS" block in scripts/selftest.sh (cut out before
# comparing that file).
#
# Usage: [FOUNDRY_BIN="prog ..."] [FOUNDRY_FILES="path ..."] scripts/compare-image.sh OURS KERNELS OUT_DIR
set -euo pipefail
fail=0
OURS=$1 THEIRS=$2 OUT=$(realpath -m "$3")/compare
export MTOOLS_SKIP_CHECK=1
rm -rf "$OUT" && mkdir -p "$OUT/ours" "$OUT/kernel"
mcopy -s -n -i "$OURS@@1M" '::/*' "$OUT/ours/"
mcopy -s -n -i "$THEIRS@@1M" '::/*' "$OUT/kernel/"

(cd "$OUT/ours/bin" && ls | LC_ALL=C sort) > "$OUT/bin-ours-all.txt"
grep -vxF -f <(printf '%s\n' ${FOUNDRY_BIN:-} '') "$OUT/bin-ours-all.txt" > "$OUT/bin-ours.txt" || true
echo "== Foundry OS's own programs (not in the kernel's image): ${FOUNDRY_BIN:-none}"
for p in ${FOUNDRY_BIN:-}; do [ -f "$OUT/ours/bin/$p" ] || { echo "   MISSING /bin/$p"; fail=1; }; done
for f in ${FOUNDRY_FILES:-}; do
    if [ -f "$OUT/ours/$f" ]; then echo "   Foundry OS file: $f (not compared)"; rm "$OUT/ours/$f"
    else echo "   MISSING $f"; fail=1; fi
done
# Our selftest.sh = the kernel's + a "Foundry OS" block; compare without it.
sed -i '/^# ---- Foundry OS ----$/,/^# ---- end Foundry OS ----$/d' "$OUT/ours/scripts/selftest.sh"
(cd "$OUT/kernel/bin" && ls | LC_ALL=C sort) > "$OUT/bin-kernel.txt"
echo "== /bin program list: ours $(wc -l < "$OUT/bin-ours.txt"), kernel $(wc -l < "$OUT/bin-kernel.txt")"
if diff -u "$OUT/bin-kernel.txt" "$OUT/bin-ours.txt"; then
    echo "   same list"
else
    echo "   LISTS DIFFER (- kernel, + ours)"; fail=1
fi

echo "== files outside /bin (must be byte-identical)"
(cd "$OUT/ours" && find . -path ./bin -prune -o -type f -print | LC_ALL=C sort) > "$OUT/files-ours.txt"
(cd "$OUT/kernel" && find . -path ./bin -prune -o -type f -print | LC_ALL=C sort) > "$OUT/files-kernel.txt"
if ! diff -u "$OUT/files-kernel.txt" "$OUT/files-ours.txt"; then fail=1; fi
while read -r f; do
    if [ -f "$OUT/kernel/$f" ] && cmp -s "$OUT/ours/$f" "$OUT/kernel/$f"; then echo "   same      $f"
    else echo "   DIFFERENT $f"; fail=1; fi
done < "$OUT/files-ours.txt"

echo "== /bin bytes (Rust programs from rust/ may differ: Cargo vs plain rustc)"
same=0 diff=0
while read -r p; do
    [ -f "$OUT/kernel/bin/$p" ] || continue
    a=$(stat -c %s "$OUT/kernel/bin/$p") b=$(stat -c %s "$OUT/ours/bin/$p")
    if cmp -s "$OUT/kernel/bin/$p" "$OUT/ours/bin/$p"; then
        printf '   same      %-12s %8d bytes\n' "$p" "$a"; same=$((same + 1))
    else
        printf '   different %-12s %8d -> %8d bytes\n' "$p" "$a" "$b"; diff=$((diff + 1))
    fi
done < "$OUT/bin-ours.txt"
echo "== $same identical, $diff different in bytes; extracted trees in $OUT"
[ $fail = 0 ] && echo "[compare] OK: same program list and same non-program files" || { echo "[compare] FAILED"; exit 1; }