Repository navigation
Expand file tree
/
Copy pathbuild.sh
More file actions
executable file
·127 lines (115 loc) · 4.15 KB
/
Copy pathbuild.sh
File metadata and controls
executable file
·127 lines (115 loc) · 4.15 KB
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
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
#!/usr/bin/env bash
# Build a bootable raw disk image: MBR + stage 2 + Rust kernel + AOT HolyC apps.
#
# Two kernel links: pass 1 establishes the fixed `.hcapi` addresses (HC_Print,
# HC_FBW, ...), hcc compiles apps/*.HC into flat blobs against that table, and
# pass 2 links the blobs into the kernel.
set -euo pipefail
cd "$(dirname "$0")"
ROOT="$(pwd)"
mkdir -p build
echo "[1/6] kernel (pass 1: fixed HC_* addresses)"
cargo build --release
KERNEL_ELF=target/x86_64-unknown-linux-gnu/release/kernel
nm "$KERNEL_ELF" | awk '($2=="T"||$2=="D"||$2=="B") && $3 ~ /^HC_/ {print $3, $1}' \
> build/kernel_api.nm
NHC=$(wc -l < build/kernel_api.nm)
echo " $NHC fixed-address HC_* symbols harvested"
echo "[2/6] hcc (host AOT compiler)"
# hcc is an ordinary host binary. Building it with the cwd INSIDE the repo
# would inherit the kernel's .cargo/config.toml (-C linker=ld.lld
# -Tlinker.ld ...), so build from outside and point at the manifest.
mkdir -p /tmp/opencode
HCC="$ROOT/hcc/target/release/hcc"
if ! [ -x "$HCC" ] || [ -n "$(find "$ROOT/hcc/src" -newer "$HCC" -print -quit)" ]; then
( cd /tmp/opencode && \
cargo build --release \
--manifest-path "$ROOT/hcc/Cargo.toml" \
--target-dir "$ROOT/hcc/target" )
fi
echo "[3/6] HolyC apps -> flat blobs"
mkdir -p build/apps
NAPP=0
for src in apps/*.HC; do
[ -e "$src" ] || continue
stem="$(basename "$src" .HC)"
"$HCC" "$src" "build/apps/$stem.bin" --api build/kernel_api.nm
NAPP=$((NAPP + 1))
done
echo " $NAPP app(s) compiled"
echo "[4/6] embed apps (build/hcapps_data.rs)"
python3 - "$ROOT" <<'PYEOF'
import glob, os, sys
root = sys.argv[1]
apps_dir = os.path.join(root, "build", "apps")
lines = [
"// Generated by build.sh -- embedded AOT-compiled HolyC apps.",
"// Consumed by src/hcapps.rs via include!.",
"static APPS: &[(&str, &[u8])] = &[",
]
for f in sorted(glob.glob(os.path.join(apps_dir, "*.bin"))):
stem = os.path.basename(f)[:-4]
data = open(f, "rb").read()
bs = ",".join(str(b) for b in data)
lines.append(f' ("{stem}", &[{bs}]),')
lines.append("];")
content = "\n".join(lines) + "\n"
out = os.path.join(root, "build", "hcapps_data.rs")
try:
old = open(out).read()
except FileNotFoundError:
old = None
if old != content:
open(out, "w").write(content)
# make cargo notice the regenerated include! source
os.utime(os.path.join(root, "src", "hcapps.rs"))
print(" manifest regenerated")
else:
print(" manifest unchanged")
PYEOF
echo "[5/6] kernel (pass 2: blobs embedded)"
cargo build --release
objcopy -O binary "$KERNEL_ELF" build/kernel.bin
KSIZE=$(stat -c%s build/kernel.bin)
KSECT=$(( (KSIZE + 511) / 512 ))
echo " $KSIZE bytes, $KSECT sectors"
if [ "$KSIZE" -gt $(( 0x80000 - 0x10000 )) ]; then
echo "kernel too large (would hit the page tables at 0x90000)" >&2
exit 1
fi
echo "[6/6] stage 2"
S2SECT=64
for _ in 1 2 3 4; do
gcc -m16 -c \
-DKERNEL_LBA=$(( 1 + S2SECT )) \
-DKERNEL_SECTORS=$KSECT \
-o build/stage2.o boot/stage2.S
ld -m elf_i386 -Ttext 0x8000 -e _stage2 -o build/stage2.elf build/stage2.o
objcopy -O binary -j .text build/stage2.elf build/stage2.bin
NEW=$(( ($(stat -c%s build/stage2.bin) + 511) / 512 ))
if [ "$NEW" -eq "$S2SECT" ]; then
break
fi
S2SECT=$NEW
done
echo " $S2SECT sectors"
gcc -m16 -c -DSTAGE2_SECTORS=$S2SECT -o build/boot.o boot/boot.S
ld -m elf_i386 -Ttext 0x7c00 -e _start -o build/boot.elf build/boot.o
objcopy -O binary -j .text build/boot.elf build/boot.bin
BSIZE=$(stat -c%s build/boot.bin)
if [ "$BSIZE" -ne 512 ]; then
echo "boot sector is $BSIZE bytes, expected 512" >&2
exit 1
fi
truncate -s $(( KSECT * 512 )) build/kernel.bin
IMG=build/temple-rust.img
TOTAL=$(( (1 + S2SECT + KSECT) * 512 ))
rm -f "$IMG"
truncate -s "$TOTAL" "$IMG"
dd if=build/boot.bin of="$IMG" bs=512 conv=notrunc status=none
dd if=build/stage2.bin of="$IMG" bs=512 seek=1 conv=notrunc status=none
dd if=build/kernel.bin of="$IMG" bs=512 seek=$(( 1 + S2SECT )) conv=notrunc status=none
echo " $IMG ($(stat -c%s "$IMG") bytes)"
echo
echo " qemu-system-x86_64 -m 64 -drive format=raw,file=$IMG"
echo " or open $IMG in GNOME Boxes"