RustForge

foundry

Foundry OS: the operating system built on the Rustbelt kernel

foundry / scripts / build-kernel.sh
2420 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
#!/usr/bin/env bash
# Build the pinned Rustbelt kernel for Foundry OS, without touching the
# kernel repo's working tree or its target/ directory.
#
#   1. `git archive KERNEL_REV` reads the commit straight from the kernel
#      repo's git object store and unpacks it into out/kernel-src. Nothing in
#      KERNEL_DIR is written.
#   2. cargo builds it there with CARGO_TARGET_DIR=out/kernel-target.
#      (Cargo reads .cargo/config.toml and rust-toolchain.toml from the
#      directory it runs in, so we must cd into the kernel source first.)
#   3. Two boot images are kept: out/kernel/bootimage-headless.bin (runs the
#      self-test, then powers QEMU off) and out/kernel/bootimage.bin
#      (interactive).
#
# Side effect we rely on: the kernel's build.rs also writes its own disk
# images into out/kernel-target: disk.img (the reference for `make compare`)
# and the kernel-owned test disks ext2.img, exfat.img, btrfs.img, which
# `make run`/`make test` attach as drives C:, D:, E: (contract v1, point 5).
#
# Usage: scripts/build-kernel.sh KERNEL_DIR KERNEL_REV OUT_DIR [--export-only]
set -euo pipefail
KERNEL_DIR=$1 KERNEL_REV=$2 OUT=$(realpath -m "$3")
SRC=$OUT/kernel-src TARGET=$OUT/kernel-target DEST=$OUT/kernel

want=$(git -C "$KERNEL_DIR" rev-parse --verify "$KERNEL_REV^{commit}")
if [ "$(cat "$SRC/.foundry-kernel-rev" 2>/dev/null)" != "$want" ]; then
    echo "[kernel] exporting $KERNEL_REV ($want) from $KERNEL_DIR into $SRC"
    rm -rf "$SRC" && mkdir -p "$SRC"
    git -C "$KERNEL_DIR" archive "$want" | tar -x -C "$SRC"
    echo "$want" > "$SRC/.foundry-kernel-rev"
fi
[ "${4:-}" = --export-only ] && exit 0
mkdir -p "$TARGET" "$DEST"
cd "$SRC"
export CARGO_TARGET_DIR=$TARGET
ELF=$TARGET/x86_64-rust_kernel/debug/rustbelt
BOOT=$TARGET/x86_64-rust_kernel/debug/bootimage-rustbelt.bin
for variant in headless interactive; do
    if [ $variant = headless ]; then feat=(--features headless); out=$DEST/bootimage-headless.bin
    else feat=(); out=$DEST/bootimage.bin; fi
    echo "[kernel] cargo bootimage ${feat[*]:-} (target dir $TARGET)"
    cargo build "${feat[@]}"
    # bootimage caches by timestamp; switching features can reuse an old
    # ELF, so touch it (the kernel's scripts/runner.sh does the same).
    touch "$ELF"
    cargo bootimage "${feat[@]}"
    cp "$BOOT" "$out"
done
echo "$want" > "$DEST/rev"
echo "[kernel] done: $DEST/bootimage{,-headless}.bin, test disks in $TARGET"