Initial commit: DarkForge Linux — Phases 0-12
Complete from-scratch Linux distribution targeting AMD Ryzen 9 9950X3D + NVIDIA RTX 5090 on ASUS ROG CROSSHAIR X870E HERO. Deliverables: - dpack: custom package manager in Rust (3,800 lines) - TOML package parser, dependency resolver, build sandbox - CRUX Pkgfile and Gentoo ebuild converters - Shared library conflict detection - 124 package definitions across 4 repos (core/extra/desktop/gaming) - 34 toolchain bootstrap scripts (LFS 13.0 adapted for Zen 5) - Linux 6.19.8 kernel config (hardware-specific, fully commented) - SysVinit init system with rc.d service scripts - Live ISO builder (UEFI-only, squashfs+xorriso) - Interactive installer (GPT partitioning, EFISTUB boot) - Integration test checklist (docs/TESTING.md) No systemd. No bootloader. No display manager. Kernel boots via EFISTUB → auto-login → dwl Wayland compositor. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
20
configs/fstab.template
Normal file
20
configs/fstab.template
Normal file
@@ -0,0 +1,20 @@
|
||||
# ============================================================================
|
||||
# DarkForge Linux — /etc/fstab
|
||||
# ============================================================================
|
||||
# Filesystem table. Populated by the installer with actual UUIDs.
|
||||
# Partition scheme: GPT with ESP + root (ext4) + swap (96GB)
|
||||
# ============================================================================
|
||||
|
||||
# <device> <mount> <type> <options> <dump> <pass>
|
||||
|
||||
# Root filesystem — ext4 on NVMe
|
||||
UUID=__ROOT_UUID__ / ext4 defaults,noatime 0 1
|
||||
|
||||
# EFI System Partition — kernel lives here
|
||||
UUID=__ESP_UUID__ /boot/efi vfat defaults,noatime 0 2
|
||||
|
||||
# Swap partition — 96GB for hibernation support
|
||||
UUID=__SWAP_UUID__ none swap defaults 0 0
|
||||
|
||||
# Pseudo-filesystems (mounted by rc.sysinit, listed here for completeness)
|
||||
tmpfs /tmp tmpfs defaults,nosuid,nodev 0 0
|
||||
34
configs/inittab
Normal file
34
configs/inittab
Normal file
@@ -0,0 +1,34 @@
|
||||
# ============================================================================
|
||||
# DarkForge Linux — /etc/inittab
|
||||
# ============================================================================
|
||||
# SysVinit configuration. Defines runlevels and getty spawning.
|
||||
# Runlevel 3 = multi-user with networking (our default).
|
||||
# No display manager — tty1 auto-logs in 'danny' and starts dwl.
|
||||
# ============================================================================
|
||||
|
||||
# Default runlevel
|
||||
id:3:initdefault:
|
||||
|
||||
# System initialization script (runs once at boot)
|
||||
si::sysinit:/etc/rc.d/rc.sysinit
|
||||
|
||||
# Runlevel scripts
|
||||
l0:0:wait:/etc/rc.d/rc.shutdown
|
||||
l3:3:wait:/etc/rc.d/rc.multi
|
||||
l6:6:wait:/etc/rc.d/rc.reboot
|
||||
|
||||
# --- Virtual consoles -------------------------------------------------------
|
||||
# tty1: Auto-login danny — no password prompt, launches dwl via .zprofile
|
||||
1:2345:respawn:/sbin/agetty --autologin danny --noclear 38400 tty1 linux
|
||||
|
||||
# tty2-4: Standard login prompts (for emergency access)
|
||||
2:2345:respawn:/sbin/agetty 38400 tty2 linux
|
||||
3:2345:respawn:/sbin/agetty 38400 tty3 linux
|
||||
4:2345:respawn:/sbin/agetty 38400 tty4 linux
|
||||
|
||||
# --- Special keys -----------------------------------------------------------
|
||||
# Ctrl+Alt+Del triggers a clean reboot
|
||||
ca::ctrlaltdel:/sbin/shutdown -r now
|
||||
|
||||
# Power key triggers a clean shutdown (if ACPI sends it)
|
||||
pf::powerfail:/sbin/shutdown -h +0 "Power failure — shutting down"
|
||||
69
configs/rc.conf
Normal file
69
configs/rc.conf
Normal file
@@ -0,0 +1,69 @@
|
||||
#!/bin/bash
|
||||
# ============================================================================
|
||||
# DarkForge Linux — System Configuration
|
||||
# ============================================================================
|
||||
# /etc/rc.conf — sourced by all rc.d scripts and the init system.
|
||||
# This is the single place to configure hostname, locale, timezone,
|
||||
# network, daemons, and kernel modules.
|
||||
# ============================================================================
|
||||
|
||||
# --- System identity --------------------------------------------------------
|
||||
HOSTNAME="darkforge"
|
||||
|
||||
# --- Locale and language ----------------------------------------------------
|
||||
LOCALE="en_US.UTF-8"
|
||||
KEYMAP="us"
|
||||
TIMEZONE="America/New_York"
|
||||
# These are set during installation and can be changed here post-install.
|
||||
|
||||
# --- Console font -----------------------------------------------------------
|
||||
FONT="ter-v18n"
|
||||
# Terminus font at 18px — crisp on high-DPI displays. Requires kbd package.
|
||||
# Set to "" to use the kernel default.
|
||||
|
||||
# --- Daemons to start at boot ----------------------------------------------
|
||||
# Order matters. Each name corresponds to a script in /etc/rc.d/
|
||||
# Scripts are started in listed order at boot, stopped in reverse at shutdown.
|
||||
DAEMONS=(
|
||||
eudev # Device manager — must be first for hardware detection
|
||||
syslog # System logging
|
||||
dbus # D-Bus message bus — needed by polkit, PipeWire
|
||||
dhcpcd # DHCP client for ethernet
|
||||
pipewire # Audio server (replaces PulseAudio)
|
||||
)
|
||||
|
||||
# --- Kernel modules to load at boot ----------------------------------------
|
||||
# Modules not auto-loaded by eudev that we need explicitly.
|
||||
MODULES=(
|
||||
nvidia
|
||||
nvidia-modeset
|
||||
nvidia-drm
|
||||
nvidia-uvm
|
||||
)
|
||||
|
||||
# --- Module parameters ------------------------------------------------------
|
||||
# Pass parameters to kernel modules when loading.
|
||||
# Format: "module_name parameter=value"
|
||||
MODULE_PARAMS=(
|
||||
"nvidia-drm modeset=1"
|
||||
# nvidia-drm modeset=1 — required for Wayland DRM/KMS support
|
||||
)
|
||||
|
||||
# --- Network ----------------------------------------------------------------
|
||||
NETWORK_INTERFACE="enp6s0"
|
||||
# The primary ethernet interface. Detected by eudev.
|
||||
# Verify with: ip link show
|
||||
# X870E Hero Realtek 2.5GbE is typically enp6s0 or similar.
|
||||
|
||||
NETWORK_DHCP=yes
|
||||
# Use DHCP for automatic IP configuration.
|
||||
# Set to "no" for static IP and configure NETWORK_IP/MASK/GATEWAY below.
|
||||
|
||||
#NETWORK_IP="192.168.1.100"
|
||||
#NETWORK_MASK="255.255.255.0"
|
||||
#NETWORK_GATEWAY="192.168.1.1"
|
||||
#NETWORK_DNS="1.1.1.1 8.8.8.8"
|
||||
|
||||
# --- Miscellaneous ----------------------------------------------------------
|
||||
HARDWARECLOCK="UTC"
|
||||
# The hardware clock is set to UTC. localtime is computed from TIMEZONE.
|
||||
35
configs/rc.d/dbus
Executable file
35
configs/rc.d/dbus
Executable file
@@ -0,0 +1,35 @@
|
||||
#!/bin/bash
|
||||
# ============================================================================
|
||||
# DarkForge Linux — D-Bus service
|
||||
# ============================================================================
|
||||
# D-Bus message bus — required by polkit, PipeWire, and many desktop apps.
|
||||
# ============================================================================
|
||||
|
||||
DAEMON="/usr/bin/dbus-daemon"
|
||||
PIDFILE="/run/dbus/pid"
|
||||
|
||||
case "$1" in
|
||||
start)
|
||||
echo " Starting dbus..."
|
||||
mkdir -p /run/dbus
|
||||
dbus-uuidgen --ensure
|
||||
${DAEMON} --system && echo " dbus started"
|
||||
;;
|
||||
stop)
|
||||
echo " Stopping dbus..."
|
||||
if [ -f ${PIDFILE} ]; then
|
||||
kill $(cat ${PIDFILE}) 2>/dev/null
|
||||
rm -f ${PIDFILE}
|
||||
fi
|
||||
echo " dbus stopped"
|
||||
;;
|
||||
restart)
|
||||
$0 stop
|
||||
sleep 1
|
||||
$0 start
|
||||
;;
|
||||
*)
|
||||
echo "Usage: $0 {start|stop|restart}"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
48
configs/rc.d/dhcpcd
Executable file
48
configs/rc.d/dhcpcd
Executable file
@@ -0,0 +1,48 @@
|
||||
#!/bin/bash
|
||||
# ============================================================================
|
||||
# DarkForge Linux — dhcpcd service
|
||||
# ============================================================================
|
||||
# DHCP client daemon for ethernet. Uses interface from rc.conf.
|
||||
# ============================================================================
|
||||
|
||||
. /etc/rc.conf
|
||||
|
||||
DAEMON="/usr/sbin/dhcpcd"
|
||||
PIDFILE="/run/dhcpcd-${NETWORK_INTERFACE}.pid"
|
||||
|
||||
case "$1" in
|
||||
start)
|
||||
echo " Starting dhcpcd on ${NETWORK_INTERFACE}..."
|
||||
if [ "${NETWORK_DHCP}" = "yes" ]; then
|
||||
${DAEMON} -q "${NETWORK_INTERFACE}" && echo " dhcpcd started"
|
||||
else
|
||||
# Static IP configuration
|
||||
ip addr add "${NETWORK_IP}/${NETWORK_MASK}" dev "${NETWORK_INTERFACE}"
|
||||
ip link set "${NETWORK_INTERFACE}" up
|
||||
ip route add default via "${NETWORK_GATEWAY}"
|
||||
if [ -n "${NETWORK_DNS}" ]; then
|
||||
echo "# Generated by rc.d/dhcpcd" > /etc/resolv.conf
|
||||
for dns in ${NETWORK_DNS}; do
|
||||
echo "nameserver ${dns}" >> /etc/resolv.conf
|
||||
done
|
||||
fi
|
||||
echo " Static IP configured: ${NETWORK_IP}"
|
||||
fi
|
||||
;;
|
||||
stop)
|
||||
echo " Stopping dhcpcd..."
|
||||
if [ -f "${PIDFILE}" ]; then
|
||||
${DAEMON} -x "${NETWORK_INTERFACE}" 2>/dev/null
|
||||
fi
|
||||
echo " dhcpcd stopped"
|
||||
;;
|
||||
restart)
|
||||
$0 stop
|
||||
sleep 2
|
||||
$0 start
|
||||
;;
|
||||
*)
|
||||
echo "Usage: $0 {start|stop|restart}"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
32
configs/rc.d/eudev
Executable file
32
configs/rc.d/eudev
Executable file
@@ -0,0 +1,32 @@
|
||||
#!/bin/bash
|
||||
# ============================================================================
|
||||
# DarkForge Linux — eudev service
|
||||
# ============================================================================
|
||||
# Device manager — must be the first daemon started.
|
||||
# Populates /dev with device nodes and triggers udev rules.
|
||||
# ============================================================================
|
||||
|
||||
case "$1" in
|
||||
start)
|
||||
echo " Starting eudev..."
|
||||
/sbin/udevd --daemon
|
||||
udevadm trigger --action=add --type=subsystems
|
||||
udevadm trigger --action=add --type=devices
|
||||
udevadm settle
|
||||
echo " eudev started"
|
||||
;;
|
||||
stop)
|
||||
echo " Stopping eudev..."
|
||||
udevadm control --exit 2>/dev/null
|
||||
echo " eudev stopped"
|
||||
;;
|
||||
restart)
|
||||
$0 stop
|
||||
sleep 1
|
||||
$0 start
|
||||
;;
|
||||
*)
|
||||
echo "Usage: $0 {start|stop|restart}"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
34
configs/rc.d/pipewire
Executable file
34
configs/rc.d/pipewire
Executable file
@@ -0,0 +1,34 @@
|
||||
#!/bin/bash
|
||||
# ============================================================================
|
||||
# DarkForge Linux — PipeWire service
|
||||
# ============================================================================
|
||||
# PipeWire audio server + WirePlumber session manager.
|
||||
# NOTE: PipeWire is designed to run as a user service, not system-wide.
|
||||
# This script starts it for the auto-login user (danny) on tty1.
|
||||
# For the system-level boot, we just ensure the prerequisites are ready.
|
||||
# The actual PipeWire startup is handled in the user's shell profile.
|
||||
# ============================================================================
|
||||
|
||||
case "$1" in
|
||||
start)
|
||||
echo " PipeWire: ready (will start with user session)"
|
||||
# Ensure runtime directory exists for the user
|
||||
mkdir -p /run/user/1000
|
||||
chown danny:danny /run/user/1000
|
||||
chmod 700 /run/user/1000
|
||||
;;
|
||||
stop)
|
||||
echo " Stopping PipeWire..."
|
||||
killall pipewire wireplumber pipewire-pulse 2>/dev/null
|
||||
echo " PipeWire stopped"
|
||||
;;
|
||||
restart)
|
||||
$0 stop
|
||||
sleep 1
|
||||
$0 start
|
||||
;;
|
||||
*)
|
||||
echo "Usage: $0 {start|stop|restart}"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
21
configs/rc.d/rc.multi
Executable file
21
configs/rc.d/rc.multi
Executable file
@@ -0,0 +1,21 @@
|
||||
#!/bin/bash
|
||||
# ============================================================================
|
||||
# DarkForge Linux — Multi-User Startup
|
||||
# ============================================================================
|
||||
# /etc/rc.d/rc.multi — starts all daemons listed in rc.conf DAEMONS array.
|
||||
# Called by init when entering runlevel 3.
|
||||
# ============================================================================
|
||||
|
||||
. /etc/rc.conf
|
||||
|
||||
echo ":: Starting daemons..."
|
||||
|
||||
for daemon in "${DAEMONS[@]}"; do
|
||||
if [ -x "/etc/rc.d/${daemon}" ]; then
|
||||
"/etc/rc.d/${daemon}" start
|
||||
else
|
||||
echo "!! Daemon script not found: /etc/rc.d/${daemon}"
|
||||
fi
|
||||
done
|
||||
|
||||
echo ":: All daemons started"
|
||||
9
configs/rc.d/rc.reboot
Executable file
9
configs/rc.d/rc.reboot
Executable file
@@ -0,0 +1,9 @@
|
||||
#!/bin/bash
|
||||
# ============================================================================
|
||||
# DarkForge Linux — System Reboot
|
||||
# ============================================================================
|
||||
# /etc/rc.d/rc.reboot — runs shutdown then reboots.
|
||||
# ============================================================================
|
||||
|
||||
/etc/rc.d/rc.shutdown
|
||||
reboot -f
|
||||
40
configs/rc.d/rc.shutdown
Executable file
40
configs/rc.d/rc.shutdown
Executable file
@@ -0,0 +1,40 @@
|
||||
#!/bin/bash
|
||||
# ============================================================================
|
||||
# DarkForge Linux — System Shutdown
|
||||
# ============================================================================
|
||||
# /etc/rc.d/rc.shutdown — stops daemons and cleans up before halt/reboot.
|
||||
# ============================================================================
|
||||
|
||||
. /etc/rc.conf
|
||||
|
||||
echo ":: Shutting down..."
|
||||
|
||||
# --- Stop daemons in reverse order ------------------------------------------
|
||||
REVERSED=()
|
||||
for daemon in "${DAEMONS[@]}"; do
|
||||
REVERSED=("${daemon}" "${REVERSED[@]}")
|
||||
done
|
||||
|
||||
for daemon in "${REVERSED[@]}"; do
|
||||
if [ -x "/etc/rc.d/${daemon}" ]; then
|
||||
"/etc/rc.d/${daemon}" stop
|
||||
fi
|
||||
done
|
||||
|
||||
# --- Save random seed -------------------------------------------------------
|
||||
dd if=/dev/urandom of=/var/lib/random-seed count=1 bs=512 2>/dev/null
|
||||
|
||||
# --- Write wtmp shutdown entry ----------------------------------------------
|
||||
halt -w
|
||||
|
||||
# --- Deactivate swap --------------------------------------------------------
|
||||
swapoff -a
|
||||
|
||||
# --- Unmount filesystems ----------------------------------------------------
|
||||
echo ":: Unmounting filesystems..."
|
||||
umount -a -r 2>/dev/null
|
||||
|
||||
# --- Remount root read-only -------------------------------------------------
|
||||
mount -o remount,ro /
|
||||
|
||||
echo ":: Shutdown complete"
|
||||
104
configs/rc.d/rc.sysinit
Executable file
104
configs/rc.d/rc.sysinit
Executable file
@@ -0,0 +1,104 @@
|
||||
#!/bin/bash
|
||||
# ============================================================================
|
||||
# DarkForge Linux — System Initialization
|
||||
# ============================================================================
|
||||
# /etc/rc.d/rc.sysinit — runs once at boot before daemons start.
|
||||
# Sets up: hostname, clock, filesystems, kernel modules, swap, sysctl.
|
||||
# ============================================================================
|
||||
|
||||
. /etc/rc.conf
|
||||
|
||||
echo "DarkForge Linux — booting..."
|
||||
|
||||
# --- Mount virtual filesystems (if not already by kernel) -------------------
|
||||
mountpoint -q /proc || mount -t proc proc /proc
|
||||
mountpoint -q /sys || mount -t sysfs sysfs /sys
|
||||
mountpoint -q /run || mount -t tmpfs tmpfs /run
|
||||
mountpoint -q /dev || mount -t devtmpfs devtmpfs /dev
|
||||
mkdir -p /dev/pts /dev/shm /run/lock
|
||||
mountpoint -q /dev/pts || mount -t devpts devpts /dev/pts
|
||||
mountpoint -q /dev/shm || mount -t tmpfs tmpfs /dev/shm
|
||||
|
||||
# --- Set hostname -----------------------------------------------------------
|
||||
echo "${HOSTNAME}" > /proc/sys/kernel/hostname
|
||||
echo ":: Hostname set to ${HOSTNAME}"
|
||||
|
||||
# --- Set hardware clock -----------------------------------------------------
|
||||
if [ "${HARDWARECLOCK}" = "UTC" ]; then
|
||||
hwclock --systohc --utc 2>/dev/null
|
||||
else
|
||||
hwclock --systohc --localtime 2>/dev/null
|
||||
fi
|
||||
|
||||
# --- Set timezone -----------------------------------------------------------
|
||||
if [ -f "/usr/share/zoneinfo/${TIMEZONE}" ]; then
|
||||
ln -sf "/usr/share/zoneinfo/${TIMEZONE}" /etc/localtime
|
||||
echo ":: Timezone set to ${TIMEZONE}"
|
||||
fi
|
||||
|
||||
# --- Set console keymap -----------------------------------------------------
|
||||
if [ -n "${KEYMAP}" ]; then
|
||||
loadkeys "${KEYMAP}" 2>/dev/null && echo ":: Keymap set to ${KEYMAP}"
|
||||
fi
|
||||
|
||||
# --- Set console font -------------------------------------------------------
|
||||
if [ -n "${FONT}" ]; then
|
||||
setfont "${FONT}" 2>/dev/null && echo ":: Console font set to ${FONT}"
|
||||
fi
|
||||
|
||||
# --- Filesystem check -------------------------------------------------------
|
||||
echo ":: Checking filesystems..."
|
||||
fsck -A -T -C -a
|
||||
if [ $? -gt 1 ]; then
|
||||
echo "!! Filesystem errors detected. Dropping to emergency shell."
|
||||
echo "!! Run 'fsck' manually, then 'exit' to continue boot."
|
||||
/bin/bash
|
||||
fi
|
||||
|
||||
# --- Mount all filesystems from fstab ---------------------------------------
|
||||
echo ":: Mounting filesystems..."
|
||||
mount -a
|
||||
mount -o remount,rw /
|
||||
|
||||
# --- Activate swap ----------------------------------------------------------
|
||||
echo ":: Activating swap..."
|
||||
swapon -a
|
||||
|
||||
# --- Load kernel modules from rc.conf --------------------------------------
|
||||
echo ":: Loading kernel modules..."
|
||||
for mod in "${MODULES[@]}"; do
|
||||
modprobe "${mod}" && echo " Loaded: ${mod}"
|
||||
done
|
||||
|
||||
# --- Apply module parameters ------------------------------------------------
|
||||
for param in "${MODULE_PARAMS[@]}"; do
|
||||
mod=$(echo "${param}" | awk '{print $1}')
|
||||
args=$(echo "${param}" | cut -d' ' -f2-)
|
||||
# Module params are passed at load time, but if already loaded,
|
||||
# try writing to sysfs
|
||||
if [ -d "/sys/module/${mod}/parameters" ]; then
|
||||
key=$(echo "${args}" | cut -d'=' -f1)
|
||||
val=$(echo "${args}" | cut -d'=' -f2)
|
||||
echo "${val}" > "/sys/module/${mod}/parameters/${key}" 2>/dev/null
|
||||
fi
|
||||
done
|
||||
|
||||
# --- Apply sysctl settings --------------------------------------------------
|
||||
if [ -f /etc/sysctl.conf ]; then
|
||||
sysctl -p /etc/sysctl.conf >/dev/null 2>&1
|
||||
echo ":: Applied sysctl settings"
|
||||
fi
|
||||
|
||||
# --- Set up /tmp ------------------------------------------------------------
|
||||
chmod 1777 /tmp
|
||||
|
||||
# --- Seed random number generator ------------------------------------------
|
||||
if [ -f /var/lib/random-seed ]; then
|
||||
cat /var/lib/random-seed > /dev/urandom
|
||||
fi
|
||||
dd if=/dev/urandom of=/var/lib/random-seed count=1 bs=512 2>/dev/null
|
||||
|
||||
# --- Clear old PID files and locks ------------------------------------------
|
||||
rm -f /run/*.pid /var/lock/* 2>/dev/null
|
||||
|
||||
echo ":: System initialization complete"
|
||||
32
configs/rc.d/syslog
Executable file
32
configs/rc.d/syslog
Executable file
@@ -0,0 +1,32 @@
|
||||
#!/bin/bash
|
||||
# ============================================================================
|
||||
# DarkForge Linux — syslog service
|
||||
# ============================================================================
|
||||
# System logging daemon. Uses sysklogd or syslog-ng.
|
||||
# ============================================================================
|
||||
|
||||
DAEMON="/usr/sbin/syslogd"
|
||||
PIDFILE="/run/syslogd.pid"
|
||||
|
||||
case "$1" in
|
||||
start)
|
||||
echo " Starting syslog..."
|
||||
${DAEMON} -m 0 && echo " syslog started"
|
||||
/usr/sbin/klogd && echo " klogd started"
|
||||
;;
|
||||
stop)
|
||||
echo " Stopping syslog..."
|
||||
killall syslogd klogd 2>/dev/null
|
||||
rm -f ${PIDFILE}
|
||||
echo " syslog stopped"
|
||||
;;
|
||||
restart)
|
||||
$0 stop
|
||||
sleep 1
|
||||
$0 start
|
||||
;;
|
||||
*)
|
||||
echo "Usage: $0 {start|stop|restart}"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
48
configs/zprofile
Normal file
48
configs/zprofile
Normal file
@@ -0,0 +1,48 @@
|
||||
# ============================================================================
|
||||
# DarkForge Linux — User Shell Profile (~/.zprofile)
|
||||
# ============================================================================
|
||||
# Sourced on login to zsh. Auto-starts PipeWire and dwl on tty1.
|
||||
# This file is installed to /home/danny/.zprofile during system installation.
|
||||
# ============================================================================
|
||||
|
||||
# --- Environment variables for Wayland + NVIDIA ----------------------------
|
||||
export XDG_SESSION_TYPE=wayland
|
||||
export XDG_RUNTIME_DIR="/run/user/$(id -u)"
|
||||
export XDG_CONFIG_HOME="${HOME}/.config"
|
||||
export XDG_CACHE_HOME="${HOME}/.cache"
|
||||
export XDG_DATA_HOME="${HOME}/.local/share"
|
||||
export XDG_STATE_HOME="${HOME}/.local/state"
|
||||
|
||||
# NVIDIA Wayland-specific environment
|
||||
export GBM_BACKEND=nvidia-drm
|
||||
export __GLX_VENDOR_LIBRARY_NAME=nvidia
|
||||
export WLR_NO_HARDWARE_CURSORS=1
|
||||
# WLR_NO_HARDWARE_CURSORS may be needed for wlroots + nvidia
|
||||
# Remove if hardware cursors work correctly
|
||||
|
||||
export MOZ_ENABLE_WAYLAND=1
|
||||
# Firefox: use Wayland backend
|
||||
|
||||
export QT_QPA_PLATFORM=wayland
|
||||
# Qt applications: use Wayland backend
|
||||
|
||||
export SDL_VIDEODRIVER=wayland
|
||||
# SDL2 games: prefer Wayland (falls back to X11 via XWayland)
|
||||
|
||||
# --- Ensure XDG runtime directory exists ------------------------------------
|
||||
if [ ! -d "${XDG_RUNTIME_DIR}" ]; then
|
||||
mkdir -p "${XDG_RUNTIME_DIR}"
|
||||
chmod 700 "${XDG_RUNTIME_DIR}"
|
||||
fi
|
||||
|
||||
# --- Auto-start Wayland compositor on tty1 ----------------------------------
|
||||
if [ -z "${WAYLAND_DISPLAY}" ] && [ "$(tty)" = "/dev/tty1" ]; then
|
||||
# Start PipeWire audio stack (runs as user, not system service)
|
||||
pipewire &
|
||||
pipewire-pulse &
|
||||
wireplumber &
|
||||
|
||||
# Start the dwl Wayland compositor
|
||||
# dwl will set WAYLAND_DISPLAY and become the session leader
|
||||
exec dwl -s "foot" 2>/dev/null
|
||||
fi
|
||||
Reference in New Issue
Block a user