Monorepo for Aesthetic.Computer aesthetic.computer
at main 218 lines 7.8 kB view raw
1#!/bin/sh 2# AC Native OS init — DRM direct boot with crash recovery 3 4export PATH="/bin:/sbin:/usr/bin:/usr/sbin" 5 6mount -t proc proc /proc 2>/dev/null 7mount -t sysfs sysfs /sys 2>/dev/null 8mount -t devtmpfs devtmpfs /dev 2>/dev/null 9mkdir -p /dev/pts /dev/shm /tmp /run /etc 10mount -t devpts devpts /dev/pts -o ptmxmode=0666 2>/dev/null 11mount -t tmpfs tmpfs /dev/shm 2>/dev/null 12mount -t tmpfs tmpfs /tmp 2>/dev/null 13mount -t tmpfs tmpfs /run 2>/dev/null 14mount -t efivarfs efivarfs /sys/firmware/efi/efivars 2>/dev/null 15 16# zram swap 17modprobe zram 2>/dev/null || true 18if [ -e /sys/block/zram0/disksize ] && [ -b /dev/zram0 ]; then 19 echo 1G > /sys/block/zram0/disksize && 20 mkswap /dev/zram0 >/dev/null 2>&1 && 21 swapon /dev/zram0 2>/dev/null 22fi 23 24# Loopback 25ip link set lo up 2>/dev/null 26 27# Restore baked Claude credentials (tmpfs mount hid the originals) 28if [ -f /claude-creds.json ]; then 29 mkdir -p /tmp/.claude 30 cp /claude-creds.json /tmp/.claude/.credentials.json 31 cp /claude-state.json /tmp/.claude.json 2>/dev/null 32 printf '{"permissions":{"allow":["Bash(*)","Read(*)","Write(*)","Edit(*)","Glob(*)","Grep(*)","WebFetch(*)","WebSearch(*)"]},"autoUpdates":false,"installMethod":"native"}\n' > /tmp/.claude/settings.json 33fi 34mkdir -p /tmp/ac 35[ -f /device-claude.md ] && cp /device-claude.md /tmp/ac/CLAUDE.md 2>/dev/null 36[ -f /device-score.md ] && cp /device-score.md /tmp/ac/SCORE.md 2>/dev/null 37 38# /etc/group and /etc/passwd needed by seatd 39echo "root:x:0:" > /etc/group 40echo "root:x:0:root" > /etc/passwd 41 42# Wait for GPU (up to 3 seconds) 43i=0 44while [ ! -e /dev/dri/card0 ] && [ ! -e /dev/dri/card1 ] && [ ! -e /dev/fb0 ] && [ $i -lt 300 ]; do 45 usleep 10000 2>/dev/null || sleep 1 46 i=$((i+1)) 47done 48 49# Performance governor (silently skip if cpufreq not available) 50if [ -d /sys/devices/system/cpu/cpu0/cpufreq ]; then 51 for g in /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor; do 52 echo performance > "$g" 2>/dev/null 53 done 54fi 55export SSL_CERT_FILE="/etc/pki/tls/certs/ca-bundle.crt" 56export CURL_CA_BUNDLE="/etc/pki/tls/certs/ca-bundle.crt" 57export SSL_CERT_DIR="/etc/ssl/certs" 58export HOME="/tmp" 59 60# ── Mount USB config/log partition (for config.json, wifi creds, logs) ── 61# Prefer the writable config partition over the boot partitions. 62modprobe vfat 2>/dev/null 63modprobe nls_cp437 2>/dev/null 64modprobe nls_ascii 2>/dev/null 65USB_MOUNTED=0 66USB_PARTS="/dev/sda1 /dev/sda2 /dev/sda3 /dev/sdb1 /dev/sdb2 /dev/sdb3 /dev/sdc1 /dev/sdc2 /dev/sdc3 /dev/sdd1 /dev/sdd2 /dev/sdd3 /dev/nvme0n1p1 /dev/nvme0n1p2 /dev/nvme0n1p3" 67 68mount_usb_partition() { 69 pass="$1" 70 for p in $USB_PARTS; do 71 if [ -b "$p" ]; then 72 mkdir -p /mnt 73 mount -t vfat "$p" /mnt 2>/dev/null || continue 74 if [ "$pass" = "config" ] && [ -f /mnt/config.json ]; then 75 USB_MOUNTED=1 76 return 0 77 fi 78 if [ "$pass" = "boot" ] && { [ -f /mnt/EFI/BOOT/BOOTX64.EFI ] || [ -f /mnt/EFI/BOOT/KERNEL.EFI ]; }; then 79 USB_MOUNTED=1 80 return 0 81 fi 82 umount /mnt 2>/dev/null 83 fi 84 done 85 return 1 86} 87 88for attempt in 1 2 3 4 5 6 7 8 9 10; do 89 mount_usb_partition config && break 90 mount_usb_partition boot && break 91 [ "$USB_MOUNTED" = "1" ] && break 92 sleep 1 93done 94 95# Create samples directory on boot media + mount point for music USB 96if [ "$USB_MOUNTED" = "1" ]; then 97 mkdir -p /mnt/samples 98fi 99mkdir -p /media 100 101if [ -x /scripts/usb-midi-gadget.sh ]; then 102 if [ "$USB_MOUNTED" = "1" ] && [ -f /mnt/config.json ] && 103 grep -Eq '"usbMidi"[[:space:]]*:[[:space:]]*true' /mnt/config.json 2>/dev/null; then 104 /scripts/usb-midi-gadget.sh up >/tmp/usb-midi-gadget.log 2>&1 || true 105 else 106 /scripts/usb-midi-gadget.sh down >/tmp/usb-midi-gadget.log 2>&1 || true 107 fi 108fi 109 110# Run ac-native in a loop — if it crashes, restart; if clean exit, shutdown 111export LD_LIBRARY_PATH="/lib64:/usr/lib64:${LD_LIBRARY_PATH:-}" 112 113# Write diagnostics to console AND USB 114echo "[init] USB_MOUNTED=$USB_MOUNTED" > /dev/tty0 2>/dev/null 115if [ "$USB_MOUNTED" = "1" ]; then 116 LOG=/mnt/pre-launch.log 117else 118 # No USB config partition — try writing logs to /tmp 119 LOG=/tmp/pre-launch.log 120fi 121echo "=== PRE-LAUNCH ===" > $LOG 122ls /dev/dri/ >> $LOG 2>&1 123echo "binary: $(ls -la /ac-native 2>&1)" >> $LOG 124echo "build: $(cat /etc/ac-build 2>&1)" >> $LOG 125echo "usb_mounted: $USB_MOUNTED" >> $LOG 126echo "gpu:" >> $LOG 127ls -la /dev/dri/ >> $LOG 2>&1 128ls -la /dev/fb* >> $LOG 2>&1 129echo "block devs:" >> $LOG 130ls /dev/sd* /dev/nvme* >> $LOG 2>&1 131echo "=== DMESG ===" >> $LOG 132dmesg >> $LOG 2>&1 133echo "=== CPUINFO ===" >> $LOG 134head -30 /proc/cpuinfo >> $LOG 2>&1 135echo "=== CMDLINE ===" >> $LOG 136cat /proc/cmdline >> $LOG 2>&1 137sync 138echo "[init] GPU: $(ls /dev/dri/ 2>/dev/null || echo NONE) USB=$USB_MOUNTED" > /dev/tty0 2>/dev/null 139 140# Start Swank server in background (if SBCL image exists) 141SWANK_PID=0 142if [ -x /ac-swank ]; then 143 LD_LIBRARY_PATH="/lib64:/usr/lib64" /ac-swank --swank-only >/dev/null 2>&1 & 144 SWANK_PID=$! 145fi 146 147# Main loop — ac-native runs as a child process (not PID 1). 148# First attempt: with SDL3/GPU env vars. 149# If it crashes (signal), retry without SDL (AC_NO_SDL=1). 150# If that also crashes, keep retrying without SDL with backoff. 151CRASH_COUNT=0 152SDL_ENABLED=1 153while true; do 154 if [ "$SDL_ENABLED" = "1" ]; then 155 echo "[init] launching ac-native (SDL3 GPU enabled)..." > /dev/tty0 2>/dev/null 156 LD_LIBRARY_PATH="/lib64" LIBGL_DRIVERS_PATH="/lib64/dri" GBM_DRIVERS_PATH="/lib64/dri" MESA_LOADER_DRIVER_OVERRIDE=iris \ 157 /ac-native /piece.mjs 2>/tmp/ac-native-stderr.log & 158 else 159 echo "[init] launching ac-native (DRM only)..." > /dev/tty0 2>/dev/null 160 LD_LIBRARY_PATH="/lib64" AC_NO_SDL=1 \ 161 /ac-native /piece.mjs 2>/tmp/ac-native-stderr.log & 162 fi 163 CHILD_PID=$! 164 wait $CHILD_PID 165 EXIT_CODE=$? 166 # Save crash info 167 echo "[init] ac-native (pid $CHILD_PID) exited: code=$EXIT_CODE crash=$CRASH_COUNT sdl=$SDL_ENABLED" > /dev/tty0 2>/dev/null 168 head -5 /tmp/ac-native-stderr.log > /dev/tty0 2>/dev/null 169 # Save crash info to USB if mounted 170 if [ "$USB_MOUNTED" = "1" ]; then 171 echo "exit=$EXIT_CODE crash=$CRASH_COUNT $(date 2>/dev/null)" >> /mnt/ac-crash.log 172 cp /tmp/ac-native-stderr.log /mnt/ac-native-stderr.log 2>/dev/null 173 sync 174 fi 175 176 if [ "$EXIT_CODE" = "0" ]; then 177 sync 178 # Suppress all kernel output before shutdown 179 echo 0 > /proc/sys/kernel/printk 2>/dev/null 180 printf '\033[?25l\033[2J' > /dev/tty0 2>/dev/null 181 poweroff -f 2>/dev/null 182 echo o > /proc/sysrq-trigger 2>/dev/null 183 sleep 30 184 break 185 fi 186 if [ "$EXIT_CODE" = "2" ]; then 187 sync 188 echo 0 > /proc/sys/kernel/printk 2>/dev/null 189 printf '\033[?25l\033[2J' > /dev/tty0 2>/dev/null 190 reboot -f 2>/dev/null 191 echo b > /proc/sysrq-trigger 2>/dev/null 192 sleep 30 193 break 194 fi 195 196 CRASH_COUNT=$((CRASH_COUNT + 1)) 197 198 # If crashed with SDL enabled, disable it and retry immediately 199 if [ "$SDL_ENABLED" = "1" ] && [ "$EXIT_CODE" -gt 128 ]; then 200 # Exit > 128 = killed by signal (128 + signal number) 201 SIG=$((EXIT_CODE - 128)) 202 echo "[init] Signal $SIG with SDL — disabling GPU, retrying with DRM..." > /dev/tty0 2>/dev/null 203 SDL_ENABLED=0 204 if [ "$USB_MOUNTED" = "1" ]; then 205 echo "sdl_crash: signal=$SIG, disabling SDL" >> /mnt/ac-crash.log 206 sync 207 fi 208 sleep 1 209 continue 210 fi 211 212 # Flash screen red via framebuffer 213 if [ -c /dev/fb0 ]; then 214 dd if=/dev/zero bs=4096 count=512 2>/dev/null | tr '\0' '\377' > /dev/fb0 2>/dev/null 215 fi 216 217 sleep 2 218done