Red Bear OS — microkernel OS in Rust, based on Redox

Derivative of Redox OS (https://www.redox-os.org) adding:
- AMD GPU driver (amdgpu) via LinuxKPI compat layer
- ext4 filesystem support (ext4d scheme daemon)
- ACPI fixes for AMD bare metal (x2APIC, DMAR, IVRS, MCFG)
- Custom branding (hostname, os-release, boot identity)

Build system is full upstream Redox with RBOS overlay in local/.
Patches for kernel, base, and relibc are symlinked from local/patches/
and protected from make clean/distclean. Custom recipes live in
local/recipes/ with symlinks into the recipes/ search path.

Build:  make all CONFIG_NAME=redbear-full
Sync:   ./local/scripts/sync-upstream.sh
This commit is contained in:
2026-04-12 19:05:00 +01:00
commit 50b731f1b7
3392 changed files with 98327 additions and 0 deletions
+156
View File
@@ -0,0 +1,156 @@
#!/usr/bin/env bash
# apply-patches.sh — Apply all RBOS patches on top of upstream Redox build system.
#
# Usage: ./local/scripts/apply-patches.sh [--force]
#
# This script:
# 1. Applies build-system patches (rebranding, cookbook fixes, config, docs)
# 2. Ensures recipe patches are symlinked from local/patches/
# 3. Ensures custom recipe symlinks exist in recipes/
#
# With --force: reapplies even if patches appear already applied.
#
# SAFE: does not touch local/ directory. Only modifies upstream files.
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
REPO_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)"
PATCHES_DIR="$REPO_ROOT/local/patches"
FORCE="${1:-}"
cd "$REPO_ROOT"
# ── Helper ──────────────────────────────────────────────────────────
symlink() {
local target="$1" link="$2"
if [ -L "$link" ]; then
current="$(readlink "$link")"
if [ "$current" = "$target" ]; then
return 0 # already correct
fi
fi
rm -f "$link"
ln -s "$target" "$link"
echo " linked $link -> $target"
}
# ── 1. Build-system patches ─────────────────────────────────────────
echo "==> Applying build-system patches..."
for patch_file in "$PATCHES_DIR"/build-system/[0-9]*.patch; do
[ -f "$patch_file" ] || continue
patch_name="$(basename "$patch_file")"
# Check if already applied (skip unless --force)
if [ "$FORCE" != "--force" ]; then
if git apply --check "$patch_file" 2>/dev/null; then
: # patch applies cleanly, apply it
else
echo " SKIP $patch_name (already applied or conflicts)"
echo " Use --force to attempt re-application"
continue
fi
fi
if git apply --whitespace=nowarn "$patch_file"; then
echo " OK $patch_name"
else
echo " FAIL $patch_name — resolve conflicts manually"
echo " Patch file: $patch_file"
exit 1
fi
done
# ── 2. Recipe patches (kernel, base) ───────────────────────────────
echo "==> Linking recipe patches from local/patches/..."
symlink "../../../local/patches/kernel/redox.patch" "recipes/core/kernel/redox.patch"
symlink "../../../local/patches/base/redox.patch" "recipes/core/base/redox.patch"
# ── 3. Custom recipe symlinks ──────────────────────────────────────
echo "==> Linking custom recipes from local/recipes/..."
# Branding
mkdir -p recipes/branding
symlink "../../local/recipes/branding/redbear-release" "recipes/branding/redbear-release"
# Drivers
mkdir -p recipes/drivers
symlink "../../local/recipes/drivers/linux-kpi" "recipes/drivers/linux-kpi"
symlink "../../local/recipes/drivers/redox-driver-sys" "recipes/drivers/redox-driver-sys"
# GPU
mkdir -p recipes/gpu
symlink "../../local/recipes/gpu/amdgpu" "recipes/gpu/amdgpu"
symlink "../../local/recipes/gpu/redox-drm" "recipes/gpu/redox-drm"
# System
mkdir -p recipes/system
symlink "../../local/recipes/system/evdevd" "recipes/system/evdevd"
symlink "../../local/recipes/system/firmware-loader" "recipes/system/firmware-loader"
symlink "../../local/recipes/system/redbear-meta" "recipes/system/redbear-meta"
symlink "../../local/recipes/system/udev-shim" "recipes/system/udev-shim"
# Core additions
mkdir -p recipes/core
symlink "../../local/recipes/core/ext4d" "recipes/core/ext4d"
# ── 4. New files not in upstream ────────────────────────────────────
echo "==> Ensuring RBOS-specific files exist..."
# rbos.ipxe (network boot)
if [ ! -f rbos.ipxe ] && [ ! -L rbos.ipxe ]; then
cat > rbos.ipxe <<'IPXE'
#!ipxe
kernel bootloader-live.efi
initrd http://${next-server}:8080/rbos-live.iso
boot
IPXE
echo " created rbos.ipxe"
fi
# redbear-full config (not in upstream)
if [ ! -f config/redbear-full.toml ] && [ ! -L config/redbear-full.toml ]; then
cat > config/redbear-full.toml <<'TOML'
# Red Bear OS Full Configuration
# Complete desktop + all RBOS custom drivers and tools
#
# Build: make all CONFIG_NAME=redbear-full
# Live: make live CONFIG_NAME=redbear-full
include = ["desktop.toml"]
[general]
# 2GB filesystem — plenty for full desktop + drivers
# (desktop.toml sets 650MB, but we want headroom for our custom packages)
filesystem_size = 2048
[packages]
# Red Bear OS branding (os-release, hostname, motd)
redbear-release = {}
# ext4 filesystem support (our custom port)
ext4d = {}
# RBOS driver infrastructure
redox-driver-sys = {}
linux-kpi = {}
firmware-loader = {}
# Input layer
evdevd = {}
udev-shim = {}
# GPU driver (AMD — modesetting display core)
redox-drm = {}
amdgpu = {}
# RBOS meta-package (dependencies, default config)
redbear-meta = {}
TOML
echo " created config/redbear-full.toml"
fi
echo ""
echo "==> All RBOS patches applied. Ready to build."
echo " make all CONFIG_NAME=redbear-full"
+86
View File
@@ -0,0 +1,86 @@
#!/usr/bin/env bash
# Build Red Bear OS with AMD GPU support (Phase P2)
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)"
CONFIG="${1:-my-amd-desktop}"
JOBS="${JOBS:-$(nproc)}"
APPLY_PATCHES="${APPLY_PATCHES:-1}"
echo "=== Red Bear OS AMD GPU Build ==="
echo "Config: $CONFIG"
echo "Jobs: $JOBS"
echo "Apply patches: $APPLY_PATCHES"
echo "Root: $PROJECT_ROOT"
echo ""
cd "$PROJECT_ROOT"
# Step 0: Apply local patches
if [ "$APPLY_PATCHES" = "1" ]; then
echo ">>> Applying local patches..."
apply_patch_dir() {
local patch_dir="$1"
local target_dir="$2"
local label="$3"
if [ ! -d "$patch_dir" ]; then
return 0
fi
for patch_file in $(ls "$patch_dir"/*.patch 2>/dev/null | sort); do
patch_name=$(basename "$patch_file")
if [ ! -d "$target_dir" ]; then
echo " SKIP $patch_name ($label source not fetched yet)"
continue
fi
if patch --dry-run -p1 -d "$target_dir" < "$patch_file" > /dev/null 2>&1; then
patch -p1 -d "$target_dir" < "$patch_file" > /dev/null 2>&1
echo " OK $patch_name"
else
echo " SKIP $patch_name (already applied or won't apply)"
fi
done
}
apply_patch_dir "$PROJECT_ROOT/local/patches/kernel" "$PROJECT_ROOT/recipes/core/kernel/source" "kernel"
apply_patch_dir "$PROJECT_ROOT/local/patches/base" "$PROJECT_ROOT/recipes/core/base/source" "base"
apply_patch_dir "$PROJECT_ROOT/local/patches/relibc" "$PROJECT_ROOT/recipes/core/relibc/source" "relibc"
apply_patch_dir "$PROJECT_ROOT/local/patches/bootloader" "$PROJECT_ROOT/recipes/core/bootloader/source" "bootloader"
apply_patch_dir "$PROJECT_ROOT/local/patches/installer" "$PROJECT_ROOT/recipes/core/installer/source" "installer"
echo ""
fi
# Step 1: Build cookbook binary if needed
if [ ! -f "target/release/repo" ]; then
echo ">>> Building cookbook binary..."
cargo build --release
fi
# Step 2: Fetch AMD firmware blobs if missing
FW_DIR="$PROJECT_ROOT/local/firmware/amdgpu"
if [ -z "$(ls -A "$FW_DIR" 2>/dev/null)" ]; then
echo ">>> AMD firmware blobs not found. Run local/scripts/fetch-firmware.sh first."
echo " Skipping firmware fetch. Driver will NOT function without firmware."
else
FW_COUNT=$(ls "$FW_DIR"/*.bin 2>/dev/null | wc -l)
echo ">>> Found $FW_COUNT AMD firmware blobs"
fi
# Step 3: Build
echo ">>> Building RBOS with config: $CONFIG"
echo ">>> This may take 30-60 minutes on first build..."
CI=1 make all "CONFIG_NAME=$CONFIG" "JOBS=$JOBS"
echo ""
echo "=== Build Complete ==="
echo "Image: build/x86_64/harddrive.img"
echo ""
echo "To run in QEMU:"
echo " make qemu QEMUFLAGS=\"-m 4G\""
echo ""
echo "To test on bare metal:"
echo " dd if=build/x86_64/harddrive.img of=/dev/sdX bs=4M status=progress"
+117
View File
@@ -0,0 +1,117 @@
#!/usr/bin/env bash
# build-redbear.sh — Build Red Bear OS
#
# Usage:
# ./local/scripts/build-redbear.sh # Default: redbear-desktop
# ./local/scripts/build-redbear.sh redbear-minimal # Minimal variant
# ./local/scripts/build-redbear.sh redbear-live # Live ISO variant
# APPLY_PATCHES=0 ./local/scripts/build-redbear.sh # Skip patch application
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)"
CONFIG="${1:-redbear-desktop}"
JOBS="${JOBS:-$(nproc)}"
APPLY_PATCHES="${APPLY_PATCHES:-1}"
case "$CONFIG" in
redbear-desktop|redbear-minimal|redbear-live)
;;
*)
echo "ERROR: Unknown config '$CONFIG'"
echo "Supported: redbear-desktop, redbear-minimal, redbear-live"
exit 1
;;
esac
echo "========================================"
echo " Red Bear OS Build System"
echo "========================================"
echo "Config: $CONFIG"
echo "Jobs: $JOBS"
echo "Apply patches: $APPLY_PATCHES"
echo "Root: ${PROJECT_ROOT##*/}"
echo "========================================"
echo ""
cd "$PROJECT_ROOT"
# Step 0: Apply local patches
if [ "$APPLY_PATCHES" = "1" ]; then
echo ">>> Applying local patches..."
apply_patch_dir() {
local patch_dir="$1"
local target_dir="$2"
local label="$3"
if [ ! -d "$patch_dir" ]; then
return 0
fi
for patch_file in "$patch_dir"/*.patch; do
[ -f "$patch_file" ] || continue
patch_name=$(basename "$patch_file")
if [ ! -d "$target_dir" ]; then
echo " SKIP $patch_name ($label source not fetched yet)"
continue
fi
if patch --dry-run -p1 -d "$target_dir" < "$patch_file" > /dev/null 2>&1; then
patch -p1 -d "$target_dir" < "$patch_file" > /dev/null 2>&1
echo " OK $patch_name"
else
echo " SKIP $patch_name (already applied or won't apply)"
fi
done
}
apply_patch_dir "$PROJECT_ROOT/local/patches/kernel" "$PROJECT_ROOT/recipes/core/kernel/source" "kernel"
apply_patch_dir "$PROJECT_ROOT/local/patches/base" "$PROJECT_ROOT/recipes/core/base/source" "base"
apply_patch_dir "$PROJECT_ROOT/local/patches/relibc" "$PROJECT_ROOT/recipes/core/relibc/source" "relibc"
apply_patch_dir "$PROJECT_ROOT/local/patches/bootloader" "$PROJECT_ROOT/recipes/core/bootloader/source" "bootloader"
apply_patch_dir "$PROJECT_ROOT/local/patches/installer" "$PROJECT_ROOT/recipes/core/installer/source" "installer"
echo ""
fi
# Step 1: Build cookbook binary
if [ ! -f "target/release/repo" ]; then
echo ">>> Building cookbook binary..."
cargo build --release
fi
# Step 2: Check firmware
FW_AMD_DIR="$PROJECT_ROOT/local/firmware/amdgpu"
if [ "$CONFIG" != "redbear-minimal" ]; then
if [ -d "$FW_AMD_DIR" ] && [ -n "$(ls -A "$FW_AMD_DIR" 2>/dev/null)" ]; then
FW_COUNT=$(ls "$FW_AMD_DIR"/*.bin 2>/dev/null | wc -l)
echo ">>> Found $FW_COUNT AMD firmware blobs"
else
echo ">>> WARNING: No AMD firmware blobs found."
echo " Run: ./local/scripts/fetch-firmware.sh"
echo " GPU driver will NOT function without firmware."
fi
echo ""
fi
# Step 3: Build
echo ">>> Building Red Bear OS with config: $CONFIG"
echo ">>> This may take 30-60 minutes on first build..."
CI=1 make all "CONFIG_NAME=$CONFIG" "JOBS=$JOBS"
# Step 4: Report
ARCH="${ARCH:-$(uname -m)}"
echo ""
echo "========================================"
echo " Build Complete!"
echo "========================================"
echo "Image: build/$ARCH/$CONFIG/harddrive.img"
echo ""
echo "To run in QEMU:"
echo " make qemu QEMUFLAGS=\"-m 4G\""
echo ""
echo "To build live ISO:"
echo " make live CONFIG_NAME=$CONFIG"
echo ""
echo "To burn to USB (verify device first!):"
echo " dd if=build/$ARCH/$CONFIG/harddrive.img of=/dev/sdX bs=4M status=progress"
+180
View File
@@ -0,0 +1,180 @@
#!/usr/bin/env bash
# Fetch AMD GPU firmware blobs from linux-firmware repository
# These are required for amdgpu driver to function
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
FIRMWARE_DIR="$SCRIPT_DIR/../firmware/amdgpu"
LINUX_FIRMWARE_REPO="https://git.kernel.org/pub/scm/linux/kernel/git/firmware/linux-firmware.git"
TEMP_DIR=$(mktemp -d)
SUBSET="all"
usage() {
cat <<EOF
Usage: $(basename "$0") [--subset all|rdna]
Fetch AMD GPU firmware blobs from linux-firmware.
Options:
--subset all Fetch the full amdgpu firmware set (default)
--subset rdna Fetch only RDNA2/RDNA3-oriented firmware blobs
-h, --help Show this help text
EOF
}
cleanup() {
rm -rf "$TEMP_DIR"
}
trap cleanup EXIT
while [ "$#" -gt 0 ]; do
case "$1" in
--subset)
if [ "$#" -lt 2 ]; then
echo "ERROR: --subset requires a value"
usage
exit 1
fi
SUBSET="$2"
shift 2
;;
-h|--help)
usage
exit 0
;;
*)
echo "ERROR: Unknown option: $1"
usage
exit 1
;;
esac
done
case "$SUBSET" in
all|rdna)
;;
*)
echo "ERROR: Unsupported subset: $SUBSET"
usage
exit 1
;;
esac
echo "=== AMD GPU Firmware Fetcher ==="
echo "Target: $FIRMWARE_DIR"
echo "Subset: $SUBSET"
# Clone linux-firmware (shallow)
echo "Cloning linux-firmware repository..."
git clone --depth 1 "$LINUX_FIRMWARE_REPO" "$TEMP_DIR/linux-firmware"
# Create target directory
mkdir -p "$FIRMWARE_DIR"
# Copy AMD GPU firmware
echo "Copying AMD GPU firmware blobs..."
if [ -d "$TEMP_DIR/linux-firmware/amdgpu" ]; then
shopt -s nullglob
source_blobs=("$TEMP_DIR/linux-firmware/amdgpu/"*.bin)
if [ "$SUBSET" = "rdna" ]; then
selected_blobs=()
for blob in "${source_blobs[@]}"; do
base="$(basename "$blob")"
case "$base" in
psp_13_*|gc_10_3_*|gc_11_0_*|sdma_5_*|sdma_6_*|dcn_3_*|dcn_3_1_*|mes_2_*|smu_13_*|vcn_4_*|gc_11_5_*)
selected_blobs+=("$blob")
;;
esac
done
else
selected_blobs=("${source_blobs[@]}")
fi
if [ "${#selected_blobs[@]}" -eq 0 ]; then
echo "ERROR: No firmware blobs matched subset: $SUBSET"
exit 1
fi
rm -f "$FIRMWARE_DIR"/*.bin
cp -v "${selected_blobs[@]}" "$FIRMWARE_DIR/"
echo "Copied $(ls "$FIRMWARE_DIR/"*.bin 2>/dev/null | wc -l) firmware blobs"
echo "=== Verifying firmware selection ==="
if [ "$SUBSET" = "rdna" ]; then
if ls "$FIRMWARE_DIR"/gc_10_3_*.bin "$FIRMWARE_DIR"/gc_11_0_*.bin >/dev/null 2>&1; then
echo "Verified RDNA graphics firmware families (gfx10.3/gfx11) are present"
else
echo "ERROR: Missing RDNA2/RDNA3 graphics firmware blobs"
exit 1
fi
if ls "$FIRMWARE_DIR"/psp_13_*_sos.bin >/dev/null 2>&1; then
echo "Verified PSP SOS firmware is present"
else
echo "ERROR: Missing PSP SOS firmware blobs"
exit 1
fi
non_rdna_count=0
for blob in "$FIRMWARE_DIR"/*.bin; do
base="$(basename "$blob")"
case "$base" in
psp_13_*|gc_10_3_*|gc_11_0_*|sdma_5_*|sdma_6_*|dcn_3_*|mes_2_*|smu_13_*|vcn_4_*|gc_11_5_*) ;;
*) non_rdna_count=$((non_rdna_count + 1)) ;;
esac
done
if [ "$non_rdna_count" -gt 0 ]; then
echo "ERROR: Non-RDNA firmware blob detected in rdna subset"
exit 1
fi
echo "Verified subset contains only RDNA-oriented firmware families"
else
if ls "$FIRMWARE_DIR"/*.bin >/dev/null 2>&1; then
echo "Verified full AMD firmware set copied successfully"
else
echo "ERROR: No firmware blobs were copied"
exit 1
fi
fi
shopt -u nullglob
else
echo "ERROR: amdgpu firmware directory not found in linux-firmware"
exit 1
fi
# Also create a listing of which firmware blobs map to which ASICs
echo "=== Creating firmware manifest ==="
cat > "$FIRMWARE_DIR/MANIFEST.txt" << 'MANIFEST'
# AMD GPU Firmware for Red Bear OS
# Source: linux-firmware (https://git.kernel.org/pub/scm/linux/kernel/git/firmware/linux-firmware.git)
# License: Various — see linux-firmware WHENCE file for details
#
# Required for: RDNA2 (gfx10.3), RDNA3 (gfx11)
# Minimum set for basic display output:
# - PSP SOS + TA (security processor)
# - GC ME/PFP/CE/MEC (graphics/compute)
# - SDMA (DMA engine)
# - DMCUB (Display Microcontroller)
#
# Key files for RDNA2 (Navi 21/22/23/24, gfx10.3):
# psp_13_0_*_sos.bin, gc_10_3_*.bin, sdma_5_*.bin, dcn_3_*.bin
#
# Key files for RDNA3 (Navi 31/32/33, gfx11):
# psp_13_*_sos.bin, gc_11_0_*.bin, sdma_6_*.bin, dcn_3_1_*.bin
MANIFEST
echo "$FIRMWARE_DIR/MANIFEST.txt created"
# Summary
echo ""
echo "=== Firmware blobs installed ==="
ls -la "$FIRMWARE_DIR/" | head -20
echo "..."
echo "Total: $(ls "$FIRMWARE_DIR/"*.bin 2>/dev/null | wc -l) blobs"
echo ""
echo "WARNING: These are proprietary firmware blobs from AMD."
echo "They are NOT open source. Verify your license compliance."
+159
View File
@@ -0,0 +1,159 @@
#!/usr/bin/env bash
# sync-upstream.sh — Update from upstream Redox and reapply RBOS patches.
#
# Usage:
# ./local/scripts/sync-upstream.sh # Rebase onto upstream master
# ./local/scripts/sync-upstream.sh --dry-run # Preview what would change
# ./local/scripts/sync-upstream.sh --no-merge # Only fetch + check for conflicts
#
# Strategy: git rebase (preserves RBOS commits, replays on new upstream).
# Fallback: if rebase fails, patches in local/patches/build-system/ can be
# applied from scratch via: ./local/scripts/apply-patches.sh --force
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
REPO_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)"
UPSTREAM_URL="${UPSTREAM_URL:-https://github.com/redox-os/redox.git}"
UPSTREAM_REMOTE="upstream-redox"
UPSTREAM_BRANCH="${UPSTREAM_BRANCH:-master}"
DRY_RUN=0
NO_MERGE=0
for arg in "$@"; do
case "$arg" in
--dry-run) DRY_RUN=1 ;;
--no-merge) NO_MERGE=1 ;;
--help|-h)
echo "Usage: $0 [--dry-run] [--no-merge]"
echo " --dry-run Show what would happen without making changes"
echo " --no-merge Only fetch and check patch conflicts"
exit 0
;;
*)
echo "Unknown argument: $arg"
exit 1
;;
esac
done
cd "$REPO_ROOT"
# ── 1. Ensure upstream remote ───────────────────────────────────────
if ! git remote get-url "$UPSTREAM_REMOTE" &>/dev/null; then
echo "==> Adding upstream remote: $UPSTREAM_URL"
[ "$DRY_RUN" = "0" ] && git remote add "$UPSTREAM_REMOTE" "$UPSTREAM_URL"
fi
echo "==> Fetching $UPSTREAM_REMOTE/$UPSTREAM_BRANCH..."
[ "$DRY_RUN" = "0" ] && git fetch "$UPSTREAM_REMOTE" "$UPSTREAM_BRANCH"
UPSTREAM_REF="${UPSTREAM_REMOTE}/${UPSTREAM_BRANCH}"
# ── 2. Check patch conflicts with upstream changes ──────────────────
MERGE_BASE=$(git merge-base HEAD "$UPSTREAM_REF" 2>/dev/null || echo "")
if [ -n "$MERGE_BASE" ]; then
CHANGED_FILES=$(git diff --name-only "$MERGE_BASE" "$UPSTREAM_REF" 2>/dev/null || true)
CHANGE_COUNT=$(echo "$CHANGED_FILES" | grep -c . 2>/dev/null || echo "0")
echo " $CHANGE_COUNT files changed upstream since common ancestor"
if [ -n "$CHANGED_FILES" ] && [ -d local/patches ]; then
echo ""
echo "==> Checking patch conflict risks..."
for patch_file in local/patches/build-system/[0-9]*.patch; do
[ -f "$patch_file" ] || continue
PATCH_NAME=$(basename "$patch_file")
PATCHED_FILES=$(grep '^--- a/' "$patch_file" 2>/dev/null | sed 's|^--- a/||' | sort -u || true)
for pf in $PATCHED_FILES; do
if echo "$CHANGED_FILES" | grep -q "$pf" 2>/dev/null; then
echo " ⚠ CONFLICT RISK: $PATCH_NAME modifies $pf (also changed upstream)"
fi
done
done
for patch_dir in local/patches/kernel local/patches/base; do
[ -f "$patch_dir/redox.patch" ] || continue
echo " $patch_dir/redox.patch — check manually if kernel/base changed upstream"
done
fi
else
echo " WARNING: Could not find common ancestor with upstream"
fi
# ── 3. Summary ─────────────────────────────────────────────────────
AHEAD=$(git rev-list --count "$UPSTREAM_REF..HEAD" 2>/dev/null || echo "?")
BEHIND=$(git rev-list --count "HEAD..$UPSTREAM_REF" 2>/dev/null || echo "?")
echo ""
echo "=== Sync Summary ==="
echo "Upstream: $UPSTREAM_REF"
echo "Local: HEAD ($(git rev-parse --short HEAD))"
echo "Ahead: $AHEAD RBOS commits"
echo "Behind: $BEHIND upstream commits"
if [ "$NO_MERGE" = 1 ]; then
echo ""
echo "To merge manually:"
echo " git rebase $UPSTREAM_REF"
exit 0
fi
if [ "$DRY_RUN" = "1" ]; then
echo ""
echo " [dry-run] Would rebase onto $UPSTREAM_REF"
exit 0
fi
# ── 4. Stash uncommitted changes ────────────────────────────────────
STASHED=0
if ! git diff --quiet 2>/dev/null || ! git diff --cached --quiet 2>/dev/null; then
echo "==> Stashing uncommitted changes..."
git stash push -m "rbos-sync-$(date +%Y%m%d-%H%M%S)"
STASHED=1
fi
PREV_HEAD=$(git rev-parse HEAD)
# ── 5. Rebase ───────────────────────────────────────────────────────
echo ""
echo "==> Rebasing RBOS commits onto $UPSTREAM_REF..."
echo " (this replays our $AHEAD commits on top of updated upstream)"
if git rebase "$UPSTREAM_REF"; then
echo ""
echo "==> Rebase successful."
else
echo ""
echo "!! Rebase conflict. Options:"
echo " 1. Resolve conflicts: edit files, git add, git rebase --continue"
echo " 2. Abort: git rebase --abort"
echo " 3. Nuclear option:"
echo " git rebase --abort"
echo " git reset --hard $UPSTREAM_REF"
echo " ./local/scripts/apply-patches.sh --force"
echo ""
echo " Patches for recovery: local/patches/build-system/"
echo " Previous HEAD: $PREV_HEAD"
exit 1
fi
# ── 6. Restore stash ────────────────────────────────────────────────
if [ "$STASHED" = 1 ]; then
echo "==> Restoring stashed changes..."
git stash pop || echo " (stash pop had conflicts — resolve manually)"
fi
# ── 7. Verify symlinks ─────────────────────────────────────────────
echo "==> Verifying recipe patch symlinks..."
if [ -f local/scripts/apply-patches.sh ]; then
bash local/scripts/apply-patches.sh
else
echo " apply-patches.sh not found — verify symlinks manually"
ls -la recipes/core/kernel/redox.patch recipes/core/base/redox.patch
fi
echo ""
echo "==> Sync complete."
echo " Previous HEAD: $PREV_HEAD"
echo " New HEAD: $(git rev-parse HEAD)"
echo ""
echo "Next: make all CONFIG_NAME=redbear-full"
+43
View File
@@ -0,0 +1,43 @@
#!/usr/bin/env bash
# Test AMD GPU driver on Red Bear OS
# Run this inside RBOS (or via QEMU serial console)
set -euo pipefail
echo "=== AMD GPU Driver Test ==="
echo ""
# Check if scheme:drm exists
if [ -e "/scheme/drm" ]; then
echo "✅ scheme:drm registered"
else
echo "❌ scheme:drm NOT found — redox-drm daemon not running?"
exit 1
fi
# Check card0
if [ -e "/scheme/drm/card0" ]; then
echo "✅ /scheme/drm/card0 exists"
else
echo "❌ /scheme/drm/card0 NOT found — AMD GPU not detected?"
exit 1
fi
# Try to read connector info
echo ""
echo "=== Connector Info ==="
if command -v modetest &>/dev/null; then
modetest -M amd 2>&1 | head -50
else
echo "modetest not available — reading raw scheme"
# Read from scheme directly
cat /scheme/drm/card0 2>&1 | head -20 || true
fi
echo ""
echo "=== PCI Devices (GPU) ==="
ls /scheme/pci/ 2>/dev/null | while read -r entry; do
echo " $entry"
done
echo ""
echo "=== Test Complete ==="
+228
View File
@@ -0,0 +1,228 @@
#!/usr/bin/env bash
# Build and burn a Red Bear OS hard drive image for bare-metal AMD testing
# Requires explicit target device selection and write permissions
set -euo pipefail
REDOX_ROOT="$(dirname "$0")/../.."
REDOX_ROOT="$(cd "$REDOX_ROOT" && pwd)"
IMAGE_PATH="$REDOX_ROOT/build/harddrive.img"
CONFIG="my-amd-desktop"
DEVICE=""
DRY_RUN=0
SKIP_BUILD=0
VERIFY_BURN=0
usage() {
cat <<EOF
Usage: $(basename "$0") [OPTIONS] [CONFIG_NAME]
Build and burn a Red Bear OS bare-metal test image to a block device.
Arguments:
CONFIG_NAME Red Bear OS config to build (default: my-amd-desktop)
Options:
--device PATH Target block device to overwrite (required)
--skip-build Skip 'make all CONFIG_NAME=...'
--verify Verify the written image with cmp after dd
--dry-run Show actions without building or writing
-h, --help Show this help text
Notes:
- This script never auto-detects a target device.
- Run it with permissions that can write to the selected block device.
- Expected image path: build/harddrive.img
EOF
}
run_cmd() {
if [ "$DRY_RUN" -eq 1 ]; then
printf '[dry-run]'
printf ' %q' "$@"
printf '\n'
else
"$@"
fi
}
show_available_devices() {
echo "=== Available block devices ==="
lsblk -e7 -o NAME,PATH,SIZE,MODEL,TRAN,TYPE,MOUNTPOINTS
echo ""
}
warn_if_system_disk() {
local target_path="$1"
local target_name parent_name mount_info root_source root_parent
target_name="$(basename "$target_path")"
parent_name="$(lsblk -no PKNAME "$target_path" 2>/dev/null | head -n 1 || true)"
mount_info="$(lsblk -nr -o PATH,MOUNTPOINTS "$target_path" 2>/dev/null || true)"
root_source="$(findmnt -n -o SOURCE / 2>/dev/null || true)"
root_parent=""
if [ -n "$root_source" ] && [ -b "$root_source" ]; then
root_parent="$(lsblk -no PKNAME "$root_source" 2>/dev/null | head -n 1 || true)"
fi
if printf '%s\n' "$mount_info" | grep -Eq '(/|/boot|/home|\[SWAP\])'; then
echo "WARNING: $target_path or one of its partitions appears to be mounted."
echo "$mount_info"
fi
if [ -n "$root_source" ]; then
if [ "$root_source" = "$target_path" ] || [ "/dev/$parent_name" = "$target_path" ] || [ "$target_name" = "$root_parent" ]; then
echo "WARNING: $target_path appears related to the current root device ($root_source)."
fi
fi
}
refuse_unsafe_device() {
local target_path="$1"
local target_name
target_name="$(basename "$target_path")"
case "$target_name" in
sda|hda|vda|xvda|mmcblk0|nvme0|nvme0n1)
echo "ERROR: Refusing to write to likely system disk $target_path"
exit 1
;;
esac
}
confirm_write() {
local prompt="$1"
local reply
if [ "$DRY_RUN" -eq 1 ]; then
echo "[dry-run] Confirmation skipped: $prompt"
return
fi
read -r -p "$prompt [y/N]: " reply
case "$reply" in
y|Y|yes|YES)
;;
*)
echo "Aborted."
exit 1
;;
esac
}
while [ "$#" -gt 0 ]; do
case "$1" in
--device)
if [ "$#" -lt 2 ]; then
echo "ERROR: --device requires a path"
usage
exit 1
fi
DEVICE="$2"
shift 2
;;
--skip-build)
SKIP_BUILD=1
shift
;;
--verify)
VERIFY_BURN=1
shift
;;
--dry-run)
DRY_RUN=1
shift
;;
-h|--help)
usage
exit 0
;;
--*)
echo "ERROR: Unknown option: $1"
usage
exit 1
;;
*)
CONFIG="$1"
shift
;;
esac
done
echo "=== Red Bear OS Bare-Metal AMD Test Image Burner ==="
echo "Config: $CONFIG"
echo "Image: $IMAGE_PATH"
echo "Device: ${DEVICE:-<not set>}"
echo ""
if [ -z "$DEVICE" ]; then
echo "ERROR: You must specify a target block device with --device"
echo ""
usage
exit 1
fi
show_available_devices
if [ ! -e "$DEVICE" ]; then
echo "ERROR: Target device does not exist: $DEVICE"
exit 1
fi
if [ ! -b "$DEVICE" ]; then
echo "ERROR: Target path is not a block device: $DEVICE"
exit 1
fi
if [ "$(lsblk -dn -o TYPE "$DEVICE")" != "disk" ]; then
echo "ERROR: Target must be a whole-disk block device, not a partition: $DEVICE"
exit 1
fi
refuse_unsafe_device "$DEVICE"
warn_if_system_disk "$DEVICE"
if [ "$SKIP_BUILD" -eq 0 ]; then
echo "=== Building RBOS image ==="
run_cmd make -C "$REDOX_ROOT" all CONFIG_NAME="$CONFIG"
else
echo "=== Skipping build step ==="
fi
echo "=== Checking image ==="
if [ ! -f "$IMAGE_PATH" ]; then
echo "ERROR: RBOS image not found: $IMAGE_PATH"
exit 1
fi
IMAGE_SIZE_BYTES="$(stat -c %s "$IMAGE_PATH")"
echo "Image size: $IMAGE_SIZE_BYTES bytes"
echo ""
echo "About to write $IMAGE_PATH to $DEVICE"
echo "This will overwrite all data on the target device."
confirm_write "Continue with dd write?"
echo "=== Writing image to device ==="
run_cmd dd if="$IMAGE_PATH" of="$DEVICE" bs=4M conv=fsync status=progress
echo "=== Synchronizing device ==="
run_cmd sync
if [ "$VERIFY_BURN" -eq 1 ]; then
echo "=== Verifying written image ==="
run_cmd cmp -n "$IMAGE_SIZE_BYTES" "$IMAGE_PATH" "$DEVICE"
echo "Verification completed successfully."
fi
echo ""
echo "=== Next steps ==="
echo "1. Safely eject or unplug the target device if your host requires it."
echo "2. Insert the device into the AMD test machine and boot from it in UEFI mode."
echo "3. Capture serial output during boot if available to diagnose early failures."
echo "4. Check ACPI, SMP, framebuffer, and storage initialization on real hardware."
echo ""
echo "If you need serial logs, connect your serial console before powering on the target system."