feat: make kernel architecture-agnostic; primitive work on arm port
This commit is contained in:
1 parent
dab7d5427b
commit
1bae77ec84
164 files changed
+3664
-1641
No files matched your search
Executable
+101
@@ -0,0 +1,101 @@
|
||||
#!/bin/sh
|
||||
# check-arch-neutral.sh - Verify the kernel's architecture boundary.
|
||||
#
|
||||
# 1. Static rules: outside kernel/src/Arch/, kernel code may not contain
|
||||
# inline assembly, assembly sources, architecture #ifdefs, or includes of
|
||||
# a specific port's headers (it must use the interfaces in Arch/*.hpp).
|
||||
# 2. If clang is installed, compile the whole kernel for a second
|
||||
# architecture (default aarch64) and report any symbol the generic code
|
||||
# needs that the port does not define. Links too when ld.lld is found.
|
||||
#
|
||||
# Usage: ./scripts/check-arch-neutral.sh [arch]
|
||||
#
|
||||
# Copyright (c) 2026 Daniel Hammer
|
||||
|
||||
set -e
|
||||
|
||||
ROOT="$(cd "$(dirname "$0")/.." && pwd)"
|
||||
SRC="$ROOT/kernel/src"
|
||||
ARCH="${1:-aarch64}"
|
||||
status=0
|
||||
|
||||
cd "$SRC"
|
||||
|
||||
# Files allowed to name an architecture: the Limine adapter reads the
|
||||
# per-architecture MP structures limine.h defines, and Io/IoPort.hpp is an
|
||||
# interface header that dispatches to the port like Arch/*.hpp do.
|
||||
ALLOW='^(limine\.h|Boot/Protocols/LimineProtocol\.cpp|Io/IoPort\.hpp)$'
|
||||
|
||||
generic=$(find . -type f \( -name '*.c' -o -name '*.cpp' -o -name '*.h' -o -name '*.hpp' \) \
|
||||
! -path './Arch/*' | sed 's|^\./||' | LC_ALL=C sort)
|
||||
|
||||
report() {
|
||||
echo "check-arch-neutral: $1" >&2
|
||||
echo "$2" | sed 's/^/ /' >&2
|
||||
status=1
|
||||
}
|
||||
|
||||
hits=$(grep -nE '(^|[^_[:alnum:]])(asm|__asm__)[[:space:]]*(volatile|\()' $generic || true)
|
||||
[ -n "$hits" ] && report "inline assembly outside src/Arch/:" "$hits"
|
||||
|
||||
hits=$(find . -type f \( -name '*.asm' -o -name '*.S' -o -name '*.s' \) ! -path './Arch/*')
|
||||
[ -n "$hits" ] && report "assembly sources outside src/Arch/:" "$hits"
|
||||
|
||||
hits=$(echo "$generic" | grep -vE "$ALLOW" | xargs grep -nE \
|
||||
'__(x86_64|i386|aarch64|arm|riscv|loongarch[0-9]*)__|MONTAUK_ARCH_(X86|AARCH|RISCV|LOONG)[A-Z0-9_]*' || true)
|
||||
[ -n "$hits" ] && report "architecture conditionals outside src/Arch/:" "$hits"
|
||||
|
||||
hits=$(echo "$generic" | grep -vE "$ALLOW" | xargs grep -nE \
|
||||
'#[[:space:]]*include[[:space:]]*[<"]Arch/[^/>"]+/' || true)
|
||||
[ -n "$hits" ] && report "includes of a port's private headers:" "$hits"
|
||||
|
||||
if [ $status -eq 0 ]; then
|
||||
echo "check-arch-neutral: static rules OK"
|
||||
fi
|
||||
|
||||
# ---- Cross-compile check ----
|
||||
if ! command -v clang >/dev/null 2>&1; then
|
||||
echo "check-arch-neutral: clang not found, skipping the $ARCH build"
|
||||
exit $status
|
||||
fi
|
||||
if [ ! -d "Arch/$ARCH" ]; then
|
||||
echo "check-arch-neutral: no src/Arch/$ARCH port" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "check-arch-neutral: compiling the kernel for $ARCH"
|
||||
make -C "$ROOT/kernel" ARCH="$ARCH" objects -j"$(nproc 2>/dev/null || echo 4)" \
|
||||
>/dev/null 2>"$ROOT/kernel/check-arch-$ARCH.log" || {
|
||||
echo "check-arch-neutral: $ARCH compile failed (kernel/check-arch-$ARCH.log):" >&2
|
||||
grep -E 'error' "$ROOT/kernel/check-arch-$ARCH.log" | head -20 >&2
|
||||
exit 1
|
||||
}
|
||||
rm -f "$ROOT/kernel/check-arch-$ARCH.log"
|
||||
|
||||
NM="$(clang -print-prog-name=llvm-nm)"
|
||||
command -v "$NM" >/dev/null 2>&1 || NM=nm
|
||||
CXXFILT="$(clang -print-prog-name=llvm-cxxfilt)"
|
||||
command -v "$CXXFILT" >/dev/null 2>&1 || CXXFILT=cat
|
||||
|
||||
cd "$ROOT/kernel"
|
||||
objs=$(find "obj-$ARCH" -name '*.o')
|
||||
tmp=$(mktemp -d)
|
||||
trap 'rm -rf "$tmp"' EXIT
|
||||
"$NM" --defined-only -j $objs "cc-runtime-$ARCH/cc-runtime.a" 2>/dev/null | LC_ALL=C sort -u > "$tmp/def"
|
||||
"$NM" --undefined-only -j $objs | LC_ALL=C sort -u > "$tmp/undef"
|
||||
# Provided by the linker script.
|
||||
printf '%s\n' KernelStartSymbol KernelEndSymbol __init_array __init_array_end >> "$tmp/def"
|
||||
LC_ALL=C sort -u -o "$tmp/def" "$tmp/def"
|
||||
missing=$(LC_ALL=C comm -23 "$tmp/undef" "$tmp/def" | "$CXXFILT")
|
||||
if [ -n "$missing" ]; then
|
||||
report "symbols the $ARCH port must still provide:" "$missing"
|
||||
exit 1
|
||||
fi
|
||||
echo "check-arch-neutral: $ARCH objects compile and every symbol resolves"
|
||||
|
||||
if command -v "${KERNEL_LD:-ld.lld}" >/dev/null 2>&1; then
|
||||
make ARCH="$ARCH" >/dev/null
|
||||
echo "check-arch-neutral: linked kernel/bin-$ARCH/kernel"
|
||||
fi
|
||||
|
||||
exit $status
|
||||
Reference in new issue
Block a user