mirror of
https://github.com/archr-linux/Arch-R.git
synced 2026-03-31 14:41:55 -07:00
Major architecture change: move from BSP kernel 6.6 with pre-merged panel DTBs to mainline kernel 6.12.61 LTS with separated board DTBs + panel overlays. - Board DTB = hardware profile (GPIOs, PMIC, joypad, audio). 16 boards. Auto-selected by U-Boot via SARADC ADC reading (hwrev). - Panel overlay = display init sequence. 20 panels. Applied at boot time via boot.ini fdt apply. - Two image variants: original (a_boot.ini) and clone (b_boot.ini) - Kernel cross-compiles from x86 host (no ARM chroot needed) - Initramfs boot splash with SVG rendering at 0.7s - Out-of-tree joypad driver (singleadc-joypad) for clone boards - Panel generic-dsi driver with archr,generic-dsi compatible Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
348 lines
12 KiB
Bash
Executable File
348 lines
12 KiB
Bash
Executable File
#!/bin/bash
|
|
|
|
#==============================================================================
|
|
# Arch R - Kernel Build Script
|
|
#==============================================================================
|
|
# Builds mainline Linux 6.12.x with Arch R patches for RK3326 R36S
|
|
# Applies: device patches, 6.12-LTS patches, mainline patches
|
|
# Builds: kernel Image + ALL DTBs + modules + out-of-tree joypad driver
|
|
#==============================================================================
|
|
|
|
set -e
|
|
|
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
|
|
# Colors
|
|
RED='\033[0;31m'
|
|
GREEN='\033[0;32m'
|
|
YELLOW='\033[1;33m'
|
|
NC='\033[0m'
|
|
|
|
log() { echo -e "${GREEN}[$(date '+%H:%M:%S')]${NC} $1"; }
|
|
warn() { echo -e "${YELLOW}[$(date '+%H:%M:%S')] WARNING:${NC} $1"; }
|
|
error() { echo -e "${RED}[$(date '+%H:%M:%S')] ERROR:${NC} $1"; exit 1; }
|
|
|
|
#------------------------------------------------------------------------------
|
|
# Configuration
|
|
#------------------------------------------------------------------------------
|
|
|
|
KERNEL_VERSION="6.12.61"
|
|
KERNEL_URL="https://www.kernel.org/pub/linux/kernel/v6.x/linux-${KERNEL_VERSION}.tar.xz"
|
|
|
|
# Paths
|
|
KERNEL_SRC="$SCRIPT_DIR/kernel/src/linux-${KERNEL_VERSION}"
|
|
PATCHES_DIR="$SCRIPT_DIR/patches/linux"
|
|
DTS_DIR="$SCRIPT_DIR/kernel/dts/archr"
|
|
JOYPAD_DIR="$SCRIPT_DIR/kernel/drivers/archr-joypad"
|
|
CONFIG_BASE="$SCRIPT_DIR/config/linux-archr-base.config"
|
|
|
|
# Output
|
|
OUTPUT_DIR="$SCRIPT_DIR/output"
|
|
BOOT_DIR="$OUTPUT_DIR/boot"
|
|
MODULES_DIR="$OUTPUT_DIR/modules"
|
|
|
|
# Cross-compilation
|
|
export ARCH=arm64
|
|
export CROSS_COMPILE=aarch64-linux-gnu-
|
|
|
|
# Build parallelism
|
|
JOBS=$(nproc)
|
|
|
|
# DTS target directory inside kernel
|
|
KERNEL_DTS_DIR="$KERNEL_SRC/arch/arm64/boot/dts/rockchip"
|
|
|
|
log "================================================================"
|
|
log " Arch R - Kernel $KERNEL_VERSION (Mainline + Arch R patches)"
|
|
log "================================================================"
|
|
log ""
|
|
log "Source: $KERNEL_SRC"
|
|
log "Patches: $PATCHES_DIR"
|
|
log "DTS: $DTS_DIR"
|
|
log "Config: $CONFIG_BASE"
|
|
log "Jobs: $JOBS"
|
|
|
|
#------------------------------------------------------------------------------
|
|
# Step 1: Verify Kernel Source
|
|
#------------------------------------------------------------------------------
|
|
log ""
|
|
log "Step 1: Checking kernel source..."
|
|
|
|
if [ ! -d "$KERNEL_SRC" ]; then
|
|
TARBALL="$SCRIPT_DIR/kernel/src/linux-${KERNEL_VERSION}.tar.xz"
|
|
if [ ! -f "$TARBALL" ]; then
|
|
log " Downloading kernel $KERNEL_VERSION..."
|
|
wget -c "$KERNEL_URL" -O "$TARBALL"
|
|
fi
|
|
log " Extracting..."
|
|
tar -xf "$TARBALL" -C "$SCRIPT_DIR/kernel/src/"
|
|
fi
|
|
|
|
if [ ! -f "$KERNEL_SRC/Makefile" ]; then
|
|
error "Kernel source not found at: $KERNEL_SRC"
|
|
fi
|
|
|
|
ACTUAL_VERSION=$(make -C "$KERNEL_SRC" -s kernelversion 2>/dev/null)
|
|
log " Kernel: $ACTUAL_VERSION"
|
|
|
|
#------------------------------------------------------------------------------
|
|
# Step 2: Apply Patches (idempotent — skip already applied)
|
|
#------------------------------------------------------------------------------
|
|
log ""
|
|
log "Step 2: Applying patches..."
|
|
|
|
PATCH_MARKER="$KERNEL_SRC/.archr-patches-applied"
|
|
|
|
if [ -f "$PATCH_MARKER" ]; then
|
|
log " Patches already applied (marker exists). Skipping."
|
|
else
|
|
PATCH_COUNT=0
|
|
|
|
# Order: mainline first (GPIO API, input-polldev), then 6.12-LTS, then device-specific
|
|
for PATCH_SUBDIR in mainline 6.12-lts device; do
|
|
PDIR="$PATCHES_DIR/$PATCH_SUBDIR"
|
|
if [ ! -d "$PDIR" ]; then
|
|
warn " Patch dir not found: $PDIR"
|
|
continue
|
|
fi
|
|
for PATCH in $(ls "$PDIR"/*.patch 2>/dev/null | sort); do
|
|
PNAME=$(basename "$PATCH")
|
|
log " Applying [$PATCH_SUBDIR] $PNAME..."
|
|
if ! patch -d "$KERNEL_SRC" -p1 --forward --batch < "$PATCH" 2>&1 | tail -3; then
|
|
warn " Patch may have failed or already applied: $PNAME"
|
|
fi
|
|
PATCH_COUNT=$((PATCH_COUNT + 1))
|
|
done
|
|
done
|
|
|
|
touch "$PATCH_MARKER"
|
|
log " Applied $PATCH_COUNT patches"
|
|
fi
|
|
|
|
#------------------------------------------------------------------------------
|
|
# Step 3: Copy DTS files
|
|
#------------------------------------------------------------------------------
|
|
log ""
|
|
log "Step 3: Copying DTS files..."
|
|
|
|
if [ ! -d "$DTS_DIR" ]; then
|
|
error "DTS directory not found: $DTS_DIR"
|
|
fi
|
|
|
|
DTS_COUNT=0
|
|
for DTS_FILE in "$DTS_DIR"/*.dts "$DTS_DIR"/*.dtsi; do
|
|
[ -f "$DTS_FILE" ] || continue
|
|
DEST="$KERNEL_DTS_DIR/$(basename "$DTS_FILE")"
|
|
cp "$DTS_FILE" "$DEST"
|
|
DTS_COUNT=$((DTS_COUNT + 1))
|
|
done
|
|
|
|
# Add DTS entries to Makefile (for each .dts, ensure dtb- line exists)
|
|
ROCKCHIP_MAKEFILE="$KERNEL_DTS_DIR/Makefile"
|
|
for DTS_FILE in "$DTS_DIR"/*.dts; do
|
|
[ -f "$DTS_FILE" ] || continue
|
|
DTB_NAME=$(basename "$DTS_FILE" .dts)
|
|
if ! grep -q "${DTB_NAME}.dtb" "$ROCKCHIP_MAKEFILE"; then
|
|
# Add before the first empty line or at the end of the dtb list
|
|
echo "dtb-\$(CONFIG_ARCH_ROCKCHIP) += ${DTB_NAME}.dtb" >> "$ROCKCHIP_MAKEFILE"
|
|
log " Added to Makefile: ${DTB_NAME}.dtb"
|
|
fi
|
|
done
|
|
|
|
log " Copied $DTS_COUNT DTS files"
|
|
|
|
#------------------------------------------------------------------------------
|
|
# Step 4: Configure Kernel
|
|
#------------------------------------------------------------------------------
|
|
log ""
|
|
log "Step 4: Configuring kernel..."
|
|
|
|
if [ ! -f "$CONFIG_BASE" ]; then
|
|
error "Config base not found: $CONFIG_BASE"
|
|
fi
|
|
|
|
# Copy Arch R base config
|
|
cp "$CONFIG_BASE" "$KERNEL_SRC/.config"
|
|
|
|
# Replace placeholder for initramfs
|
|
INITRAMFS_DIR="$OUTPUT_DIR/initramfs"
|
|
if [ -d "$INITRAMFS_DIR" ] && [ -x "$INITRAMFS_DIR/init" ]; then
|
|
log " Embedding initramfs from: $INITRAMFS_DIR"
|
|
sed -i "s|@INITRAMFS_SOURCE@|${INITRAMFS_DIR}|" "$KERNEL_SRC/.config"
|
|
else
|
|
warn " Initramfs not found at $INITRAMFS_DIR"
|
|
warn " Run build-initramfs.sh first! Disabling embedded initramfs."
|
|
sed -i 's|CONFIG_INITRAMFS_SOURCE=.*|CONFIG_INITRAMFS_SOURCE=""|' "$KERNEL_SRC/.config"
|
|
fi
|
|
|
|
# Finalize config
|
|
make -C "$KERNEL_SRC" ARCH=$ARCH CROSS_COMPILE=$CROSS_COMPILE olddefconfig
|
|
|
|
# Verify critical settings
|
|
log " Verifying config..."
|
|
check_config() {
|
|
local key="$1" expected="$2" desc="$3"
|
|
local val=$(grep "^${key}=" "$KERNEL_SRC/.config" 2>/dev/null | head -1)
|
|
if [ -z "$val" ]; then
|
|
val=$(grep "^# ${key} is not set" "$KERNEL_SRC/.config" 2>/dev/null | head -1)
|
|
fi
|
|
if echo "$val" | grep -q "$expected"; then
|
|
log " $desc: OK"
|
|
else
|
|
warn " $desc: UNEXPECTED ($val)"
|
|
fi
|
|
}
|
|
|
|
check_config "CONFIG_DRM_PANFROST" "=m" "Panfrost GPU"
|
|
check_config "CONFIG_DRM_PANEL_SITRONIX_ST7703" "=y" "ST7703 panel"
|
|
check_config "CONFIG_FRAMEBUFFER_CONSOLE" "=y" "fbcon"
|
|
check_config "CONFIG_FRAMEBUFFER_CONSOLE_DEFERRED_TAKEOVER" "is not set" "No deferred takeover"
|
|
check_config "CONFIG_EXT4_FS" "=y" "ext4"
|
|
check_config "CONFIG_DEVTMPFS" "=y" "devtmpfs"
|
|
|
|
log " Kernel configured"
|
|
|
|
#------------------------------------------------------------------------------
|
|
# Step 5: Build Kernel Image
|
|
#------------------------------------------------------------------------------
|
|
log ""
|
|
log "Step 5: Building kernel Image..."
|
|
|
|
make -C "$KERNEL_SRC" -j$JOBS ARCH=$ARCH CROSS_COMPILE=$CROSS_COMPILE Image 2>&1 | tail -5
|
|
|
|
if [ ! -f "$KERNEL_SRC/arch/arm64/boot/Image" ]; then
|
|
error "Kernel Image build failed!"
|
|
fi
|
|
|
|
IMAGE_SIZE=$(du -h "$KERNEL_SRC/arch/arm64/boot/Image" | cut -f1)
|
|
log " Kernel Image built ($IMAGE_SIZE)"
|
|
|
|
#------------------------------------------------------------------------------
|
|
# Step 6: Build ALL Device Trees
|
|
#------------------------------------------------------------------------------
|
|
log ""
|
|
log "Step 6: Building Device Trees..."
|
|
|
|
# Build dtbs target (compiles all DTBs referenced in Makefile)
|
|
make -C "$KERNEL_SRC" -j$JOBS ARCH=$ARCH CROSS_COMPILE=$CROSS_COMPILE DTC_FLAGS=-@ dtbs 2>&1 | tail -10
|
|
|
|
# Verify R36S DTB was built
|
|
if [ ! -f "$KERNEL_DTS_DIR/rk3326-gameconsole-r36s.dtb" ]; then
|
|
error "R36S DTB not built!"
|
|
fi
|
|
|
|
DTB_COUNT=$(find "$KERNEL_DTS_DIR" -name "rk3326-*.dtb" | wc -l)
|
|
log " Built $DTB_COUNT RK3326 DTBs"
|
|
|
|
#------------------------------------------------------------------------------
|
|
# Step 7: Build Kernel Modules
|
|
#------------------------------------------------------------------------------
|
|
log ""
|
|
log "Step 7: Building kernel modules..."
|
|
|
|
make -C "$KERNEL_SRC" -j$JOBS ARCH=$ARCH CROSS_COMPILE=$CROSS_COMPILE modules 2>&1 | tail -5
|
|
|
|
log " Kernel modules built"
|
|
|
|
#------------------------------------------------------------------------------
|
|
# Step 8: Build Out-of-Tree Drivers
|
|
#------------------------------------------------------------------------------
|
|
log ""
|
|
log "Step 8: Building out-of-tree drivers..."
|
|
|
|
if [ -d "$JOYPAD_DIR" ] && [ -f "$JOYPAD_DIR/Makefile" ]; then
|
|
log " Building archr-joypad..."
|
|
make -C "$KERNEL_SRC" ARCH=$ARCH CROSS_COMPILE=$CROSS_COMPILE \
|
|
M="$JOYPAD_DIR" modules 2>&1 | tail -5
|
|
if find "$JOYPAD_DIR" -name "*.ko" | grep -q .; then
|
|
log " archr-joypad: OK"
|
|
else
|
|
warn " archr-joypad: no .ko files produced"
|
|
fi
|
|
else
|
|
warn " Joypad driver not found at: $JOYPAD_DIR"
|
|
fi
|
|
|
|
#------------------------------------------------------------------------------
|
|
# Step 9: Install to Output Directory
|
|
#------------------------------------------------------------------------------
|
|
log ""
|
|
log "Step 9: Installing artifacts..."
|
|
|
|
mkdir -p "$BOOT_DIR"
|
|
mkdir -p "$MODULES_DIR"
|
|
|
|
# Copy kernel image as KERNEL (Arch R naming convention)
|
|
cp "$KERNEL_SRC/arch/arm64/boot/Image" "$BOOT_DIR/KERNEL"
|
|
log " Copied: KERNEL"
|
|
|
|
# Copy ALL RK3326 DTBs to dtbs/ subdirectory
|
|
mkdir -p "$BOOT_DIR/dtbs"
|
|
for DTB in "$KERNEL_DTS_DIR"/rk3326-*.dtb; do
|
|
[ -f "$DTB" ] || continue
|
|
cp "$DTB" "$BOOT_DIR/dtbs/"
|
|
done
|
|
log " Copied: $(ls "$BOOT_DIR/dtbs"/rk3326-*.dtb 2>/dev/null | wc -l) DTBs to dtbs/"
|
|
|
|
# Install kernel modules
|
|
set -o pipefail
|
|
make -C "$KERNEL_SRC" ARCH=$ARCH CROSS_COMPILE=$CROSS_COMPILE \
|
|
INSTALL_MOD_PATH="$MODULES_DIR" \
|
|
modules_install 2>&1 | tail -5
|
|
set +o pipefail
|
|
|
|
# Install joypad driver module
|
|
if find "$JOYPAD_DIR" -name "*.ko" | grep -q .; then
|
|
KREL=$(cat "$KERNEL_SRC/include/config/kernel.release" 2>/dev/null)
|
|
JOYPAD_DEST="$MODULES_DIR/lib/modules/$KREL/extra/archr-joypad"
|
|
mkdir -p "$JOYPAD_DEST"
|
|
cp "$JOYPAD_DIR"/*.ko "$JOYPAD_DEST/"
|
|
log " Installed joypad modules to: extra/archr-joypad/"
|
|
# Regenerate modules.dep
|
|
depmod -b "$MODULES_DIR" "$KREL"
|
|
fi
|
|
|
|
# Remove build/source symlinks (save space on target)
|
|
rm -f "$MODULES_DIR/lib/modules/"*/source 2>/dev/null || true
|
|
rm -f "$MODULES_DIR/lib/modules/"*/build 2>/dev/null || true
|
|
|
|
# Verify critical modules
|
|
KREL=$(cat "$KERNEL_SRC/include/config/kernel.release" 2>/dev/null)
|
|
for MOD in panfrost; do
|
|
if find "$MODULES_DIR/lib/modules/$KREL" -name "${MOD}.ko*" 2>/dev/null | grep -q .; then
|
|
log " Module OK: $MOD"
|
|
else
|
|
warn " Module MISSING: $MOD"
|
|
fi
|
|
done
|
|
# Note: rockchipdrm is CONFIG_DRM_ROCKCHIP=y (built-in, not a module) — no .ko to check
|
|
|
|
log " Modules installed"
|
|
|
|
#------------------------------------------------------------------------------
|
|
# Summary
|
|
#------------------------------------------------------------------------------
|
|
log ""
|
|
log "================================================================"
|
|
log " BUILD COMPLETE"
|
|
log "================================================================"
|
|
log ""
|
|
|
|
KERNEL_FULL=$(make -C "$KERNEL_SRC" -s kernelversion 2>/dev/null)
|
|
KERNEL_SIZE=$(du -h "$BOOT_DIR/KERNEL" | cut -f1)
|
|
MODULES_SIZE=$(du -sh "$MODULES_DIR" 2>/dev/null | cut -f1)
|
|
DTB_COUNT=$(ls "$BOOT_DIR/dtbs"/rk3326-*.dtb 2>/dev/null | wc -l)
|
|
|
|
log "Kernel: $KERNEL_FULL (mainline + Arch R patches)"
|
|
log "KERNEL: $BOOT_DIR/KERNEL ($KERNEL_SIZE)"
|
|
log "DTBs: $DTB_COUNT files in $BOOT_DIR/dtbs/"
|
|
log "Modules: $MODULES_DIR/ ($MODULES_SIZE)"
|
|
log ""
|
|
log "Key DTBs:"
|
|
for DTB in rk3326-gameconsole-r36s rk3326-odroid-go2 rk3326-gameconsole-r33s; do
|
|
if [ -f "$BOOT_DIR/dtbs/${DTB}.dtb" ]; then
|
|
log " ${DTB}.dtb ($(du -h "$BOOT_DIR/dtbs/${DTB}.dtb" | cut -f1))"
|
|
fi
|
|
done
|
|
log ""
|
|
log "Ready for deployment to SD card!"
|