Initial commit - Arch R project structure

This commit is contained in:
Douglas Teles
2026-02-04 14:09:18 -03:00
commit 487c4f2cbd
12 changed files with 1294 additions and 0 deletions

13
.gitignore vendored Normal file
View File

@@ -0,0 +1,13 @@
# Build output
output/
rootfs/staging/
*.log
# Archives
*.tar.gz
*.xz
*.img
# Kernel source (will be cloned separately)
kernel/src/
bootloader/src/

52
README.md Normal file
View File

@@ -0,0 +1,52 @@
# Arch R
> Arch Linux-based Gaming Distribution for R36S Handheld
## About
Arch R is a custom Linux distribution optimized for the R36S handheld gaming console.
Based on Arch Linux ARM with full support for RetroArch and EmulationStation.
## Building
### Prerequisites
- Ubuntu 22.04+ or WSL2
- Cross-compilation toolchain for aarch64
- 10GB+ free disk space
### Quick Start
```bash
# Setup build environment (run once)
./setup-toolchain.sh
# Build everything
./build-all.sh
# Output will be in output/ directory
```
## Project Structure
```
arch-r/
├── bootloader/ # U-Boot configuration
├── kernel/ # Kernel source and DTB
├── rootfs/ # Root filesystem overlay
├── config/ # Configuration files
├── scripts/ # Runtime scripts
└── output/ # Build artifacts
```
## Hardware Support
- **SoC**: Rockchip RK3326
- **Display**: 640x480
- **USB OTG**: Host mode with VBUS power
- **Wi-Fi**: AIC8800 USB adapter support
- **Controls**: Full joypad + analog sticks
## License
GPL v3

93
build-all.sh Normal file
View File

@@ -0,0 +1,93 @@
#!/bin/bash
#==============================================================================
# Arch R - Master Build Script
#==============================================================================
set -e
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
# Load environment
if [ -f "$SCRIPT_DIR/env.sh" ]; then
source "$SCRIPT_DIR/env.sh"
else
echo "ERROR: env.sh not found. Run setup-toolchain.sh first!"
exit 1
fi
echo "=========================================="
echo " Arch R Build System"
echo "=========================================="
echo ""
echo "Device: $ARCHR_DEVICE"
echo "SoC: $ARCHR_SOC"
echo ""
# Parse arguments
BUILD_KERNEL=0
BUILD_ROOTFS=0
BUILD_IMAGE=0
if [ $# -eq 0 ]; then
BUILD_KERNEL=1
BUILD_ROOTFS=1
BUILD_IMAGE=1
else
for arg in "$@"; do
case $arg in
kernel) BUILD_KERNEL=1 ;;
rootfs) BUILD_ROOTFS=1 ;;
image) BUILD_IMAGE=1 ;;
all)
BUILD_KERNEL=1
BUILD_ROOTFS=1
BUILD_IMAGE=1
;;
*)
echo "Unknown option: $arg"
echo "Usage: $0 [kernel|rootfs|image|all]"
exit 1
;;
esac
done
fi
# Build steps
if [ $BUILD_KERNEL -eq 1 ]; then
echo ""
echo "=== Building Kernel ==="
if [ -x "$SCRIPT_DIR/build-kernel.sh" ]; then
"$SCRIPT_DIR/build-kernel.sh"
else
echo "WARNING: build-kernel.sh not found or not executable"
fi
fi
if [ $BUILD_ROOTFS -eq 1 ]; then
echo ""
echo "=== Building Root Filesystem ==="
if [ -x "$SCRIPT_DIR/build-rootfs.sh" ]; then
"$SCRIPT_DIR/build-rootfs.sh"
else
echo "WARNING: build-rootfs.sh not found or not executable"
fi
fi
if [ $BUILD_IMAGE -eq 1 ]; then
echo ""
echo "=== Building SD Card Image ==="
if [ -x "$SCRIPT_DIR/build-image.sh" ]; then
"$SCRIPT_DIR/build-image.sh"
else
echo "WARNING: build-image.sh not found or not executable"
fi
fi
echo ""
echo "=========================================="
echo " Build Complete!"
echo "=========================================="
echo ""
echo "Output files are in: $ARCHR_OUTPUT"
ls -la "$ARCHR_OUTPUT" 2>/dev/null || echo "(empty)"

234
build-image.sh Normal file
View File

@@ -0,0 +1,234 @@
#!/bin/bash
#==============================================================================
# Arch R - SD Card Image Build Script
#==============================================================================
# Creates a bootable SD card image for R36S
#==============================================================================
set -e
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
# Load environment
if [ -f "$SCRIPT_DIR/env.sh" ]; then
source "$SCRIPT_DIR/env.sh"
else
echo "ERROR: env.sh not found!"
exit 1
fi
LOG_FILE="$ARCHR_OUTPUT/build-image.log"
IMAGE_FILE="$ARCHR_OUTPUT/archr-r36s.img"
IMAGE_SIZE="4G" # Minimum image size
log() {
echo "[$(date '+%H:%M:%S')] $1" | tee -a "$LOG_FILE"
}
log "=== Arch R Image Build ==="
#------------------------------------------------------------------------------
# Check root
#------------------------------------------------------------------------------
if [ "$EUID" -ne 0 ]; then
log "This script needs root for loop device operations."
log "Please run: sudo $0"
exit 1
fi
#------------------------------------------------------------------------------
# Check prerequisites
#------------------------------------------------------------------------------
log ""
log "Checking prerequisites..."
BOOT_FILES="$ARCHR_OUTPUT/boot"
ROOTFS_ARCHIVE="$ARCHR_OUTPUT/archr-rootfs.tar.gz"
if [ ! -d "$BOOT_FILES" ] || [ ! -f "$BOOT_FILES/Image" ]; then
log "ERROR: Kernel not built. Run build-kernel.sh first."
exit 1
fi
if [ ! -f "$ROOTFS_ARCHIVE" ]; then
log "ERROR: Rootfs not built. Run build-rootfs.sh first."
exit 1
fi
log " Prerequisites OK"
#------------------------------------------------------------------------------
# Step 1: Create image file
#------------------------------------------------------------------------------
log ""
log "Step 1: Creating image file..."
rm -f "$IMAGE_FILE"
truncate -s "$IMAGE_SIZE" "$IMAGE_FILE"
log " Created: $IMAGE_FILE ($IMAGE_SIZE)"
#------------------------------------------------------------------------------
# Step 2: Partition image
#------------------------------------------------------------------------------
log ""
log "Step 2: Partitioning image..."
# Partition layout:
# 0MB-1MB: Reserved for bootloader (idbloader, u-boot)
# 1MB-129MB: Boot partition (FAT32)
# 129MB-end: Root partition (ext4)
parted -s "$IMAGE_FILE" mklabel msdos
parted -s "$IMAGE_FILE" mkpart primary fat32 1MiB 129MiB
parted -s "$IMAGE_FILE" mkpart primary ext4 129MiB 100%
parted -s "$IMAGE_FILE" set 1 boot on
log " Partitions created"
#------------------------------------------------------------------------------
# Step 3: Setup loop device
#------------------------------------------------------------------------------
log ""
log "Step 3: Setting up loop device..."
LOOP_DEV=$(losetup --find --show --partscan "$IMAGE_FILE")
log " Loop device: $LOOP_DEV"
# Wait for partitions to appear
sleep 2
BOOT_PART="${LOOP_DEV}p1"
ROOT_PART="${LOOP_DEV}p2"
#------------------------------------------------------------------------------
# Step 4: Format partitions
#------------------------------------------------------------------------------
log ""
log "Step 4: Formatting partitions..."
mkfs.vfat -F 32 -n BOOT "$BOOT_PART"
log " Formatted: $BOOT_PART (FAT32)"
mkfs.ext4 -L ROOT "$ROOT_PART"
log " Formatted: $ROOT_PART (ext4)"
#------------------------------------------------------------------------------
# Step 5: Mount and populate
#------------------------------------------------------------------------------
log ""
log "Step 5: Mounting partitions..."
MOUNT_DIR="$ARCHR_OUTPUT/mnt"
BOOT_MOUNT="$MOUNT_DIR/boot"
ROOT_MOUNT="$MOUNT_DIR/root"
mkdir -p "$BOOT_MOUNT" "$ROOT_MOUNT"
mount "$BOOT_PART" "$BOOT_MOUNT"
mount "$ROOT_PART" "$ROOT_MOUNT"
log " Mounted partitions"
#------------------------------------------------------------------------------
# Step 6: Copy boot files
#------------------------------------------------------------------------------
log ""
log "Step 6: Copying boot files..."
# Copy kernel
cp "$BOOT_FILES/Image" "$BOOT_MOUNT/"
log " Copied: Image"
# Copy DTB
if [ -f "$BOOT_FILES/rk3326-r36s.dtb" ]; then
cp "$BOOT_FILES/rk3326-r36s.dtb" "$BOOT_MOUNT/"
log " Copied: rk3326-r36s.dtb"
fi
# Create boot.ini for R36S
cat > "$BOOT_MOUNT/boot.ini" << 'EOF'
# Arch R Boot Configuration for R36S
setenv bootargs "root=/dev/mmcblk0p2 rootwait rw console=ttyFIQ0 quiet splash loglevel=0"
setenv loadaddr "0x02000000"
setenv initrd_loadaddr "0x01100000"
setenv dtb_loadaddr "0x01f00000"
load mmc 1:1 ${loadaddr} Image
load mmc 1:1 ${dtb_loadaddr} rk3326-r36s.dtb
booti ${loadaddr} - ${dtb_loadaddr}
EOF
log " Created: boot.ini"
#------------------------------------------------------------------------------
# Step 7: Extract rootfs
#------------------------------------------------------------------------------
log ""
log "Step 7: Extracting rootfs..."
tar -xzf "$ROOTFS_ARCHIVE" -C "$ROOT_MOUNT/"
log " Rootfs extracted"
# Create fstab
cat > "$ROOT_MOUNT/etc/fstab" << 'EOF'
# Arch R fstab
/dev/mmcblk0p1 /boot vfat defaults 0 2
/dev/mmcblk0p2 / ext4 defaults,noatime 0 1
EOF
log " Created: /etc/fstab"
#------------------------------------------------------------------------------
# Step 8: Install bootloader (if available)
#------------------------------------------------------------------------------
log ""
log "Step 8: Installing bootloader..."
UBOOT_DIR="$ARCHR_BOOTLOADER/output"
if [ -f "$UBOOT_DIR/idbloader.img" ] && [ -f "$UBOOT_DIR/u-boot.itb" ]; then
dd if="$UBOOT_DIR/idbloader.img" of="$LOOP_DEV" seek=64 conv=notrunc
dd if="$UBOOT_DIR/u-boot.itb" of="$LOOP_DEV" seek=16384 conv=notrunc
log " Bootloader installed"
else
log " WARNING: U-Boot not found. You may need to install it manually."
log " For now, the image will use the existing bootloader on SD card."
fi
#------------------------------------------------------------------------------
# Step 9: Cleanup
#------------------------------------------------------------------------------
log ""
log "Step 9: Cleanup..."
sync
umount "$BOOT_MOUNT"
umount "$ROOT_MOUNT"
losetup -d "$LOOP_DEV"
rmdir "$BOOT_MOUNT" "$ROOT_MOUNT" "$MOUNT_DIR"
log " Cleanup complete"
#------------------------------------------------------------------------------
# Step 10: Compress image
#------------------------------------------------------------------------------
log ""
log "Step 10: Compressing image..."
xz -z -k -9 -T 0 "$IMAGE_FILE" 2>&1 | tee -a "$LOG_FILE"
log " Created: ${IMAGE_FILE}.xz"
#------------------------------------------------------------------------------
# Complete
#------------------------------------------------------------------------------
log ""
log "=== Image Build Complete ==="
log ""
log "Output files:"
ls -lh "$IMAGE_FILE"*
log ""
log "To flash to SD card:"
log " xzcat ${IMAGE_FILE}.xz | sudo dd of=/dev/sdX bs=4M status=progress"

168
build-kernel.sh Normal file
View File

@@ -0,0 +1,168 @@
#!/bin/bash
#==============================================================================
# Arch R - Kernel Build Script
#==============================================================================
# Builds the Linux kernel with R36S Device Tree
#==============================================================================
set -e
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
# Load environment
if [ -f "$SCRIPT_DIR/env.sh" ]; then
source "$SCRIPT_DIR/env.sh"
else
echo "ERROR: env.sh not found!"
exit 1
fi
LOG_FILE="$ARCHR_OUTPUT/build-kernel.log"
log() {
echo "[$(date '+%H:%M:%S')] $1" | tee -a "$LOG_FILE"
}
log "=== Arch R Kernel Build ==="
#------------------------------------------------------------------------------
# Configuration
#------------------------------------------------------------------------------
# Kernel source - You can use:
# 1. Rockchip BSP kernel (4.4.x) - More hardware support
# 2. Mainline kernel (5.x/6.x) - Newer features but may need more patches
KERNEL_VERSION="4.4.189"
KERNEL_SRC_DIR="$ARCHR_KERNEL/src/linux-$KERNEL_VERSION"
# If using dArkOS kernel source
DARKOS_KERNEL_URL="" # Set this to your kernel source repo
#------------------------------------------------------------------------------
# Step 1: Check/Download Kernel Source
#------------------------------------------------------------------------------
log ""
log "Step 1: Checking kernel source..."
if [ -d "$KERNEL_SRC_DIR" ]; then
log " Kernel source exists at: $KERNEL_SRC_DIR"
else
log " Kernel source not found!"
log ""
log " You need to provide the kernel source. Options:"
log " 1. Copy the dArkOS kernel source to: $KERNEL_SRC_DIR"
log " 2. Clone from a git repository"
log ""
log " Example:"
log " git clone <kernel-repo> $KERNEL_SRC_DIR"
log ""
exit 1
fi
#------------------------------------------------------------------------------
# Step 2: Apply R36S Device Tree
#------------------------------------------------------------------------------
log ""
log "Step 2: Checking Device Tree..."
DTS_FILE="$ARCHR_KERNEL/dts/rk3326-r36s.dts"
if [ ! -f "$DTS_FILE" ]; then
log " R36S DTS not found. Creating from template..."
# Check if we have the original DTB to decompile
if [ -f "$SCRIPT_DIR/../gameconsole-r36s.dtb" ]; then
log " Found gameconsole-r36s.dtb, decompiling..."
dtc -I dtb -O dts "$SCRIPT_DIR/../gameconsole-r36s.dtb" -o "$DTS_FILE" 2>/dev/null
log " Created: $DTS_FILE"
else
log " ERROR: No DTB or DTS found!"
log " Please place gameconsole-r36s.dtb in the parent directory"
exit 1
fi
fi
#------------------------------------------------------------------------------
# Step 3: Apply kernel config
#------------------------------------------------------------------------------
log ""
log "Step 3: Configuring kernel..."
CONFIG_FILE="$ARCHR_KERNEL/configs/r36s_defconfig"
if [ ! -f "$CONFIG_FILE" ]; then
log " No custom config found, using defconfig from kernel..."
cd "$KERNEL_SRC_DIR"
# Try to use existing RK3326 config
if [ -f "arch/arm64/configs/rk3326_linux_defconfig" ]; then
make ARCH=$ARCH CROSS_COMPILE=$CROSS_COMPILE rk3326_linux_defconfig
elif [ -f "arch/arm64/configs/rockchip_linux_defconfig" ]; then
make ARCH=$ARCH CROSS_COMPILE=$CROSS_COMPILE rockchip_linux_defconfig
else
log " WARNING: No suitable defconfig found!"
make ARCH=$ARCH CROSS_COMPILE=$CROSS_COMPILE defconfig
fi
else
log " Using custom config: $CONFIG_FILE"
cp "$CONFIG_FILE" "$KERNEL_SRC_DIR/.config"
fi
#------------------------------------------------------------------------------
# Step 4: Build kernel
#------------------------------------------------------------------------------
log ""
log "Step 4: Building kernel... (this may take a while)"
cd "$KERNEL_SRC_DIR"
# Disable warnings as errors if needed
sed -i 's/CONFIG_ERROR_ON_WARNING=y/CONFIG_ERROR_ON_WARNING=n/' .config 2>/dev/null || true
# Build kernel image
log " Building Image..."
make ARCH=$ARCH CROSS_COMPILE=$CROSS_COMPILE Image $MAKEFLAGS 2>&1 | tee -a "$LOG_FILE"
# Build DTBs
log " Building Device Trees..."
make ARCH=$ARCH CROSS_COMPILE=$CROSS_COMPILE dtbs $MAKEFLAGS 2>&1 | tee -a "$LOG_FILE"
# Build modules
log " Building modules..."
make ARCH=$ARCH CROSS_COMPILE=$CROSS_COMPILE modules $MAKEFLAGS 2>&1 | tee -a "$LOG_FILE"
#------------------------------------------------------------------------------
# Step 5: Install to output directory
#------------------------------------------------------------------------------
log ""
log "Step 5: Installing kernel artifacts..."
mkdir -p "$ARCHR_OUTPUT/boot"
mkdir -p "$ARCHR_OUTPUT/modules"
# Copy kernel image
cp arch/arm64/boot/Image "$ARCHR_OUTPUT/boot/"
log " Copied: Image"
# Copy DTB
if [ -f "arch/arm64/boot/dts/rockchip/rk3326-r36s.dtb" ]; then
cp "arch/arm64/boot/dts/rockchip/rk3326-r36s.dtb" "$ARCHR_OUTPUT/boot/"
log " Copied: rk3326-r36s.dtb"
fi
# Install modules
make ARCH=$ARCH CROSS_COMPILE=$CROSS_COMPILE \
INSTALL_MOD_PATH="$ARCHR_OUTPUT/modules" \
modules_install 2>&1 | tee -a "$LOG_FILE"
log " Modules installed to: $ARCHR_OUTPUT/modules"
#------------------------------------------------------------------------------
# Complete
#------------------------------------------------------------------------------
log ""
log "=== Kernel Build Complete ==="
log ""
log "Artifacts:"
ls -la "$ARCHR_OUTPUT/boot/"

224
build-rootfs.sh Normal file
View File

@@ -0,0 +1,224 @@
#!/bin/bash
#==============================================================================
# Arch R - Root Filesystem Build Script
#==============================================================================
# Creates an Arch Linux ARM root filesystem for R36S
#==============================================================================
set -e
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
# Load environment
if [ -f "$SCRIPT_DIR/env.sh" ]; then
source "$SCRIPT_DIR/env.sh"
else
echo "ERROR: env.sh not found!"
exit 1
fi
LOG_FILE="$ARCHR_OUTPUT/build-rootfs.log"
ROOTFS_DIR="$ARCHR_ROOTFS/staging"
ROOTFS_ARCHIVE="$ARCHR_OUTPUT/archr-rootfs.tar.gz"
log() {
echo "[$(date '+%H:%M:%S')] $1" | tee -a "$LOG_FILE"
}
log "=== Arch R Root Filesystem Build ==="
#------------------------------------------------------------------------------
# Check if running as root (required for chroot)
#------------------------------------------------------------------------------
if [ "$EUID" -ne 0 ]; then
log "This script needs to run as root for chroot operations."
log "Please run: sudo $0"
exit 1
fi
#------------------------------------------------------------------------------
# Step 1: Download Arch Linux ARM base
#------------------------------------------------------------------------------
log ""
log "Step 1: Getting Arch Linux ARM base..."
ALARM_ROOTFS="$ARCHR_ROOTFS/ArchLinuxARM-aarch64-latest.tar.gz"
ALARM_URL="http://os.archlinuxarm.org/os/ArchLinuxARM-aarch64-latest.tar.gz"
if [ -f "$ALARM_ROOTFS" ]; then
log " Base archive exists: $ALARM_ROOTFS"
else
log " Downloading Arch Linux ARM..."
wget -O "$ALARM_ROOTFS" "$ALARM_URL" 2>&1 | tee -a "$LOG_FILE"
fi
#------------------------------------------------------------------------------
# Step 2: Extract rootfs
#------------------------------------------------------------------------------
log ""
log "Step 2: Extracting rootfs..."
# Clean staging directory
rm -rf "$ROOTFS_DIR"
mkdir -p "$ROOTFS_DIR"
bsdtar -xpf "$ALARM_ROOTFS" -C "$ROOTFS_DIR" 2>&1 | tee -a "$LOG_FILE"
log " Extracted to: $ROOTFS_DIR"
#------------------------------------------------------------------------------
# Step 3: Setup for chroot
#------------------------------------------------------------------------------
log ""
log "Step 3: Setting up for chroot..."
# Copy QEMU static binary for ARM64 emulation
cp /usr/bin/qemu-aarch64-static "$ROOTFS_DIR/usr/bin/"
# Mount required filesystems
mount -t proc /proc "$ROOTFS_DIR/proc"
mount -t sysfs /sys "$ROOTFS_DIR/sys"
mount -o bind /dev "$ROOTFS_DIR/dev"
mount -o bind /dev/pts "$ROOTFS_DIR/dev/pts"
# Copy DNS resolution
cp /etc/resolv.conf "$ROOTFS_DIR/etc/resolv.conf"
log " Chroot environment ready"
#------------------------------------------------------------------------------
# Step 4: Configure system in chroot
#------------------------------------------------------------------------------
log ""
log "Step 4: Configuring system in chroot..."
cat > "$ROOTFS_DIR/tmp/setup.sh" << 'CHROOT_SCRIPT'
#!/bin/bash
set -e
echo "=== Inside chroot ==="
# Initialize pacman keyring
pacman-key --init
pacman-key --populate archlinuxarm
# Update system
pacman -Syu --noconfirm
# Install base packages
pacman -S --noconfirm --needed \
base \
linux-firmware \
networkmanager \
wpa_supplicant \
sudo \
vim \
htop \
mesa \
sdl2 \
alsa-utils \
git \
# Install gaming packages
pacman -S --noconfirm --needed \
retroarch \
retroarch-assets-xmb \
retroarch-assets-ozone \
# Install libretro cores (available in AUR or prebuilt)
# Note: Not all cores are in official repos
pacman -S --noconfirm --needed \
libretro-mgba \
libretro-snes9x \
libretro-nestopia \
libretro-genesis-plus-gx \
|| echo "Some cores may need to be built separately"
# Create archr user
useradd -m -G wheel -s /bin/bash archr 2>/dev/null || true
echo "archr:archr" | chpasswd
# Allow wheel group sudo
echo "%wheel ALL=(ALL) NOPASSWD: ALL" > /etc/sudoers.d/wheel
# Set hostname
echo "archr" > /etc/hostname
# Enable services
systemctl enable NetworkManager
# Set timezone
ln -sf /usr/share/zoneinfo/America/Sao_Paulo /etc/localtime
# Generate locales
echo "en_US.UTF-8 UTF-8" >> /etc/locale.gen
echo "pt_BR.UTF-8 UTF-8" >> /etc/locale.gen
locale-gen
# Cleanup
pacman -Scc --noconfirm
echo "=== Chroot setup complete ==="
CHROOT_SCRIPT
chmod +x "$ROOTFS_DIR/tmp/setup.sh"
chroot "$ROOTFS_DIR" /tmp/setup.sh 2>&1 | tee -a "$LOG_FILE"
#------------------------------------------------------------------------------
# Step 5: Apply overlay
#------------------------------------------------------------------------------
log ""
log "Step 5: Applying overlay..."
if [ -d "$ARCHR_ROOTFS/overlay" ]; then
cp -a "$ARCHR_ROOTFS/overlay/"* "$ROOTFS_DIR/" 2>/dev/null || true
log " Overlay applied"
fi
#------------------------------------------------------------------------------
# Step 6: Install kernel modules
#------------------------------------------------------------------------------
log ""
log "Step 6: Installing kernel modules..."
if [ -d "$ARCHR_OUTPUT/modules/lib/modules" ]; then
cp -a "$ARCHR_OUTPUT/modules/lib/modules/"* "$ROOTFS_DIR/lib/modules/" 2>/dev/null || true
log " Modules installed"
else
log " WARNING: No kernel modules found. Run build-kernel.sh first."
fi
#------------------------------------------------------------------------------
# Step 7: Cleanup and unmount
#------------------------------------------------------------------------------
log ""
log "Step 7: Cleanup..."
# Remove QEMU binary
rm -f "$ROOTFS_DIR/usr/bin/qemu-aarch64-static"
rm -f "$ROOTFS_DIR/tmp/setup.sh"
# Unmount in reverse order
umount "$ROOTFS_DIR/dev/pts"
umount "$ROOTFS_DIR/dev"
umount "$ROOTFS_DIR/sys"
umount "$ROOTFS_DIR/proc"
#------------------------------------------------------------------------------
# Step 8: Create archive
#------------------------------------------------------------------------------
log ""
log "Step 8: Creating rootfs archive..."
cd "$ROOTFS_DIR"
tar -czf "$ROOTFS_ARCHIVE" .
log " Created: $ROOTFS_ARCHIVE"
log " Size: $(du -h "$ROOTFS_ARCHIVE" | cut -f1)"
#------------------------------------------------------------------------------
# Complete
#------------------------------------------------------------------------------
log ""
log "=== Root Filesystem Build Complete ==="

61
config/retroarch.cfg Normal file
View File

@@ -0,0 +1,61 @@
# Arch R - RetroArch Configuration for R36S
# Optimized for 640x480 display
# Video Settings
video_driver = "gl"
video_fullscreen = "true"
video_windowed_fullscreen = "false"
video_vsync = "true"
video_smooth = "false"
video_scale_integer = "true"
video_rotation = "0"
video_aspect_ratio_auto = "true"
# R36S has 640x480 display (rotated to 480x640 in some configs)
video_fullscreen_x = "640"
video_fullscreen_y = "480"
# Audio Settings
audio_driver = "alsa"
audio_device = "default"
audio_latency = "64"
audio_sync = "true"
# Input Settings
input_autodetect_enable = "true"
input_joypad_driver = "udev"
input_max_users = "1"
# Menu Settings
menu_driver = "ozone"
menu_show_core_updater = "true"
menu_show_online_updater = "true"
quick_menu_show_save_core_overrides = "true"
quick_menu_show_save_game_overrides = "true"
# Directories
savefile_directory = "~/.config/retroarch/saves"
savestate_directory = "~/.config/retroarch/states"
libretro_directory = "/usr/lib/libretro"
libretro_info_path = "/usr/share/libretro/info"
assets_directory = "/usr/share/retroarch/assets"
system_directory = "~/roms/bios"
# Performance
video_threaded = "true"
video_frame_delay = "0"
# Power Saving (important for handheld)
suspend_screensaver_enable = "false"
pause_nonactive = "true"
# Hotkeys (adapt these for R36S button layout)
input_enable_hotkey = "nul"
input_menu_toggle_gamepad_combo = "4"
input_exit_emulator = "escape"
input_save_state = "f2"
input_load_state = "f4"
input_state_slot_increase = "f7"
input_state_slot_decrease = "f6"
input_toggle_fast_forward = "space"
input_fps_toggle = "f3"

View File

@@ -0,0 +1,38 @@
# Arch R - R36S udev Rules for USB OTG and Wi-Fi
#---------------------------------------------------------------------------
# AIC8800 Wi-Fi USB Modeswitch
# The adapter appears first as a CD-ROM/storage device (a69c:5721)
# and needs to be ejected to switch to Wi-Fi mode (a69c:8801)
#---------------------------------------------------------------------------
# Primary CD-ROM mode - trigger eject to switch to Wi-Fi
SUBSYSTEM=="block", ATTRS{idVendor}=="a69c", ATTRS{idProduct}=="5721", RUN+="/usr/bin/eject %k"
SUBSYSTEM=="usb", ATTR{idVendor}=="a69c", ATTR{idProduct}=="5721", RUN+="/usr/bin/eject /dev/%k"
# Alternative VIDs that might appear
SUBSYSTEM=="block", ATTRS{idVendor}=="2604", ATTRS{idProduct}=="0012", RUN+="/usr/bin/eject %k"
SUBSYSTEM=="block", ATTRS{idVendor}=="2604", ATTRS{idProduct}=="0013", RUN+="/usr/bin/eject %k"
#---------------------------------------------------------------------------
# AIC8800 Wi-Fi Mode (after modeswitch)
# These are the IDs when the device is in Wi-Fi mode
#---------------------------------------------------------------------------
# Set permissions for Wi-Fi device
SUBSYSTEM=="usb", ATTR{idVendor}=="a69c", ATTR{idProduct}=="8801", MODE="0666"
SUBSYSTEM=="usb", ATTR{idVendor}=="2604", ATTR{idProduct}=="0013", MODE="0666"
#---------------------------------------------------------------------------
# R36S Controller/Joystick
#---------------------------------------------------------------------------
# ADC-based analog sticks
SUBSYSTEM=="input", ATTRS{name}=="adc-joystick", MODE="0666", ENV{ID_INPUT_JOYSTICK}="1"
# GPIO buttons (D-pad, face buttons)
SUBSYSTEM=="input", ATTRS{name}=="gpio-keys", MODE="0666", ENV{ID_INPUT_JOYSTICK}="1"
# R36S specific controller names
SUBSYSTEM=="input", ATTRS{name}=="*OdroidGoa*", MODE="0666", ENV{ID_INPUT_JOYSTICK}="1"
SUBSYSTEM=="input", ATTRS{name}=="*R36S*", MODE="0666", ENV{ID_INPUT_JOYSTICK}="1"

Binary file not shown.

101
scripts/first-boot.sh Normal file
View File

@@ -0,0 +1,101 @@
#!/bin/bash
#==============================================================================
# Arch R - First Boot Setup Script
#==============================================================================
# Runs on first boot to configure the system
#==============================================================================
FIRST_BOOT_FLAG="/var/lib/archr/.first-boot-done"
# Check if already ran
if [ -f "$FIRST_BOOT_FLAG" ]; then
exit 0
fi
echo "=== Arch R First Boot Setup ==="
#------------------------------------------------------------------------------
# Resize partition to fill SD card
#------------------------------------------------------------------------------
echo "Resizing root partition..."
ROOT_DEV="/dev/mmcblk0p2"
ROOT_DISK="/dev/mmcblk0"
# Get current end and max available
PART_INFO=$(parted -m "$ROOT_DISK" unit s print 2>/dev/null | grep "^2:")
CURRENT_END=$(echo "$PART_INFO" | cut -d: -f3 | tr -d 's')
DISK_SIZE=$(parted -m "$ROOT_DISK" unit s print 2>/dev/null | grep "^$ROOT_DISK" | cut -d: -f2 | tr -d 's')
MAX_END=$((DISK_SIZE - 34)) # Leave space for GPT backup
if [ "$CURRENT_END" -lt "$MAX_END" ]; then
echo " Expanding partition..."
parted -s "$ROOT_DISK" resizepart 2 100%
resize2fs "$ROOT_DEV"
echo " Partition expanded!"
else
echo " Partition already at maximum size"
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
systemctl enable bluetooth 2>/dev/null || true
#------------------------------------------------------------------------------
# Configure RetroArch
#------------------------------------------------------------------------------
echo "Configuring RetroArch..."
RA_CONFIG="/home/archr/.config/retroarch/retroarch.cfg"
mkdir -p "$(dirname "$RA_CONFIG")"
if [ ! -f "$RA_CONFIG" ]; then
cp /etc/archr/retroarch.cfg "$RA_CONFIG" 2>/dev/null || true
fi
chown -R archr:archr /home/archr/.config 2>/dev/null || true
#------------------------------------------------------------------------------
# Create ROM directories
#------------------------------------------------------------------------------
echo "Creating ROM directories..."
ROM_BASE="/home/archr/roms"
SYSTEMS=(
"gb" "gbc" "gba" "nes" "snes" "megadrive" "psx"
"n64" "psp" "dreamcast" "arcade" "mame"
)
for sys in "${SYSTEMS[@]}"; do
mkdir -p "$ROM_BASE/$sys"
done
chown -R archr:archr "$ROM_BASE"
#------------------------------------------------------------------------------
# Mark first boot complete
#------------------------------------------------------------------------------
mkdir -p "$(dirname "$FIRST_BOOT_FLAG")"
touch "$FIRST_BOOT_FLAG"
echo "=== First Boot Setup Complete ==="
echo ""
echo "System will continue booting..."

102
scripts/wifi-connect.sh Normal file
View File

@@ -0,0 +1,102 @@
#!/bin/bash
#==============================================================================
# Arch R - Wi-Fi Connection Script
#==============================================================================
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m' # No Color
echo -e "${GREEN}=== Arch R Wi-Fi Setup ===${NC}"
echo ""
#------------------------------------------------------------------------------
# Check for Wi-Fi interface
#------------------------------------------------------------------------------
echo "Checking for Wi-Fi interface..."
IFACE=""
for iface in wlan0 wlan1 wlp1s0; do
if [ -d "/sys/class/net/$iface" ]; then
IFACE="$iface"
break
fi
done
if [ -z "$IFACE" ]; then
echo -e "${RED}No Wi-Fi interface found!${NC}"
echo ""
echo "Troubleshooting:"
echo " 1. Make sure Wi-Fi adapter is connected"
echo " 2. Check if driver is loaded: lsmod | grep aic"
echo " 3. Check dmesg for errors: dmesg | grep -i wifi"
exit 1
fi
echo -e "${GREEN}Found interface: $IFACE${NC}"
echo ""
#------------------------------------------------------------------------------
# Check NetworkManager
#------------------------------------------------------------------------------
if command -v nmcli &> /dev/null; then
# Use NetworkManager
echo "Scanning for networks..."
echo ""
nmcli device wifi rescan 2>/dev/null
sleep 2
echo "Available networks:"
nmcli device wifi list
echo ""
read -p "Enter network name (SSID): " SSID
read -sp "Enter password: " PASSWORD
echo ""
echo "Connecting to $SSID..."
nmcli device wifi connect "$SSID" password "$PASSWORD"
if [ $? -eq 0 ]; then
echo -e "${GREEN}Connected successfully!${NC}"
echo ""
echo "IP Address:"
ip -4 addr show "$IFACE" | grep inet
else
echo -e "${RED}Connection failed!${NC}"
exit 1
fi
else
# Fallback to wpa_supplicant
echo "NetworkManager not available, using wpa_supplicant..."
read -p "Enter network name (SSID): " SSID
read -sp "Enter password: " PASSWORD
echo ""
# Create wpa_supplicant config
WPA_CONF="/tmp/wpa_temp.conf"
wpa_passphrase "$SSID" "$PASSWORD" > "$WPA_CONF"
# Stop any existing wpa_supplicant
killall wpa_supplicant 2>/dev/null
# Start wpa_supplicant
wpa_supplicant -B -i "$IFACE" -c "$WPA_CONF"
sleep 2
# Get IP via DHCP
dhcpcd "$IFACE"
echo -e "${GREEN}Connection attempted!${NC}"
echo ""
echo "IP Address:"
ip -4 addr show "$IFACE" | grep inet
fi

208
setup-toolchain.sh Normal file
View File

@@ -0,0 +1,208 @@
#!/bin/bash
#==============================================================================
# Arch R - Toolchain Setup Script
#==============================================================================
# Sets up the cross-compilation environment for building Arch R
#==============================================================================
set -e
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
LOG_FILE="$SCRIPT_DIR/setup-toolchain.log"
log() {
echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" | tee -a "$LOG_FILE"
}
log "=== Arch R Toolchain Setup ==="
log "Script directory: $SCRIPT_DIR"
# Check if running as root
if [ "$EUID" -eq 0 ]; then
log "Warning: Running as root. Some operations may require sudo anyway."
fi
#------------------------------------------------------------------------------
# Step 1: Install required packages
#------------------------------------------------------------------------------
log ""
log "Step 1: Installing required packages..."
PACKAGES=(
# Cross-compilation toolchain
gcc-aarch64-linux-gnu
g++-aarch64-linux-gnu
binutils-aarch64-linux-gnu
# Build tools
make
cmake
ninja-build
bc
bison
flex
# Device tree compiler
device-tree-compiler
# U-Boot tools
u-boot-tools
# For rootfs manipulation
binfmt-support
qemu-user-static
debootstrap
# Archive tools
bsdtar
xz-utils
zstd
# Misc
git
wget
curl
python3
python3-pip
libssl-dev
libncurses5-dev
# For image creation
parted
dosfstools
e2fsprogs
mtools
)
log "Updating package list..."
sudo apt update 2>&1 | tee -a "$LOG_FILE"
log "Installing packages..."
sudo apt install -y "${PACKAGES[@]}" 2>&1 | tee -a "$LOG_FILE"
#------------------------------------------------------------------------------
# Step 2: Create directory structure
#------------------------------------------------------------------------------
log ""
log "Step 2: Creating directory structure..."
DIRS=(
"$SCRIPT_DIR/bootloader/configs"
"$SCRIPT_DIR/bootloader/src"
"$SCRIPT_DIR/kernel/configs"
"$SCRIPT_DIR/kernel/dts"
"$SCRIPT_DIR/kernel/patches"
"$SCRIPT_DIR/kernel/src"
"$SCRIPT_DIR/rootfs/overlay/etc"
"$SCRIPT_DIR/rootfs/overlay/usr/local/bin"
"$SCRIPT_DIR/rootfs/staging"
"$SCRIPT_DIR/config/emulationstation"
"$SCRIPT_DIR/config/retroarch"
"$SCRIPT_DIR/config/udev"
"$SCRIPT_DIR/scripts"
"$SCRIPT_DIR/output"
)
for dir in "${DIRS[@]}"; do
mkdir -p "$dir"
log " Created: $dir"
done
#------------------------------------------------------------------------------
# Step 3: Verify toolchain
#------------------------------------------------------------------------------
log ""
log "Step 3: Verifying toolchain..."
if command -v aarch64-linux-gnu-gcc &> /dev/null; then
GCC_VERSION=$(aarch64-linux-gnu-gcc --version | head -1)
log " GCC: $GCC_VERSION"
else
log "ERROR: aarch64-linux-gnu-gcc not found!"
exit 1
fi
if command -v dtc &> /dev/null; then
DTC_VERSION=$(dtc --version | head -1)
log " DTC: $DTC_VERSION"
else
log "ERROR: dtc not found!"
exit 1
fi
if command -v mkimage &> /dev/null; then
log " mkimage: Available"
else
log "WARNING: mkimage not found. U-Boot builds may fail."
fi
#------------------------------------------------------------------------------
# Step 4: Setup QEMU for ARM64 emulation
#------------------------------------------------------------------------------
log ""
log "Step 4: Setting up QEMU for ARM64..."
if command -v qemu-aarch64-static &> /dev/null; then
log " QEMU AArch64 static: Available"
# Register binfmt if not already done
if [ -f /proc/sys/fs/binfmt_misc/qemu-aarch64 ]; then
log " binfmt: Already registered"
else
log " Registering binfmt..."
sudo systemctl restart binfmt-support 2>/dev/null || true
fi
else
log "WARNING: qemu-aarch64-static not found. Chroot operations will fail."
fi
#------------------------------------------------------------------------------
# Step 5: Create environment file
#------------------------------------------------------------------------------
log ""
log "Step 5: Creating environment configuration..."
cat > "$SCRIPT_DIR/env.sh" << 'EOF'
#!/bin/bash
# Arch R Build Environment Configuration
export ARCH=arm64
export CROSS_COMPILE=aarch64-linux-gnu-
# Paths
export ARCHR_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
export ARCHR_BOOTLOADER="$ARCHR_ROOT/bootloader"
export ARCHR_KERNEL="$ARCHR_ROOT/kernel"
export ARCHR_ROOTFS="$ARCHR_ROOT/rootfs"
export ARCHR_CONFIG="$ARCHR_ROOT/config"
export ARCHR_OUTPUT="$ARCHR_ROOT/output"
# Build options
export MAKEFLAGS="-j$(nproc)"
# Device-specific
export ARCHR_DEVICE="r36s"
export ARCHR_SOC="rk3326"
echo "Arch R build environment loaded."
echo " ARCH: $ARCH"
echo " CROSS_COMPILE: $CROSS_COMPILE"
echo " Device: $ARCHR_DEVICE"
EOF
log " Created: $SCRIPT_DIR/env.sh"
#------------------------------------------------------------------------------
# Complete
#------------------------------------------------------------------------------
log ""
log "=== Setup Complete! ==="
log ""
log "To start building, source the environment:"
log " source env.sh"
log ""
log "Then run the build scripts:"
log " ./build-kernel.sh"
log " ./build-rootfs.sh"
log " ./build-image.sh"