mirror of
https://github.com/archr-linux/Arch-R.git
synced 2026-03-31 14:41:55 -07:00
- Clone variant: mainline U-Boot v2025.10, boot.scr, clone DTS (type5) - Initramfs splash: archr-init.c with embedded BMP, sub-second display - Panel wizard: auto-detect with fsync persistence, evdev X-button reset - Hotkeys: adc-keys volume for clone, HP jack detection, brightness persist - Boot.ini: ASCII-only (no Unicode), GPIO check removed - ES wrapper: removed framebuffer blanking (preserves splash) - Build pipeline: both variants, splash generation, panel DTBOs - .gitignore: exclude large bootloader trees and build artifacts Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
210 lines
7.5 KiB
Bash
210 lines
7.5 KiB
Bash
#!/bin/bash
|
|
|
|
#==============================================================================
|
|
# Arch R - First Boot Setup Script
|
|
#==============================================================================
|
|
# Runs on first boot to:
|
|
# 1. Create ROMS partition (FAT32) with remaining SD card space
|
|
# 2. Generate SSH keys and machine-id
|
|
# 3. Configure RetroArch and EmulationStation
|
|
# 4. Create ROM directories
|
|
#==============================================================================
|
|
|
|
FIRST_BOOT_FLAG="/var/lib/archr/.first-boot-done"
|
|
LOG_FILE="/var/log/first-boot.log"
|
|
|
|
# Log all output for debugging
|
|
exec > >(tee -a "$LOG_FILE") 2>&1
|
|
|
|
if [ -f "$FIRST_BOOT_FLAG" ]; then
|
|
echo "First boot already completed, skipping"
|
|
exit 0
|
|
fi
|
|
|
|
echo "=== Arch R First Boot Setup === ($(date))"
|
|
|
|
#------------------------------------------------------------------------------
|
|
# Detect SD card device
|
|
#------------------------------------------------------------------------------
|
|
ROOT_SOURCE=$(findmnt -no SOURCE /)
|
|
ROOT_DISK=$(lsblk -no PKNAME "$ROOT_SOURCE" | head -1)
|
|
ROOT_DISK="/dev/${ROOT_DISK}"
|
|
|
|
echo "Root device: $ROOT_SOURCE"
|
|
echo "SD card: $ROOT_DISK"
|
|
|
|
#------------------------------------------------------------------------------
|
|
# Create ROMS partition (partition 3) if it doesn't exist
|
|
#------------------------------------------------------------------------------
|
|
ROMS_PART="${ROOT_DISK}p3"
|
|
ROMS_OK=false
|
|
|
|
if ! lsblk "$ROMS_PART" &>/dev/null; then
|
|
echo "Creating ROMS partition..."
|
|
|
|
# Parse partition info using sfdisk dump format (reliable, no column alignment issues)
|
|
LAST_INFO=$(sfdisk -d "$ROOT_DISK" 2>/dev/null | grep '^/dev' | tail -1)
|
|
PART_START=$(echo "$LAST_INFO" | grep -o 'start=[[:space:]]*[0-9]*' | grep -o '[0-9]*')
|
|
PART_SIZE=$(echo "$LAST_INFO" | grep -o 'size=[[:space:]]*[0-9]*' | grep -o '[0-9]*')
|
|
|
|
if [ -n "$PART_START" ] && [ -n "$PART_SIZE" ]; then
|
|
LAST_END=$((PART_START + PART_SIZE))
|
|
DISK_SECTORS=$(blockdev --getsz "$ROOT_DISK" 2>/dev/null)
|
|
|
|
echo " Last partition ends at sector $LAST_END, disk has $DISK_SECTORS sectors"
|
|
|
|
if [ -n "$DISK_SECTORS" ] && [ "$LAST_END" -lt "$DISK_SECTORS" ]; then
|
|
echo "${LAST_END},+,0c" | sfdisk --force --append "$ROOT_DISK" 2>&1 || \
|
|
echo ",,0c" | sfdisk --force --append "$ROOT_DISK" 2>&1 || \
|
|
echo " ERROR: sfdisk --append failed"
|
|
else
|
|
echo " ERROR: No free space on disk (last=$LAST_END, total=$DISK_SECTORS)"
|
|
fi
|
|
else
|
|
echo " WARNING: Could not parse partition table, trying generic append"
|
|
echo ",,0c" | sfdisk --force --append "$ROOT_DISK" 2>&1 || \
|
|
echo " ERROR: sfdisk --append failed"
|
|
fi
|
|
|
|
# Tell kernel about the new partition (try multiple methods)
|
|
partprobe "$ROOT_DISK" 2>/dev/null
|
|
sleep 2
|
|
|
|
if ! lsblk "$ROMS_PART" &>/dev/null; then
|
|
# partprobe failed — try partx (more reliable for adding single partitions)
|
|
partx -a "$ROOT_DISK" 2>/dev/null
|
|
sleep 2
|
|
fi
|
|
|
|
if ! lsblk "$ROMS_PART" &>/dev/null; then
|
|
# Last resort: blockdev re-read
|
|
blockdev --rereadpt "$ROOT_DISK" 2>/dev/null
|
|
sleep 3
|
|
fi
|
|
|
|
if lsblk "$ROMS_PART" &>/dev/null; then
|
|
echo " Formatting as FAT32..."
|
|
mkfs.vfat -F 32 -n ROMS "$ROMS_PART"
|
|
echo " ROMS partition created!"
|
|
else
|
|
echo " WARNING: Partition created in table but kernel can't see it yet"
|
|
echo " ROMS will be available after reboot"
|
|
fi
|
|
else
|
|
echo " ROMS partition already exists"
|
|
# Ensure it has a FAT32 filesystem with the ROMS label
|
|
if ! blkid "$ROMS_PART" | grep -q 'TYPE="vfat"'; then
|
|
echo " Formatting existing partition as FAT32..."
|
|
mkfs.vfat -F 32 -n ROMS "$ROMS_PART"
|
|
elif ! blkid "$ROMS_PART" | grep -q 'LABEL="ROMS"'; then
|
|
echo " Setting label to ROMS..."
|
|
fatlabel "$ROMS_PART" ROMS 2>/dev/null || true
|
|
fi
|
|
fi
|
|
|
|
#------------------------------------------------------------------------------
|
|
# Mount ROMS partition and create directories
|
|
#------------------------------------------------------------------------------
|
|
echo "Setting up ROM directories..."
|
|
|
|
mkdir -p /roms
|
|
|
|
if lsblk "$ROMS_PART" &>/dev/null; then
|
|
if ! mountpoint -q /roms; then
|
|
mount "$ROMS_PART" /roms 2>&1 || echo " WARNING: Could not mount $ROMS_PART"
|
|
fi
|
|
fi
|
|
|
|
if mountpoint -q /roms; then
|
|
ROMS_OK=true
|
|
|
|
SYSTEMS=(
|
|
"nes" "snes" "gb" "gbc" "gba" "nds"
|
|
"megadrive" "mastersystem" "gamegear" "genesis" "segacd" "sega32x"
|
|
"n64" "psx" "psp"
|
|
"dreamcast" "saturn"
|
|
"arcade" "mame" "fbneo" "neogeo"
|
|
"atari2600" "atari7800" "atarilynx"
|
|
"pcengine" "pcenginecd" "supergrafx"
|
|
"wonderswan" "wonderswancolor"
|
|
"ngp" "ngpc"
|
|
"virtualboy"
|
|
"scummvm" "dos"
|
|
"ports"
|
|
"bios"
|
|
)
|
|
|
|
for sys in "${SYSTEMS[@]}"; do
|
|
mkdir -p "/roms/$sys"
|
|
done
|
|
|
|
mkdir -p /roms/saves /roms/states
|
|
echo " ROM directories created"
|
|
else
|
|
echo " WARNING: /roms not mounted — directories will be created on next boot"
|
|
fi
|
|
|
|
#------------------------------------------------------------------------------
|
|
# Generate SSH host keys
|
|
#------------------------------------------------------------------------------
|
|
echo "Generating SSH host keys..."
|
|
ssh-keygen -A 2>/dev/null || true
|
|
|
|
#------------------------------------------------------------------------------
|
|
# Set random machine-id
|
|
#------------------------------------------------------------------------------
|
|
echo "Generating machine ID..."
|
|
rm -f /etc/machine-id
|
|
systemd-machine-id-setup
|
|
|
|
#------------------------------------------------------------------------------
|
|
# Enable services
|
|
#------------------------------------------------------------------------------
|
|
echo "Enabling services..."
|
|
systemctl enable NetworkManager 2>/dev/null || true
|
|
|
|
#------------------------------------------------------------------------------
|
|
# Configure RetroArch
|
|
#------------------------------------------------------------------------------
|
|
echo "Configuring RetroArch..."
|
|
|
|
RA_DIR="/home/archr/.config/retroarch"
|
|
mkdir -p "$RA_DIR/cores"
|
|
mkdir -p "$RA_DIR/saves"
|
|
mkdir -p "$RA_DIR/states"
|
|
mkdir -p "$RA_DIR/screenshots"
|
|
|
|
if [ ! -f "$RA_DIR/retroarch.cfg" ] && [ -f /etc/archr/retroarch.cfg ]; then
|
|
cp /etc/archr/retroarch.cfg "$RA_DIR/retroarch.cfg"
|
|
fi
|
|
|
|
# Set savefile/savestate directories to ROMS partition
|
|
sed -i "s|^savefile_directory =.*|savefile_directory = \"/roms/saves\"|" "$RA_DIR/retroarch.cfg" 2>/dev/null || true
|
|
sed -i "s|^savestate_directory =.*|savestate_directory = \"/roms/states\"|" "$RA_DIR/retroarch.cfg" 2>/dev/null || true
|
|
|
|
#------------------------------------------------------------------------------
|
|
# Configure EmulationStation
|
|
#------------------------------------------------------------------------------
|
|
echo "Configuring EmulationStation..."
|
|
|
|
ES_DIR="/home/archr/.emulationstation"
|
|
mkdir -p "$ES_DIR"
|
|
|
|
# Link system config
|
|
if [ ! -f "$ES_DIR/es_systems.cfg" ] && [ -f /etc/emulationstation/es_systems.cfg ]; then
|
|
ln -sf /etc/emulationstation/es_systems.cfg "$ES_DIR/es_systems.cfg"
|
|
fi
|
|
|
|
chown -R archr:archr /home/archr
|
|
|
|
#------------------------------------------------------------------------------
|
|
# Mark first boot complete (only if ROMS partition is working)
|
|
#------------------------------------------------------------------------------
|
|
if [ "$ROMS_OK" = true ]; then
|
|
mkdir -p "$(dirname "$FIRST_BOOT_FLAG")"
|
|
touch "$FIRST_BOOT_FLAG"
|
|
echo "=== First Boot Setup Complete ==="
|
|
else
|
|
echo "=== First Boot Setup Partial — ROMS partition will retry on next boot ==="
|
|
fi
|