RustForge

rust-kernel

Rustbelt: a hobby x86_64 kernel written in Rust

rust-kernel / scripts / boot-v2-check.sh
2705 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
#!/usr/bin/env bash
# Stage 21: boot contract v2, end to end. Boots the real (headless) kernel
# with the usual four data disks plus a writable copy of the GPT test disk
# (target/rootfs-gpt.img, made by build.rs), so main.rs finds the
# "Linux root (x86-64)" partition, mounts it at /, starts /sbin/init
# (user/inittest.c) as pid 1, and ends the run with init's exit status.
#
# inittest exits 7 when all its checks pass, and the kernel turns exit(n)
# into QEMU exit code 33 + 2n, so this script wants QEMU to exit with 47.
# Afterwards it runs e2fsck and fsck.exfat on the two partitions of the
# copy, which init wrote to.
#
# Usage: ./scripts/boot-v2-check.sh
set -euo pipefail
cd "$(dirname "$0")/.."
T="${CARGO_TARGET_DIR:-target}"
export PATH="$HOME/.cargo/bin:$PATH:/usr/sbin:/sbin" # e2fsck, fsck.exfat

cargo build --features headless
touch $T/x86_64-rust_kernel/debug/rustbelt # (see scripts/runner.sh)
cargo bootimage --features headless
IMG=$T/x86_64-rust_kernel/debug/bootimage-rustbelt.bin

ROOT=$T/boot-v2-root.img
cp $T/rootfs-gpt.img "$ROOT"
LOG=$T/boot-v2-serial.log
set +e
timeout 60 qemu-system-x86_64 -smp 4 -cpu max \
    -drive format=raw,file="$IMG" \
    -drive file=$T/disk.img,format=raw,if=virtio,snapshot=on \
    -drive file=$T/ext2.img,format=raw,if=virtio,snapshot=on \
    -drive file=$T/exfat.img,format=raw,if=virtio,snapshot=on \
    -drive file=$T/btrfs.img,format=raw,if=virtio,snapshot=on \
    -drive file="$ROOT",format=raw,if=virtio \
    -device isa-debug-exit,iobase=0xf4,iosize=0x04 \
    -serial stdio -display none -no-reboot | tee "$LOG"
code=${PIPESTATUS[0]}
set -e

ok=1
for line in "mounted at / (root partition)" "mounted at /mnt/share" \
            "[inittest] started as /sbin/init" "[inittest] ok: I am pid 1" \
            'headless: argv[1] is "selftest"' "[inittest] 0 failed" \
            "[init] pid 1 (/sbin/init) exited: Exited(7)"; do
    grep -qF -- "$line" "$LOG" || { echo "[boot-v2] MISSING: $line"; ok=0; }
done
[ "$code" = 47 ] || { echo "[boot-v2] QEMU exited with $code, not 47 (= exit(7))"; ok=0; }

# The partitions (start and size in 512-byte sectors, as build.rs made them).
dd if="$ROOT" of=$T/boot-v2-p1.img bs=512 skip=2048 count=24576 status=none
dd if="$ROOT" of=$T/boot-v2-p2.img bs=512 skip=26624 count=16384 status=none
e2fsck -fn $T/boot-v2-p1.img >/dev/null || { echo "[boot-v2] e2fsck found errors on the root"; ok=0; }
fsck.exfat -n $T/boot-v2-p2.img >/dev/null || { echo "[boot-v2] fsck.exfat found errors on the share"; ok=0; }
rm -f $T/boot-v2-p1.img $T/boot-v2-p2.img

if [ $ok = 1 ]; then
    echo "[boot-v2] OK: init ran as pid 1, QEMU exited 47 (= exit 7), both partitions fsck-clean"
    exit 0
fi
exit 1