diff --git a/x86_64/.gitignore b/x86_64/.gitignore new file mode 100644 index 0000000..bd03f34 --- /dev/null +++ b/x86_64/.gitignore @@ -0,0 +1,15 @@ +# x86_64 ISO build artifacts +out/ +work/ +logs/ + +# Build outputs +*.iso +*.iso.sig +*.sha256 + +# Documentation (not tracked) +*.md + +# User-specific +.claude/ diff --git a/x86_64/50-fenrir-bluez.conf b/x86_64/50-fenrir-bluez.conf new file mode 100644 index 0000000..c5ffd39 --- /dev/null +++ b/x86_64/50-fenrir-bluez.conf @@ -0,0 +1,24 @@ +# Fenrir console audio support +# Prevents bluetooth disconnection when switching TTY + +monitor.bluez.properties = { + # Disable logind integration to prevent bluetooth device suspension on TTY switch + bluez5.enable-sbc-xq = true + bluez5.enable-msbc = true + bluez5.enable-hw-volume = true +} + +monitor.bluez.rules = [ + { + matches = [ + { + device.name = "~bluez_card.*" + } + ] + actions = { + update-props = { + session.suspend-timeout-seconds = 0 + } + } + } +] diff --git a/x86_64/50-fenrir-console.conf b/x86_64/50-fenrir-console.conf new file mode 100644 index 0000000..e5f2a1d --- /dev/null +++ b/x86_64/50-fenrir-console.conf @@ -0,0 +1,24 @@ +# Fenrir console audio support +# Adds secondary socket for console applications like Fenrir + +pulse.properties = { + # the addresses this server listens on + server.address = [ + "unix:native" + "unix:/tmp/pulse.sock" # console access socket + ] +} + +# client/stream specific properties +pulse.rules = [ + { + # speech dispatcher asks for too small latency and then underruns. + matches = [ { application.name = "~speech-dispatcher*" } ] + actions = { + update-props = { + pulse.min.req = 1024/48000 # 21ms + pulse.min.quantum = 1024/48000 # 21ms + } + } + } +] diff --git a/x86_64/50-fenrir-no-suspend.conf b/x86_64/50-fenrir-no-suspend.conf new file mode 100644 index 0000000..4217470 --- /dev/null +++ b/x86_64/50-fenrir-no-suspend.conf @@ -0,0 +1,35 @@ +# Fenrir console audio support +# Prevents audio device suspension when switching to TTY console + +monitor.alsa.rules = [ + { + matches = [ + { + device.name = "~alsa_card.*" + } + ] + actions = { + update-props = { + api.alsa.use-acp = true + api.acp.auto-profile = false + api.acp.auto-port = false + session.suspend-timeout-seconds = 0 + } + } + } + { + matches = [ + { + node.name = "~alsa_input.*" + } + { + node.name = "~alsa_output.*" + } + ] + actions = { + update-props = { + session.suspend-timeout-seconds = 0 + } + } + } +] diff --git a/x86_64/airootfs/etc/audibleprompt.sh b/x86_64/airootfs/etc/audibleprompt.sh new file mode 100755 index 0000000..5faa9e6 --- /dev/null +++ b/x86_64/airootfs/etc/audibleprompt.sh @@ -0,0 +1,7 @@ +#!/usr/bin/env bash + +play -qnV0 synth 3 pluck D3 pluck A3 pluck D4 pluck F4 pluck A4 delay 0 .1 .2 .3 .4 remix - chorus 0.9 0.9 38 0.75 0.3 0.5 -t & +read -rsp "$*"$'\n' password +echo "$password" + +exit 0 diff --git a/x86_64/airootfs/etc/environment b/x86_64/airootfs/etc/environment new file mode 100644 index 0000000..f387890 --- /dev/null +++ b/x86_64/airootfs/etc/environment @@ -0,0 +1,12 @@ +# +# This file is parsed by pam_env module +# +# Syntax: simple "KEY=VAL" pairs on separate lines +# +# Accessibility variables +export ACCESSIBILITY_ENABLED=1 +export GTK_MODULES=gail:atk-bridge +export GNOME_ACCESSIBILITY=1 +export QT_ACCESSIBILITY=1 +export QT_LINUX_ACCESSIBILITY_ALWAYS_ON=1 +export SAL_USE_VCLPLUGIN=gtk3 diff --git a/x86_64/airootfs/etc/fstab b/x86_64/airootfs/etc/fstab new file mode 100644 index 0000000..49fc164 --- /dev/null +++ b/x86_64/airootfs/etc/fstab @@ -0,0 +1,6 @@ +# Static information about the filesystems. +# See fstab(5) for details. + +# +# Live ISO - root filesystem is handled by archiso, only tmpfs mounts needed +tmpfs /var/log tmpfs defaults,noatime,nosuid,nodev,noexec,mode=0755,size=128M 0 0 diff --git a/x86_64/airootfs/etc/hostname b/x86_64/airootfs/etc/hostname new file mode 100644 index 0000000..5c8e341 --- /dev/null +++ b/x86_64/airootfs/etc/hostname @@ -0,0 +1 @@ +stormux diff --git a/x86_64/airootfs/etc/hosts b/x86_64/airootfs/etc/hosts new file mode 100644 index 0000000..d6f492f --- /dev/null +++ b/x86_64/airootfs/etc/hosts @@ -0,0 +1,5 @@ +# Static table lookup for hostnames. +# See hosts(5) for details. +127.0.0.1 localhost +::1 localhost +127.0.1.1 stormux.localdomain stormux diff --git a/x86_64/airootfs/etc/mkinitcpio.conf.d/archiso.conf b/x86_64/airootfs/etc/mkinitcpio.conf.d/archiso.conf new file mode 100644 index 0000000..5c008e5 --- /dev/null +++ b/x86_64/airootfs/etc/mkinitcpio.conf.d/archiso.conf @@ -0,0 +1,3 @@ +HOOKS=(base udev microcode modconf kms memdisk archiso archiso_loop_mnt archiso_pxe_common archiso_pxe_nbd archiso_pxe_http archiso_pxe_nfs block filesystems keyboard) +COMPRESSION="xz" +COMPRESSION_OPTIONS=(-9e) diff --git a/x86_64/airootfs/etc/mkinitcpio.d/linux.preset b/x86_64/airootfs/etc/mkinitcpio.d/linux.preset new file mode 100644 index 0000000..8e85205 --- /dev/null +++ b/x86_64/airootfs/etc/mkinitcpio.d/linux.preset @@ -0,0 +1,8 @@ +# mkinitcpio preset file for the 'linux' package on archiso + +PRESETS=('archiso') + +ALL_kver='/boot/vmlinuz-linux' +archiso_config='/etc/mkinitcpio.conf.d/archiso.conf' + +archiso_image="/boot/initramfs-linux.img" diff --git a/x86_64/airootfs/etc/motd b/x86_64/airootfs/etc/motd new file mode 100644 index 0000000..7e5f0c2 --- /dev/null +++ b/x86_64/airootfs/etc/motd @@ -0,0 +1,10 @@ +Welcome to Stormux, powered by Arch Linux ARM + + Stormux Website: https://stormux.org + Arch Linux ARM Forum: https://archlinuxarm.org/forum + + Stormux IRC: #stormux on irc.stormux.org + Arch Linux ARM IRC: #archlinuxarm on irc.libera.chat + + Thank you Stormux supporters! https://ko-fi.com/stormux/leaderboard + diff --git a/x86_64/airootfs/etc/pacman.conf b/x86_64/airootfs/etc/pacman.conf new file mode 100644 index 0000000..00fe68e --- /dev/null +++ b/x86_64/airootfs/etc/pacman.conf @@ -0,0 +1,104 @@ +# +# /etc/pacman.conf +# +# See the pacman.conf(5) manpage for option and repository directives + +# +# GENERAL OPTIONS +# +[options] +# The following paths are commented out with their default values listed. +# If you wish to use different paths, uncomment and update the paths. +#RootDir = / +#DBPath = /var/lib/pacman/ +#CacheDir = /var/cache/pacman/pkg/ +#LogFile = /var/log/pacman.log +#GPGDir = /etc/pacman.d/gnupg/ +#HookDir = /etc/pacman.d/hooks/ +HoldPkg = pacman glibc +#XferCommand = /usr/bin/curl -L -C - -f -o %o %u +#XferCommand = /usr/bin/wget --passive-ftp -c -O %o %u +#CleanMethod = KeepInstalled +Architecture = auto + +# Pacman won't upgrade packages listed in IgnorePkg and members of IgnoreGroup +#IgnorePkg = +#IgnoreGroup = + +#NoUpgrade = +#NoExtract = + +# Misc options +#UseSyslog +#Color +#NoProgressBar +# We cannot check disk space from within a chroot environment +#CheckSpace +#VerbosePkgLists +ParallelDownloads = 5 +#DownloadUser = alpm +#DisableSandbox + +# By default, pacman accepts packages signed by keys that its local keyring +# trusts (see pacman-key and its man page), as well as unsigned packages. +SigLevel = Required DatabaseOptional +LocalFileSigLevel = Optional +#RemoteFileSigLevel = Required + +# NOTE: You must run `pacman-key --init` before first using pacman; the local +# keyring can then be populated with the keys of all official Arch Linux +# packagers with `pacman-key --populate archlinux`. + +# +# REPOSITORIES +# - can be defined here or included from another file +# - pacman will search repositories in the order defined here +# - local/custom mirrors can be added here or in separate files +# - repositories listed first will take precedence when packages +# have identical names, regardless of version number +# - URLs will have $repo replaced by the name of the current repo +# - URLs will have $arch replaced by the name of the architecture +# +# Repository entries are of the format: +# [repo-name] +# Server = ServerName +# Include = IncludePath +# +# The header [repo-name] is crucial - it must be present and +# uncommented to enable the repo. +# + +# The testing repositories are disabled by default. To enable, uncomment the +# repo name header and Include lines. You can add preferred servers immediately +# after the header, and they will be used before the default mirrors. + +#[core-testing] +#Include = /etc/pacman.d/mirrorlist + +[stormux] +SigLevel = Required DatabaseOptional +Server = https://packages.stormux.org/$arch + +[core] +Include = /etc/pacman.d/mirrorlist + +#[extra-testing] +#Include = /etc/pacman.d/mirrorlist + +[extra] +Include = /etc/pacman.d/mirrorlist + +# If you want to run 32 bit applications on your x86_64 system, +# enable the multilib repositories as required here. + +#[multilib-testing] +#Include = /etc/pacman.d/mirrorlist + +#[multilib] +#Include = /etc/pacman.d/mirrorlist + +# An example of a custom package repository. See the pacman manpage for +# tips on creating your own repositories. +#[custom] +#SigLevel = Optional TrustAll +#Server = file:///home/custompkgs diff --git a/x86_64/airootfs/etc/pacman.d/hooks/00-stormux-repo-key.hook b/x86_64/airootfs/etc/pacman.d/hooks/00-stormux-repo-key.hook new file mode 100644 index 0000000..c3f05e2 --- /dev/null +++ b/x86_64/airootfs/etc/pacman.d/hooks/00-stormux-repo-key.hook @@ -0,0 +1,10 @@ +[Trigger] +Operation = Install +Operation = Upgrade +Type = Package +Target = * + +[Action] +Description = Adding Stormux repository key... +When = PreTransaction +Exec = /bin/sh -c 'if [ ! -f /etc/pacman.d/.stormux-key-added ]; then pacman-key --add /usr/share/stormux/stormux_repo.pub && pacman-key --lsign-key 52ADA49000F1FF0456F8AEEFB4CDE1CD56EF8E82 && touch /etc/pacman.d/.stormux-key-added; fi' diff --git a/x86_64/airootfs/etc/pacman.d/hooks/stormux-setup.hook b/x86_64/airootfs/etc/pacman.d/hooks/stormux-setup.hook new file mode 100644 index 0000000..d90c9f3 --- /dev/null +++ b/x86_64/airootfs/etc/pacman.d/hooks/stormux-setup.hook @@ -0,0 +1,16 @@ +# remove from airootfs! +# Stormux system setup hook - creates user, configures services + +[Trigger] +Operation = Install +Operation = Upgrade +Type = Package +Target = filesystem + +[Action] +Description = Setting up Stormux user and system configuration... +When = PostTransaction +Depends = shadow +Depends = systemd +Depends = sudo +Exec = /usr/local/bin/stormux-setup.sh diff --git a/x86_64/airootfs/etc/profile.d/stormux_first_boot.sh b/x86_64/airootfs/etc/profile.d/stormux_first_boot.sh new file mode 100755 index 0000000..843df65 --- /dev/null +++ b/x86_64/airootfs/etc/profile.d/stormux_first_boot.sh @@ -0,0 +1,63 @@ +#!/usr/bin/env bash + +if [[ "$(tty)" != "/dev/tty1" ]]; then + return +fi + +if [[ -x /opt/configure-stormux/configure-stormux.sh ]]; then + return +fi + +if ! [[ -x /usr/local/bin/configure-stormux ]]; then + return +fi + +# Volume calibration FIRST +echo "Setting up audio volume..." +volume=50 +wait=0 + +# Wait for pipewire to become available +while [[ $wait -lt 30 ]]; do + if pgrep pipewire &> /dev/null ; then + break + else + sleep 1 + ((wait++)) + fi +done + +# Volume calibration - this should be the VERY FIRST interactive part +while [[ $volume -le 130 ]]; do + clear + pactl set-sink-volume @DEFAULT_SINK@ "${volume}%" 2>/dev/null + spd-say "If this is loud enough, press enter." + if read -t4 ; then + echo "Volume set to ${volume}%" + break + else + ((volume+=5)) + fi +done + +# For audible sudo prompts: +unset sudoFlags +if [[ -x /etc/audibleprompt.sh ]]; then + export SUDO_ASKPASS=/etc/audibleprompt.sh + export sudoFlags=("-A") +fi + +clear +cat << "EOF" +Hello, and welcome to Stormux! + +Let's get you set up. After you press enter, you will be prompted for the sudo password. +When that happens, type the word stormux and press enter. +You will not receive any speech feedback for this process. +That is completely normal, and speech will return after you have typed the password. +Once again, the password is stormux in all lower case letters. + +Please press enter to continue. +EOF +read -r +sudo "${sudoFlags[@]}" configure-stormux diff --git a/x86_64/airootfs/etc/skel.custom/.bash_aliases b/x86_64/airootfs/etc/skel.custom/.bash_aliases new file mode 100644 index 0000000..10ba8f8 --- /dev/null +++ b/x86_64/airootfs/etc/skel.custom/.bash_aliases @@ -0,0 +1,4 @@ +# Raspberry Pi Information +alias pi-temp='/usr/bin/vcgencmd measure_temp' +alias pi-version='cat /sys/firmware/devicetree/base/model;echo' +alias pi-ip='ip a | grep -v "127.0.0.1" | grep -E -o "([0-9]{1,3}\.){3}[0-9]{1,3}/[0-9]{1,2}"' diff --git a/x86_64/airootfs/etc/skel.custom/.bash_functions b/x86_64/airootfs/etc/skel.custom/.bash_functions new file mode 100644 index 0000000..c4d13a6 --- /dev/null +++ b/x86_64/airootfs/etc/skel.custom/.bash_functions @@ -0,0 +1,21 @@ +memuse() { + ps axo rss,comm,pid \ + | awk '{ proc_list[$2] += $1; } END \ + { for (proc in proc_list) { printf("%d\t%s\n", proc_list[proc],proc); }}' \ + | sort -n | tail -n 10 | sort -rn \ + | awk '{$1/=1024;printf "%.0fMB\t",$1}{print $2}' +} + + +pdf() +{ + if [[ $# -ne 1 ]]; then + echo 'Usage: pdf ' >&2 + else + local dir=$(mktemp -d -p /tmp pdf_conversion.XXXXXX) + local outFile="${1##*/}" + local outFile="${outFile%.*}" + pdftohtml -noframes -i -s "$1" "${dir}/${outFile}.html" + w3m -s "${dir}/${outFile}.html" + fi +} diff --git a/x86_64/airootfs/etc/skel.custom/.bashrc b/x86_64/airootfs/etc/skel.custom/.bashrc new file mode 100644 index 0000000..65f57bd --- /dev/null +++ b/x86_64/airootfs/etc/skel.custom/.bashrc @@ -0,0 +1,24 @@ +# +# ~/.bashrc +# + +# If not running interactively, don't do anything +[[ $- != *i* ]] && return + +#Change directories without using cd +shopt -s autocd + +# Keep bash history in screen +export HISTFILE="${HISTFILE}${WINDOW:+.${WINDOW}}" + +# load Aliases and functions +[[ -f ".bash_aliases" ]] && source .bash_aliases +[[ -f ".bash_functions" ]] && source .bash_functions +#Invironment variables +PS1='[\u@\h \W] \$ ' +export DIALOGOPTS='--no-lines --visit-items' +GPG_TTY=$(tty) +export GPG_TTY +# Don't put commands prefixed with space, or duplicate commands in history +export HISTCONTROL=ignoreboth + diff --git a/x86_64/airootfs/etc/skel.custom/.inputrc b/x86_64/airootfs/etc/skel.custom/.inputrc new file mode 100644 index 0000000..0dcf6ea --- /dev/null +++ b/x86_64/airootfs/etc/skel.custom/.inputrc @@ -0,0 +1,6 @@ +# Reload changes with control+x followed by control+r +set echo-control-characters off + +# History searching with up and down arrows. +"\e[A": history-search-backward +"\e[B": history-search-forward diff --git a/x86_64/airootfs/etc/skel.custom/.screenrc b/x86_64/airootfs/etc/skel.custom/.screenrc new file mode 100644 index 0000000..bd20ce3 --- /dev/null +++ b/x86_64/airootfs/etc/skel.custom/.screenrc @@ -0,0 +1,18 @@ +vbell off +bell_msg "" +hardstatus off +startup_message off +defscrollback 4096 +bind ! select 10 +bind @ select 11 +bind \# select 12 +bind $ select 13 +bind % select 14 +bind ^ select 15 +bind & select 16 +bind * select 17 +bind ( select 18 +bind ) select 19 +bind b eval "writebuf" 'exec !!! xclip -selection "clipboard" -i /tmp/screen-exchange' +#termcapinfo xterm|xterms|xs|rxvt ti@:te@ +termcapinfo xterm* ti@:te@ diff --git a/x86_64/airootfs/etc/sudoers.d/wheel b/x86_64/airootfs/etc/sudoers.d/wheel new file mode 100644 index 0000000..40695bb --- /dev/null +++ b/x86_64/airootfs/etc/sudoers.d/wheel @@ -0,0 +1 @@ +%wheel ALL=(ALL:ALL) ALL diff --git a/x86_64/airootfs/etc/sysctl.d/20-quiet-printk.conf b/x86_64/airootfs/etc/sysctl.d/20-quiet-printk.conf new file mode 100644 index 0000000..47146d2 --- /dev/null +++ b/x86_64/airootfs/etc/sysctl.d/20-quiet-printk.conf @@ -0,0 +1 @@ +kernel.printk = 3 3 3 3 diff --git a/x86_64/airootfs/etc/systemd/journald.conf.d/99-ramlog.conf b/x86_64/airootfs/etc/systemd/journald.conf.d/99-ramlog.conf new file mode 100644 index 0000000..d89ad6b --- /dev/null +++ b/x86_64/airootfs/etc/systemd/journald.conf.d/99-ramlog.conf @@ -0,0 +1,3 @@ +[Journal] +Storage=volatile +SystemMaxUse=20M diff --git a/x86_64/airootfs/etc/systemd/resolved.conf.d/dnssec.conf b/x86_64/airootfs/etc/systemd/resolved.conf.d/dnssec.conf new file mode 100644 index 0000000..d43d54a --- /dev/null +++ b/x86_64/airootfs/etc/systemd/resolved.conf.d/dnssec.conf @@ -0,0 +1,2 @@ +[Resolve] +DNSSEC=no diff --git a/x86_64/airootfs/etc/systemd/system/fenrirscreenreader.service.d/wait-for-audio.conf b/x86_64/airootfs/etc/systemd/system/fenrirscreenreader.service.d/wait-for-audio.conf new file mode 100644 index 0000000..9deed1c --- /dev/null +++ b/x86_64/airootfs/etc/systemd/system/fenrirscreenreader.service.d/wait-for-audio.conf @@ -0,0 +1,5 @@ +[Unit] +# Ensure audio and speech-dispatcher are available before starting Fenrir +# Wait for user audio initialization to complete +After=sound.target stormux-audio-setup.service speech-dispatcherd.service user@1000.service +Wants=stormux-audio-setup.service speech-dispatcherd.service user@1000.service diff --git a/x86_64/airootfs/etc/systemd/system/getty.target.wants/fenrirscreenreader.service b/x86_64/airootfs/etc/systemd/system/getty.target.wants/fenrirscreenreader.service new file mode 120000 index 0000000..6a2b2fe --- /dev/null +++ b/x86_64/airootfs/etc/systemd/system/getty.target.wants/fenrirscreenreader.service @@ -0,0 +1 @@ +/usr/lib/systemd/system/fenrirscreenreader.service \ No newline at end of file diff --git a/x86_64/airootfs/etc/systemd/system/getty@tty1.service.d/autologin.conf b/x86_64/airootfs/etc/systemd/system/getty@tty1.service.d/autologin.conf new file mode 100644 index 0000000..b9d22eb --- /dev/null +++ b/x86_64/airootfs/etc/systemd/system/getty@tty1.service.d/autologin.conf @@ -0,0 +1,3 @@ +[Service] +ExecStart= +ExecStart=-/sbin/agetty -o '-p -f -- \\u' --noclear --autologin root - $TERM diff --git a/x86_64/airootfs/etc/systemd/system/getty@tty2.service.d/autologin.conf b/x86_64/airootfs/etc/systemd/system/getty@tty2.service.d/autologin.conf new file mode 100644 index 0000000..00ba65a --- /dev/null +++ b/x86_64/airootfs/etc/systemd/system/getty@tty2.service.d/autologin.conf @@ -0,0 +1,3 @@ +[Service] +ExecStart= +ExecStart=-/sbin/agetty -o '-p -f -- \\u' --noclear --autologin stormux - $TERM diff --git a/x86_64/airootfs/etc/systemd/system/log-to-ram-setup.service b/x86_64/airootfs/etc/systemd/system/log-to-ram-setup.service new file mode 100644 index 0000000..d647d6f --- /dev/null +++ b/x86_64/airootfs/etc/systemd/system/log-to-ram-setup.service @@ -0,0 +1,16 @@ +[Unit] +Description=Setup RAM logging and restore logs from disk +DefaultDependencies=false +After=local-fs.target +Before=sysinit.target +RequiresMountsFor=/var + +[Service] +Type=oneshot +RemainAfterExit=yes +ExecStartPre=/bin/mkdir -p /var/log.hdd +ExecStartPre=/bin/sh -c 'if [ -d /var/log.hdd ] && [ "$(ls -A /var/log.hdd 2>/dev/null)" ]; then cp -au /var/log.hdd/* /var/log/ 2>/dev/null || true; fi' +ExecStart=/bin/true + +[Install] +WantedBy=sysinit.target \ No newline at end of file diff --git a/x86_64/airootfs/etc/systemd/system/log-to-ram-shutdown.service b/x86_64/airootfs/etc/systemd/system/log-to-ram-shutdown.service new file mode 100644 index 0000000..7625859 --- /dev/null +++ b/x86_64/airootfs/etc/systemd/system/log-to-ram-shutdown.service @@ -0,0 +1,14 @@ +[Unit] +Description=Sync logs to disk before shutdown +DefaultDependencies=false +Before=shutdown.target reboot.target halt.target +Conflicts=shutdown.target reboot.target halt.target + +[Service] +Type=oneshot +RemainAfterExit=true +ExecStart=/bin/sh -c 'rsync -aXv --delete --exclude="*.hdd" /var/log/ /var/log.hdd/ 2>/dev/null || true' +TimeoutStopSec=30 + +[Install] +WantedBy=shutdown.target reboot.target halt.target \ No newline at end of file diff --git a/x86_64/airootfs/etc/systemd/system/log-to-ram-sync.service b/x86_64/airootfs/etc/systemd/system/log-to-ram-sync.service new file mode 100644 index 0000000..0822563 --- /dev/null +++ b/x86_64/airootfs/etc/systemd/system/log-to-ram-sync.service @@ -0,0 +1,8 @@ +[Unit] +Description=Sync logs from RAM to disk +After=local-fs.target + +[Service] +Type=oneshot +ExecStartPre=/bin/mkdir -p /var/log.hdd +ExecStart=/bin/sh -c 'rsync -aXv --delete --exclude="*.hdd" /var/log/ /var/log.hdd/ 2>/dev/null || true' \ No newline at end of file diff --git a/x86_64/airootfs/etc/systemd/system/log-to-ram-sync.timer b/x86_64/airootfs/etc/systemd/system/log-to-ram-sync.timer new file mode 100644 index 0000000..56dad52 --- /dev/null +++ b/x86_64/airootfs/etc/systemd/system/log-to-ram-sync.timer @@ -0,0 +1,11 @@ +[Unit] +Description=Sync logs from RAM to disk every hour +Requires=log-to-ram-sync.service + +[Timer] +OnBootSec=15min +OnUnitActiveSec=1h +Persistent=true + +[Install] +WantedBy=timers.target \ No newline at end of file diff --git a/x86_64/airootfs/etc/systemd/system/multi-user.target.wants/NetworkManager.service b/x86_64/airootfs/etc/systemd/system/multi-user.target.wants/NetworkManager.service new file mode 120000 index 0000000..e874a9b --- /dev/null +++ b/x86_64/airootfs/etc/systemd/system/multi-user.target.wants/NetworkManager.service @@ -0,0 +1 @@ +/usr/lib/systemd/system/NetworkManager.service \ No newline at end of file diff --git a/x86_64/airootfs/etc/systemd/system/multi-user.target.wants/brltty.path b/x86_64/airootfs/etc/systemd/system/multi-user.target.wants/brltty.path new file mode 120000 index 0000000..e82d99f --- /dev/null +++ b/x86_64/airootfs/etc/systemd/system/multi-user.target.wants/brltty.path @@ -0,0 +1 @@ +/usr/lib/systemd/system/brltty.path \ No newline at end of file diff --git a/x86_64/airootfs/etc/systemd/system/multi-user.target.wants/stormux-repo-init.service b/x86_64/airootfs/etc/systemd/system/multi-user.target.wants/stormux-repo-init.service new file mode 120000 index 0000000..b57059f --- /dev/null +++ b/x86_64/airootfs/etc/systemd/system/multi-user.target.wants/stormux-repo-init.service @@ -0,0 +1 @@ +../stormux-repo-init.service \ No newline at end of file diff --git a/x86_64/airootfs/etc/systemd/system/pipewire-live-setup.service b/x86_64/airootfs/etc/systemd/system/pipewire-live-setup.service new file mode 100644 index 0000000..a422bc8 --- /dev/null +++ b/x86_64/airootfs/etc/systemd/system/pipewire-live-setup.service @@ -0,0 +1,13 @@ +[Unit] +Description=Setup Pipewire for Live Environment +After=sound.target +Before=fenrirscreenreader.service speech-dispatcherd.service +DefaultDependencies=no + +[Service] +Type=oneshot +RemainAfterExit=yes +ExecStart=/usr/local/bin/setup-pipewire-live.sh + +[Install] +WantedBy=multi-user.target diff --git a/x86_64/airootfs/etc/systemd/system/sound.target.wants/stormux-audio-setup.service b/x86_64/airootfs/etc/systemd/system/sound.target.wants/stormux-audio-setup.service new file mode 120000 index 0000000..1fb2f20 --- /dev/null +++ b/x86_64/airootfs/etc/systemd/system/sound.target.wants/stormux-audio-setup.service @@ -0,0 +1 @@ +../stormux-audio-setup.service \ No newline at end of file diff --git a/x86_64/airootfs/etc/systemd/system/stormux-audio-setup.service b/x86_64/airootfs/etc/systemd/system/stormux-audio-setup.service new file mode 100644 index 0000000..2c2fa9e --- /dev/null +++ b/x86_64/airootfs/etc/systemd/system/stormux-audio-setup.service @@ -0,0 +1,17 @@ +[Unit] +Description=Setup audio for Stormux live environment +# Wait for audio hardware to be ready +Wants=systemd-udev-settle.service +After=systemd-udev-settle.service sound.target + +[Service] +Type=oneshot +RemainAfterExit=yes +# Enable linger so pipewire can run without login +ExecStartPre=/bin/mkdir -p /var/lib/systemd/linger +ExecStartPre=/bin/touch /var/lib/systemd/linger/stormux +# Unmute and set volume +ExecStart=/usr/local/bin/livecd-sound + +[Install] +WantedBy=sound.target diff --git a/x86_64/airootfs/etc/systemd/system/stormux-repo-init.service b/x86_64/airootfs/etc/systemd/system/stormux-repo-init.service new file mode 100644 index 0000000..70bf01f --- /dev/null +++ b/x86_64/airootfs/etc/systemd/system/stormux-repo-init.service @@ -0,0 +1,13 @@ +[Unit] +Description=Initialize Stormux repository key +After=pacman-init.service +Requires=pacman-init.service + +[Service] +Type=oneshot +RemainAfterExit=yes +ExecStart=/usr/bin/pacman-key --add /usr/share/stormux/stormux_repo.pub +ExecStart=/usr/bin/pacman-key --lsign-key 52ADA49000F1FF0456F8AEEFB4CDE1CD56EF8E82 + +[Install] +WantedBy=multi-user.target diff --git a/x86_64/airootfs/etc/systemd/system/stormux-speech.service b/x86_64/airootfs/etc/systemd/system/stormux-speech.service new file mode 100644 index 0000000..710d13a --- /dev/null +++ b/x86_64/airootfs/etc/systemd/system/stormux-speech.service @@ -0,0 +1,16 @@ +[Unit] +Description=Stormux screen reader and speech service +After=stormux-audio-setup.service sound.target +Wants=stormux-audio-setup.service +Before=getty@tty1.service + +[Service] +Type=oneshot +RemainAfterExit=yes +# Give pipewire a moment to initialize +ExecStartPre=/bin/sleep 2 +# Start Fenrir screen reader +ExecStart=/bin/systemctl start fenrirscreenreader.service + +[Install] +WantedBy=multi-user.target diff --git a/x86_64/airootfs/etc/systemd/system/systemd-firstboot.service b/x86_64/airootfs/etc/systemd/system/systemd-firstboot.service new file mode 120000 index 0000000..dc1dc0c --- /dev/null +++ b/x86_64/airootfs/etc/systemd/system/systemd-firstboot.service @@ -0,0 +1 @@ +/dev/null \ No newline at end of file diff --git a/x86_64/airootfs/etc/systemd/system/time_sync_at_boot.service b/x86_64/airootfs/etc/systemd/system/time_sync_at_boot.service new file mode 100644 index 0000000..c49ba4c --- /dev/null +++ b/x86_64/airootfs/etc/systemd/system/time_sync_at_boot.service @@ -0,0 +1,11 @@ +[Unit] +Description=Update system time from worldtimeapi.org +After=network-online.target +Wants=network-online.target + +[Service] +Type=oneshot +ExecStart=/usr/local/bin/sync_time.sh + +[Install] +WantedBy=multi-user.target diff --git a/x86_64/airootfs/etc/vconsole.conf b/x86_64/airootfs/etc/vconsole.conf new file mode 100644 index 0000000..aaa62c0 --- /dev/null +++ b/x86_64/airootfs/etc/vconsole.conf @@ -0,0 +1,3 @@ +# This is the fallback vconsole configuration provided by systemd. + +KEYMAP=us_alt diff --git a/x86_64/airootfs/etc/wireplumber/main.lua.d/50-analog-priority.lua b/x86_64/airootfs/etc/wireplumber/main.lua.d/50-analog-priority.lua new file mode 100644 index 0000000..b29aeaa --- /dev/null +++ b/x86_64/airootfs/etc/wireplumber/main.lua.d/50-analog-priority.lua @@ -0,0 +1,31 @@ +-- Prioritize analog and USB audio devices over HDMI +-- This ensures real sound cards are selected by default + +rule = { + matches = { + { + { "device.form-factor", "equals", "internal" }, + }, + { + { "device.form-factor", "equals", "speaker" }, + }, + { + { "device.form-factor", "equals", "headphone" }, + }, + { + { "device.bus", "equals", "usb" }, + }, + { + { "node.name", "matches", "alsa_output.pci-*analog*" }, + }, + { + { "node.name", "matches", "alsa_output.usb-*" }, + }, + }, + apply_properties = { + ["priority.driver"] = 1000, + ["priority.session"] = 1000, + }, +} + +table.insert(alsa_monitor.rules, rule) diff --git a/x86_64/airootfs/etc/wireplumber/main.lua.d/51-hdmi-deprioritize.lua b/x86_64/airootfs/etc/wireplumber/main.lua.d/51-hdmi-deprioritize.lua new file mode 100644 index 0000000..0c5113f --- /dev/null +++ b/x86_64/airootfs/etc/wireplumber/main.lua.d/51-hdmi-deprioritize.lua @@ -0,0 +1,22 @@ +-- Deprioritize HDMI audio devices +-- This ensures analog/USB audio devices are preferred over HDMI + +rule = { + matches = { + { + { "device.name", "matches", "hdmi*" }, + }, + { + { "device.name", "matches", "HDMI*" }, + }, + { + { "node.name", "matches", "alsa_output.pci-*hdmi*" }, + }, + }, + apply_properties = { + ["priority.driver"] = 100, + ["priority.session"] = 100, + }, +} + +table.insert(alsa_monitor.rules, rule) diff --git a/x86_64/airootfs/home/stormux/.bash_aliases b/x86_64/airootfs/home/stormux/.bash_aliases new file mode 100644 index 0000000..10ba8f8 --- /dev/null +++ b/x86_64/airootfs/home/stormux/.bash_aliases @@ -0,0 +1,4 @@ +# Raspberry Pi Information +alias pi-temp='/usr/bin/vcgencmd measure_temp' +alias pi-version='cat /sys/firmware/devicetree/base/model;echo' +alias pi-ip='ip a | grep -v "127.0.0.1" | grep -E -o "([0-9]{1,3}\.){3}[0-9]{1,3}/[0-9]{1,2}"' diff --git a/x86_64/airootfs/home/stormux/.bash_functions b/x86_64/airootfs/home/stormux/.bash_functions new file mode 100644 index 0000000..c4d13a6 --- /dev/null +++ b/x86_64/airootfs/home/stormux/.bash_functions @@ -0,0 +1,21 @@ +memuse() { + ps axo rss,comm,pid \ + | awk '{ proc_list[$2] += $1; } END \ + { for (proc in proc_list) { printf("%d\t%s\n", proc_list[proc],proc); }}' \ + | sort -n | tail -n 10 | sort -rn \ + | awk '{$1/=1024;printf "%.0fMB\t",$1}{print $2}' +} + + +pdf() +{ + if [[ $# -ne 1 ]]; then + echo 'Usage: pdf ' >&2 + else + local dir=$(mktemp -d -p /tmp pdf_conversion.XXXXXX) + local outFile="${1##*/}" + local outFile="${outFile%.*}" + pdftohtml -noframes -i -s "$1" "${dir}/${outFile}.html" + w3m -s "${dir}/${outFile}.html" + fi +} diff --git a/x86_64/airootfs/home/stormux/.bashrc b/x86_64/airootfs/home/stormux/.bashrc new file mode 100644 index 0000000..65f57bd --- /dev/null +++ b/x86_64/airootfs/home/stormux/.bashrc @@ -0,0 +1,24 @@ +# +# ~/.bashrc +# + +# If not running interactively, don't do anything +[[ $- != *i* ]] && return + +#Change directories without using cd +shopt -s autocd + +# Keep bash history in screen +export HISTFILE="${HISTFILE}${WINDOW:+.${WINDOW}}" + +# load Aliases and functions +[[ -f ".bash_aliases" ]] && source .bash_aliases +[[ -f ".bash_functions" ]] && source .bash_functions +#Invironment variables +PS1='[\u@\h \W] \$ ' +export DIALOGOPTS='--no-lines --visit-items' +GPG_TTY=$(tty) +export GPG_TTY +# Don't put commands prefixed with space, or duplicate commands in history +export HISTCONTROL=ignoreboth + diff --git a/x86_64/airootfs/home/stormux/.config/pipewire/pipewire-pulse.conf.d/50-fenrir-console.conf b/x86_64/airootfs/home/stormux/.config/pipewire/pipewire-pulse.conf.d/50-fenrir-console.conf new file mode 100644 index 0000000..e5f2a1d --- /dev/null +++ b/x86_64/airootfs/home/stormux/.config/pipewire/pipewire-pulse.conf.d/50-fenrir-console.conf @@ -0,0 +1,24 @@ +# Fenrir console audio support +# Adds secondary socket for console applications like Fenrir + +pulse.properties = { + # the addresses this server listens on + server.address = [ + "unix:native" + "unix:/tmp/pulse.sock" # console access socket + ] +} + +# client/stream specific properties +pulse.rules = [ + { + # speech dispatcher asks for too small latency and then underruns. + matches = [ { application.name = "~speech-dispatcher*" } ] + actions = { + update-props = { + pulse.min.req = 1024/48000 # 21ms + pulse.min.quantum = 1024/48000 # 21ms + } + } + } +] diff --git a/x86_64/airootfs/home/stormux/.config/systemd/user/default.target.wants/pipewire-init-sound.service b/x86_64/airootfs/home/stormux/.config/systemd/user/default.target.wants/pipewire-init-sound.service new file mode 120000 index 0000000..b00efbc --- /dev/null +++ b/x86_64/airootfs/home/stormux/.config/systemd/user/default.target.wants/pipewire-init-sound.service @@ -0,0 +1 @@ +../pipewire-init-sound.service \ No newline at end of file diff --git a/x86_64/airootfs/home/stormux/.config/systemd/user/pipewire-init-sound.service b/x86_64/airootfs/home/stormux/.config/systemd/user/pipewire-init-sound.service new file mode 100644 index 0000000..f687e1e --- /dev/null +++ b/x86_64/airootfs/home/stormux/.config/systemd/user/pipewire-init-sound.service @@ -0,0 +1,12 @@ +[Unit] +Description=Initialize Pipewire Audio with Sound Test +After=pipewire.service pipewire-pulse.service wireplumber.service +Wants=pipewire.service pipewire-pulse.service wireplumber.service + +[Service] +Type=oneshot +RemainAfterExit=yes +ExecStart=/usr/local/bin/init-pipewire-sound.sh + +[Install] +WantedBy=default.target diff --git a/x86_64/airootfs/home/stormux/.config/wireplumber/bluetooth.conf.d/50-fenrir-bluez.conf b/x86_64/airootfs/home/stormux/.config/wireplumber/bluetooth.conf.d/50-fenrir-bluez.conf new file mode 100644 index 0000000..c5ffd39 --- /dev/null +++ b/x86_64/airootfs/home/stormux/.config/wireplumber/bluetooth.conf.d/50-fenrir-bluez.conf @@ -0,0 +1,24 @@ +# Fenrir console audio support +# Prevents bluetooth disconnection when switching TTY + +monitor.bluez.properties = { + # Disable logind integration to prevent bluetooth device suspension on TTY switch + bluez5.enable-sbc-xq = true + bluez5.enable-msbc = true + bluez5.enable-hw-volume = true +} + +monitor.bluez.rules = [ + { + matches = [ + { + device.name = "~bluez_card.*" + } + ] + actions = { + update-props = { + session.suspend-timeout-seconds = 0 + } + } + } +] diff --git a/x86_64/airootfs/home/stormux/.config/wireplumber/main.conf.d/50-fenrir-no-suspend.conf b/x86_64/airootfs/home/stormux/.config/wireplumber/main.conf.d/50-fenrir-no-suspend.conf new file mode 100644 index 0000000..4217470 --- /dev/null +++ b/x86_64/airootfs/home/stormux/.config/wireplumber/main.conf.d/50-fenrir-no-suspend.conf @@ -0,0 +1,35 @@ +# Fenrir console audio support +# Prevents audio device suspension when switching to TTY console + +monitor.alsa.rules = [ + { + matches = [ + { + device.name = "~alsa_card.*" + } + ] + actions = { + update-props = { + api.alsa.use-acp = true + api.acp.auto-profile = false + api.acp.auto-port = false + session.suspend-timeout-seconds = 0 + } + } + } + { + matches = [ + { + node.name = "~alsa_input.*" + } + { + node.name = "~alsa_output.*" + } + ] + actions = { + update-props = { + session.suspend-timeout-seconds = 0 + } + } + } +] diff --git a/x86_64/airootfs/home/stormux/.inputrc b/x86_64/airootfs/home/stormux/.inputrc new file mode 100644 index 0000000..0dcf6ea --- /dev/null +++ b/x86_64/airootfs/home/stormux/.inputrc @@ -0,0 +1,6 @@ +# Reload changes with control+x followed by control+r +set echo-control-characters off + +# History searching with up and down arrows. +"\e[A": history-search-backward +"\e[B": history-search-forward diff --git a/x86_64/airootfs/home/stormux/.screenrc b/x86_64/airootfs/home/stormux/.screenrc new file mode 100644 index 0000000..bd20ce3 --- /dev/null +++ b/x86_64/airootfs/home/stormux/.screenrc @@ -0,0 +1,18 @@ +vbell off +bell_msg "" +hardstatus off +startup_message off +defscrollback 4096 +bind ! select 10 +bind @ select 11 +bind \# select 12 +bind $ select 13 +bind % select 14 +bind ^ select 15 +bind & select 16 +bind * select 17 +bind ( select 18 +bind ) select 19 +bind b eval "writebuf" 'exec !!! xclip -selection "clipboard" -i /tmp/screen-exchange' +#termcapinfo xterm|xterms|xs|rxvt ti@:te@ +termcapinfo xterm* ti@:te@ diff --git a/x86_64/airootfs/root/.config/pulse/client.conf b/x86_64/airootfs/root/.config/pulse/client.conf new file mode 100644 index 0000000..2a09e73 --- /dev/null +++ b/x86_64/airootfs/root/.config/pulse/client.conf @@ -0,0 +1,36 @@ +# This file is part of PulseAudio. +# +# PulseAudio is free software; you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# PulseAudio is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with PulseAudio; if not, see . + +## Configuration file for PulseAudio clients. See pulse-client.conf(5) for +## more information. Default values are commented out. Use either ; or # for +## commenting. + +; default-sink = +; default-source = +default-server = unix:/tmp/pulse.sock +; default-dbus-server = + +autospawn = no +; autospawn = yes +; daemon-binary = /usr/bin/pulseaudio +; extra-arguments = --log-target=syslog + +; cookie-file = + +; enable-shm = yes +; shm-size-bytes = 0 # setting this 0 will use the system-default, usually 64 MiB + +; auto-connect-localhost = no +; auto-connect-display = no diff --git a/x86_64/airootfs/root/rename-user.sh b/x86_64/airootfs/root/rename-user.sh new file mode 100755 index 0000000..3e66b23 --- /dev/null +++ b/x86_64/airootfs/root/rename-user.sh @@ -0,0 +1,103 @@ +#!/usr/bin/env bash + +# Renames a user +# Required arguments: old user name, new user name + +set -e + +question() { + echo + echo "$@" + read -r answer + answer="${answer:0:1}" + answer="${answer^}" +} + +if [[ $# -ne 2 ]]; then + echo "Usage: $0 old-user new-user" + exit 1 +fi + +oldUser="$1" +newUser="$2" + +# Make sure old user exists +if ! id "$oldUser" >/dev/null 2>&1; then + echo "The user $oldUser does not exist." + exit 1 +fi + +# Make sure old user is not logged in +if pgrep -u "$oldUser" >/dev/null; then + echo "The user $oldUser is currently logged in or has running processes. Cannot continue." + question "Would you like to forcibly log out $oldUser? (Y/N)" + if [[ "$answer" != "Y" ]]; then + exit 1 + fi + systemctl stop display-manager + loginctl terminate-user "$oldUser" + sleep 2 + if pgrep -u "$oldUser" >/dev/null; then + echo "The user $oldUser still has running processes after termination. Cannot continue." + exit 1 + fi +fi + +# Make sure new user does not exist +if id "$newUser" >/dev/null 2>&1; then + echo "The user name $newUser is already taken." + exit 1 +fi + +# Make sure the new name is acceptable +if ! [[ "$newUser" =~ ^[a-z_][a-z0-9_-]{0,31}$ ]]; then + echo "$newUser is not an acceptable user name." + exit 1 +fi + +# Passed all safety checks, proceed with the rename +echo "Renaming $oldUser to $newUser..." +groups=$(id -nG "$oldUser") +groups="${groups// /,}" +usermod -G "$groups" -m -d "/home/$newUser" -l "$newUser" "$oldUser" + +# Update nodm.conf if it exists +if [[ -e /etc/nodm.conf ]]; then + echo "Updating /etc/nodm.conf..." + sed -i -e "s#^NODM_USER=.*#NODM_USER='$newUser'#" -e "s#^NODM_XSESSION=.*#NODM_XSESSION='/home/$newUser/.xinitrc'#" /etc/nodm.conf +fi + +# Copy over crontab if it exists +if crontab -u "$oldUser" -l >/tmp/${oldUser}_crontab.bak 2>/dev/null; then + echo "Copying over crontab..." + if crontab -u "$newUser" "/tmp/${oldUser}_crontab.bak"; then + rm "/tmp/${oldUser}_crontab.bak" + else + echo "Warning: failed to restore crontab for $newUser." + rm "/tmp/${oldUser}_crontab.bak" + fi +fi + +# Update linger +if [[ -e "/var/lib/systemd/linger/$oldUser" ]]; then + echo "Enabling linger..." + mv "/var/lib/systemd/linger/$oldUser" "/var/lib/systemd/linger/$newUser" +fi + +# Optionally update files in new home directory +echo +echo "Would you like to search for references to $oldUser and update them to $newUser in files located in /home/$newUser?" +question "This can take a while. (Y/N)" +if [[ "$answer" == "Y" ]]; then + echo "Updating files..." + find "/home/$newUser" -type f -exec grep -Iq . "{}" \; -and -exec sed -i "s|$oldUser|$newUser|g" "{}" \; +fi + +echo +echo "Rename complete. The user, $newUser, is now available." +question "Would you like to reboot?" +if [[ "${answer}" == "Y" ]]; then + reboot +fi + +exit 0 diff --git a/x86_64/airootfs/skel b/x86_64/airootfs/skel new file mode 120000 index 0000000..7ea1b11 --- /dev/null +++ b/x86_64/airootfs/skel @@ -0,0 +1 @@ +../../../pi4/files/etc/skel \ No newline at end of file diff --git a/x86_64/airootfs/usr/local/bin/configure-stormux b/x86_64/airootfs/usr/local/bin/configure-stormux new file mode 100755 index 0000000..cd2579f --- /dev/null +++ b/x86_64/airootfs/usr/local/bin/configure-stormux @@ -0,0 +1,141 @@ +#!/usr/bin/env bash + +# For audible sudo prompts: +unset sudoFlags +if [[ -x /etc/audibleprompt.sh ]]; then + export SUDO_ASKPASS=/etc/audibleprompt.sh + export sudoFlags=("-A") +fi + +trap cleanup EXIT +cleanup() { + popd &> /dev/null + if ! [[ -x /opt/configure-stormux/configure-stormux.sh ]]; then + echo "Initial setup is not complete." + echo "To continue setup, please run:" + echo "sudo configure-stormux" + fi +} + + +if [[ -x /opt/configure-stormux/configure-stormux.sh ]]; then + pushd /opt/configure-stormux + ./configure-stormux.sh + exit 0 +fi + +# Volume calibration is now handled in stormux_first_boot.sh + +export DIALOGOPTS='--insecure --no-lines --visit-items' + +set_timezone() { + # Get the list of timezones + mapfile -t regions < <(timedatectl --no-pager list-timezones | cut -d '/' -f1 | sort -u) + + # Use the same text twice here and just hide the tag field. + region=$(dialog --backtitle "Please select your Region" \ + --no-tags \ + --menu "Use up and down arrows or page-up and page-down to navigate the list, and press 'Enter' to make your selection." 0 0 0 \ + $(for i in ${regions[@]} ; do echo "$i";echo "$i";done) --stdout) + + + mapfile -t cities < <(timedatectl --no-pager list-timezones | grep "$region" | cut -d '/' -f2 | sort -u) + + # Use the same text twice here and just hide the tag field. + city=$(dialog --backtitle "Please select a city near you" \ + --no-tags \ + --menu "Use up and down arrow or page-up and page-down to navigate the list." 0 0 10 \ + $(for i in ${cities[@]} ; do echo "$i";echo "$i";done) --stdout) + + # Set the timezone + if [[ -f /etc/localtime ]]; then + rm /etc/localtime + fi + ln -sf /usr/share/zoneinfo/${region}/${city} /etc/localtime + timedatectl set-ntp true +} +# Offer to switch fenrir layout. +echo "Would you like to switch Fenrir to laptop layout?" +echo "Press y for yes or n for no followed by enter." +read -r continue +continue="${continue::1}" +if [[ "${continue,}" == "y" ]];then + sed -i 's/=desktop/=laptop/' /etc/fenrirscreenreader/settings/settings.conf + clear + systemctl restart fenrirscreenreader.service +fi + +# Check for possible resize +diskSource="$(df --output='source' / | tail -1)" +diskSize="$(df -h --output='size' / | tail -1 | tr -cd '[:digit:].')" +diskSize=${diskSize%.*} +if [[ $diskSize -le 7 ]]; then + echo "$diskSource is only $diskSize gigs, which means it probably needs to be resized. Would you like to do this now?" + echo "Press y for yes or n for no followed by enter." + read -r continue + continue="${continue::1}" + if [[ "${continue,}" == "y" ]];then + # Extract base device name (handles mmcblk0p2, nvme0n1p2, sda2, etc.) + if [[ "$diskSource" =~ (.*[0-9]+)p[0-9]+$ ]]; then + # Handle mmcblk0p2, nvme0n1p2 style + diskDevice="${BASH_REMATCH[1]}" + else + # Handle sda2, sdb3 style + diskDevice="$(echo "$diskSource" | sed 's/[0-9]*$//')" + fi + echo "Yes" | sudo "${sudoFlags[@]}" parted ---pretend-input-tty "$diskDevice" resizepart 2 100% + sudo "${sudoFlags[@]}" resize2fs -f "$diskSource" + fi +fi + +if ! ping -c1 stormux.org &> /dev/null ; then + echo "No internet connection detected. Press enter to open NetworkManager." + read -r continue + echo "setting set focus#highlight=True" | socat - UNIX-CLIENT:/tmp/fenrirscreenreader-deamon.sock + nmtui-connect + echo "setting set focus#highlight=False" | socat - UNIX-CLIENT:/tmp/fenrirscreenreader-deamon.sock +fi +# Check for internet connectivity +if ping -qc1 -W 1 stormux.org &> /dev/null; then + echo "Updating the clock to prevent certificate errors..." + # Get current date and time + date_time=$(curl -s http://worldtimeapi.org/api/ip | grep -oP '(?<="datetime":")[^"]*') + echo "Current date and time: $date_time" + # set date and time + date -s "$date_time" + echo "If your Pi does not have a CMOS battery and is powered off regularly, it may take a while for the time to be set correctly after boot." + echo "Stormux provides a service to sync the time after internet connection is established." + read -rp "Would you like the time to sync as soon as the Pi connects to the internet? " answer + answer="${answer:0:1}" + if [[ "${answer,,}" == "y" ]]; then + systemctl enable time_sync_at_boot.service + else + echo "Time sync at boot skipped." + echo "If you change your mind later, simply type:" + echo "sudo systemctl enable time_sync_at_boot.service" + fi + set_timezone +else + echo "Please connect to the internet and run ${0##*/} again." + exit 1 +fi +echo "Installing configure-stormux..." +git -C /opt clone -q https://git.stormux.org/storm/configure-stormux || exit 1 + +echo +echo "Initial setup is complete." +echo +echo "The default passwords are stormux for the stormux user" +echo "and root for the root user. It is highly recommended to change them." +echo "To change the password for stormux, run:" +echo "passwd" +echo "To change the password for root, run:" +echo "sudo passwd" +echo +echo "For more configuration options, run configure-stormux," +echo "or you may configure your system manually." +echo +echo "Thank you for choosing Stormux." + + +exit 0 diff --git a/x86_64/airootfs/usr/local/bin/init-pipewire-sound.sh b/x86_64/airootfs/usr/local/bin/init-pipewire-sound.sh new file mode 100755 index 0000000..58b9db4 --- /dev/null +++ b/x86_64/airootfs/usr/local/bin/init-pipewire-sound.sh @@ -0,0 +1,21 @@ +#!/usr/bin/env bash +# Initialize pipewire audio by attempting to play sound until it succeeds +# This ensures pipewire is fully ready before fenrir starts + +maxAttempts=30 +attempt=0 + +while [[ $attempt -lt $maxAttempts ]]; do + # Try to play a silent sound using sox + if play -qnV0 synth .1 whi norm -100 2>/dev/null; then + # Success! Pipewire is working + exit 0 + fi + + # Wait a moment before trying again + sleep 1 + ((attempt++)) +done + +# Even if we failed, exit successfully so we don't block boot +exit 0 diff --git a/x86_64/airootfs/usr/local/bin/livecd-sound b/x86_64/airootfs/usr/local/bin/livecd-sound new file mode 100755 index 0000000..8a8ff92 --- /dev/null +++ b/x86_64/airootfs/usr/local/bin/livecd-sound @@ -0,0 +1,24 @@ +#!/usr/bin/env bash +# Configure audio for Stormux live environment +# Ensures pipewire is running and audio is properly configured + +# Start pipewire for the stormux user if not already running +if id stormux &>/dev/null; then + # Enable linger for stormux user + loginctl enable-linger stormux 2>/dev/null || true + + # Start pipewire user services + stormux_uid="$(id -u stormux)" + sudo -u stormux XDG_RUNTIME_DIR="/run/user/${stormux_uid}" systemctl --user enable --now pipewire.service pipewire-pulse.service wireplumber.service 2>/dev/null || true + + # Wait for pipewire to initialize + sleep 2 +fi + +# Unmute and set reasonable volumes +amixer -q set Master 70% unmute 2>/dev/null || true +amixer -q set PCM 70% unmute 2>/dev/null || true +amixer -q set Speaker 70% unmute 2>/dev/null || true +amixer -q set Headphone 70% unmute 2>/dev/null || true + +exit 0 diff --git a/x86_64/airootfs/usr/local/bin/setup-pipewire-live.sh b/x86_64/airootfs/usr/local/bin/setup-pipewire-live.sh new file mode 100755 index 0000000..cfcc284 --- /dev/null +++ b/x86_64/airootfs/usr/local/bin/setup-pipewire-live.sh @@ -0,0 +1,22 @@ +#!/usr/bin/env bash +# Setup Pipewire for the live environment +# This ensures pipewire is running before Fenrir starts + +# Note: Do not use set -e - we want this to succeed even if commands fail + +# Enable user linger for the stormux user (allows user services to run without login) +if [ -d /var/lib/systemd/linger ]; then + touch /var/lib/systemd/linger/stormux +fi + +# Start pipewire for the stormux user +if id stormux &>/dev/null; then + # Use machinectl to start user services in the user's session + machinectl shell stormux@ /usr/bin/systemctl --user enable pipewire.service pipewire-pulse.service wireplumber.service 2>/dev/null || true + machinectl shell stormux@ /usr/bin/systemctl --user start pipewire.service pipewire-pulse.service wireplumber.service 2>/dev/null || true +fi + +# Wait a moment for pipewire to initialize +sleep 2 + +exit 0 diff --git a/x86_64/airootfs/usr/local/bin/stormux-setup.sh b/x86_64/airootfs/usr/local/bin/stormux-setup.sh new file mode 100755 index 0000000..4dca9cf --- /dev/null +++ b/x86_64/airootfs/usr/local/bin/stormux-setup.sh @@ -0,0 +1,73 @@ +#!/usr/bin/env bash +# +# Customize the airootfs after package installation +# This script runs in the chroot environment after packages are installed + +set -e -u + +# Copy custom skel files, overwriting package defaults +if [ -d /etc/skel.custom ]; then + echo "Installing custom skel files..." + cp -f /etc/skel.custom/.* /etc/skel/ 2>/dev/null || true + rm -rf /etc/skel.custom +fi + +# Set the distribution name +echo 'Stormux \r (\l)' > /etc/issue +echo >> /etc/issue + +# Create realtime group if it doesn't exist +if ! getent group realtime > /dev/null 2>&1; then + echo "Creating realtime group..." + groupadd -r realtime +fi + +# Create stormux user with groups matching Pi build +echo "Creating stormux user..." +useradd -m -g users -G wheel,realtime,audio,video,network,brlapi -s /bin/bash stormux + +# Set passwords +echo -e "root\nroot" | passwd "root" +echo -e "stormux\nstormux" | passwd "stormux" + +# Configure git for stormux user +sudo -iu stormux bash -c 'git config --global init.defaultBranch master' + +# Create user directories +sudo -iu stormux xdg-user-dirs-update + +# Enable linger so that sound will start at login +mkdir -p /var/lib/systemd/linger +touch /var/lib/systemd/linger/stormux + +# Enable pipewire globally +# Pipewire configuration for fenrir is pre-installed in airootfs +systemctl --global enable pipewire.service pipewire-pulse.service + +# Configure sudo for wheel group +echo '%wheel ALL=(ALL) ALL' > /etc/sudoers.d/wheel + +# Set hostname +echo stormux > /etc/hostname + +# Disable systemd-networkd in favor of NetworkManager +systemctl disable systemd-networkd.service systemd-networkd.socket 2>/dev/null || true + +# Enable services +services=( + brltty.path + fenrirscreenreader.service + NetworkManager.service + stormux-audio-setup.service +) + +for service in "${services[@]}"; do + echo "Enabling $service..." + if systemctl enable "$service"; then + echo " $service: OK" + else + echo " $service: FAILED" + fi +done + +echo "Airootfs customization complete" diff --git a/x86_64/airootfs/usr/local/bin/sync_time.sh b/x86_64/airootfs/usr/local/bin/sync_time.sh new file mode 100755 index 0000000..aea1925 --- /dev/null +++ b/x86_64/airootfs/usr/local/bin/sync_time.sh @@ -0,0 +1,4 @@ +#!/usr/bin/env bash + +date_time=$(curl -s http://worldtimeapi.org/api/ip | grep -oP '(?<="datetime":")[^"]*') +date -s "$date_time" diff --git a/x86_64/airootfs/usr/share/kbd/keymaps/i386/qwerty/us_alt.map.gz b/x86_64/airootfs/usr/share/kbd/keymaps/i386/qwerty/us_alt.map.gz new file mode 100644 index 0000000..2b13854 Binary files /dev/null and b/x86_64/airootfs/usr/share/kbd/keymaps/i386/qwerty/us_alt.map.gz differ diff --git a/x86_64/airootfs/usr/share/stormux/stormux_repo.pub b/x86_64/airootfs/usr/share/stormux/stormux_repo.pub new file mode 100644 index 0000000..28edfe6 --- /dev/null +++ b/x86_64/airootfs/usr/share/stormux/stormux_repo.pub @@ -0,0 +1,29 @@ +-----BEGIN PGP PUBLIC KEY BLOCK----- + +mQINBGhTtIcBEADTCqY/+das1n52HTTlp3Uf5+ER5r0fNA2HgJq4GzEeFBdqdgSF +y05P9B94d4JWtWvt0ckjsNfku19O9IquKiYP5x9/sYT8RGeRUrTlN9qlCrytTsdM +a8ij9esGQOXDeyRJQTs5igbFWQ26MrJpOkmO8xMXGmfD29yOppRLzVS8Jed0mokk +aEajui3QSWcefDnFMBYNaMF04iuWgVxv/7102adh3u3+V632+fQQhFtu+x92iosU +GtWlGGe3UkEhWJIb6wf/VCYIYQAjxTQBLul2WByXqwCXmobzc7DJbte3FSEPvPis +nJiUmT0fsIIC9c1UbTJt5Gqb6o/oI61tEJEeXieBViXFE7HwBI7FUxaIXoozgiYA +BxaLHQT0Qv9k1SXbBm82xNydjqFHIAolYSp5s1wRIhErlOaG9w3+Tb8zFSekPsbg +cgS/b3PpWmnigXBJQ94Ee+6KoPMVrwEKIu/IHexRUVAm+66Xs55ccgMY+MUupIjX +Bdn9jCYB8NwpC3UNWoSv2oQ7F2hVbXZYC/dx7gKmyvzfrw5MLOX7yEoSGlJJp2iK +fLLP8nw+x7LnDFEnAjPjtmeH7e+JANH1scP/7YMKDszO1THSK3hBAK1aeq0aEFs8 +9AO++xZrNbCrF2MnqcGaXs/753k6kf8zyrW6t7A1opxjPHIz3WrQ8SbXXwARAQAB +tExTdG9ybXV4IChGb3Igc2lnbmluZyBzdG9ybXV4IHJlcG9zaXRvcnkgcGFja2Fn +ZXMpIDxzdG9ybV9kcmFnb25Ac3Rvcm11eC5vcmc+iQJOBBMBCgA4FiEEUq2kkADx +/wRW+K7vtM3hzVbvjoIFAmhTtIcCGwMFCwkIBwMFFQoJCAsFFgIDAQACHgECF4AA +CgkQtM3hzVbvjoLiLQ/9HJzlwr2JNGdR/LaM1Y6VuhASGDZsUsi5XLJ7qKUKN/eA +kq0LMO7TzHO++otsEolodMr8fTkthQTPqSnbLZsW9Y3wK9U2vajryblRSEBaY6VB +1ds0pAg5SXz7O2eI2Ne05dkYB176G72KcjrOiSanKjI9sqh6pdTHcQM3XbRxxEVn +or7fKbLs/eveFWRPW3EAwuVnWI1aw3Xw9BQ3TE1eEDPvBh2GVKZ6qskbzdwfZtUB +kxAa30M+ftlNDaV7d6mNfREefEJfZjYFrY2XiqTK3+w1Q1ZaugK0Bbd/YdAoGMdt +6gbd2h/IZtxduWW/HhvWX2wtKqn4fNxAyYcY3aWm8kuq0pXlyEZ96gZas6a2lu+f ++yLvIh3UtC1IimFMDMQnKCTbWgdhd0HMnG9ULnoOroXVGltnBQwlO0hrHSVD+qmy +NVPUxkzS3ZhqSmoW2G8hSvXpMjt/w5fhC0FJhFb/uM/7LqJWSl5aAkUHupN3t/nG +9o7chBQzzXwbpiS6DQuIt6ouyPpwNjeELFPNBjZDf0auVWj6ZZ5+B/bmyHXQ4wFS +bYKZdO9VeXhBxRUMfGpIKvIw/Lnc+1Toan1RTWoUoRH+HuK2D/LAuvsam36gtLrQ +XV3//7Mh4oQ0Zg4REG3SEfG9i3rav8wMtRmaJaSbwmMVpC6mT/uiEzCSgQhO/0c= +=HIM9 +-----END PGP PUBLIC KEY BLOCK----- diff --git a/x86_64/airootfs/var/lib/alsa/asound.state b/x86_64/airootfs/var/lib/alsa/asound.state new file mode 100644 index 0000000..d128b82 --- /dev/null +++ b/x86_64/airootfs/var/lib/alsa/asound.state @@ -0,0 +1,79 @@ +state.ALSA { + control.1 { + iface MIXER + name 'PCM Playback Volume' + value -197 + comment { + access 'read write' + type INTEGER + count 1 + range '-10239 - 400' + dbmin -9999999 + dbmax 400 + dbvalue.0 -197 + } + } + control.2 { + iface MIXER + name 'PCM Playback Switch' + value true + comment { + access 'read write' + type BOOLEAN + count 1 + } + } + control.3 { + iface MIXER + name 'PCM Playback Route' + value 1 + comment { + access 'read write' + type INTEGER + count 1 + range '0 - 2' + } + } + control.4 { + iface PCM + name 'IEC958 Playback Default' + value '0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000' + comment { + access 'read write' + type IEC958 + count 1 + } + } + control.5 { + iface PCM + name 'IEC958 Playback Con Mask' + value '0200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000' + comment { + access read + type IEC958 + count 1 + } + } + control.6 { + iface PCM + name 'IEC958 Playback PCM Stream' + value '0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000' + comment { + access 'read write inactive' + type IEC958 + count 1 + } + } +} +state.vc4hdmi { + control.1 { + iface PCM + name ELD + value '100008006a10000100000000000000000469fd22415355532056533232380917070000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000' + comment { + access 'read volatile' + type BYTES + count 128 + } + } +} diff --git a/x86_64/build.sh b/x86_64/build.sh new file mode 100755 index 0000000..7543c26 --- /dev/null +++ b/x86_64/build.sh @@ -0,0 +1,110 @@ +#!/usr/bin/env bash +# +# Copyright 2025, Stormux, +# +# This is free software; you can redistribute it and/or modify it under the +# terms of the GNU General Public License as published by the Free +# Software Foundation; either version 3, or (at your option) any later +# version. +# +# This software is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this package; see the file COPYING. If not, write to the Free +# Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +# 02110-1301, USA. +# + +set -e + +help() { + echo "Stormux x86_64 ISO Builder" + echo + echo "Usage: $0 [options]" + echo + echo "Options:" + echo " -o Output directory (default: ./out)" + echo " -w Work directory (default: ./work)" + echo " -h Show this help" + echo + echo "This script builds a Stormux x86_64 ISO using archiso." + echo "It must be run as root on an Arch Linux system." + exit 0 +} + +# Parse command line arguments +output_dir="./out" +work_dir="./work" + +while getopts "o:w:h" opt; do + case "$opt" in + o) output_dir="$OPTARG" ;; + w) work_dir="$OPTARG" ;; + h) help ;; + *) help ;; + esac +done + +# Make sure this script is run as root +if [ "$(whoami)" != "root" ]; then + echo "Error: This script must be run as root." + exit 1 +fi + +# Check for required tools +for tool in mkarchiso pacman; do + if ! command -v "$tool" &> /dev/null; then + echo "Error: $tool is not installed. Please install archiso package." + exit 1 + fi +done + +# Get the directory where this script is located +script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +pi4_files_dir="$script_dir/../pi4/files" + +echo "Building Stormux x86_64 ISO..." +echo "Profile directory: $script_dir" +echo "Output directory: $output_dir" +echo "Work directory: $work_dir" +echo + +# Clean up work directory from previous builds to ensure clean build environment +if [ -d "$work_dir" ]; then + echo "Cleaning up previous build artifacts..." + rm -rf "$work_dir" +fi + +# Note: Shared configuration files from pi4/files should already be in airootfs/ +# The airootfs/ directory is maintained as part of the x86_64 profile +# and should not be dynamically copied during build to avoid conflicts with packages +echo "Using existing airootfs configuration files..." + +# Add Stormux repository key to build host's keyring +echo "Setting up Stormux repository key on build host..." +key_file="$script_dir/stormux_repo.pub" +if [ ! -f "$key_file" ]; then + echo "Error: Stormux repository key not found at $key_file" + echo "Please ensure stormux_repo.pub exists in the x86_64 directory" + exit 1 +fi + +# Check if key is already in keyring +if ! pacman-key --list-keys 52ADA49000F1FF0456F8AEEFB4CDE1CD56EF8E82 &>/dev/null; then + echo "Adding Stormux repository key to build host keyring..." + pacman-key --add "$key_file" + pacman-key --lsign-key 52ADA49000F1FF0456F8AEEFB4CDE1CD56EF8E82 + echo "Key added successfully" +else + echo "Stormux repository key already in keyring" +fi + +# Build the ISO +mkarchiso -v -w "$work_dir" -o "$output_dir" "$script_dir" + +echo +echo "Build complete!" +echo "ISO file is in: $output_dir" diff --git a/x86_64/client.conf b/x86_64/client.conf new file mode 100644 index 0000000..2a09e73 --- /dev/null +++ b/x86_64/client.conf @@ -0,0 +1,36 @@ +# This file is part of PulseAudio. +# +# PulseAudio is free software; you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# PulseAudio is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with PulseAudio; if not, see . + +## Configuration file for PulseAudio clients. See pulse-client.conf(5) for +## more information. Default values are commented out. Use either ; or # for +## commenting. + +; default-sink = +; default-source = +default-server = unix:/tmp/pulse.sock +; default-dbus-server = + +autospawn = no +; autospawn = yes +; daemon-binary = /usr/bin/pulseaudio +; extra-arguments = --log-target=syslog + +; cookie-file = + +; enable-shm = yes +; shm-size-bytes = 0 # setting this 0 will use the system-default, usually 64 MiB + +; auto-connect-localhost = no +; auto-connect-display = no diff --git a/x86_64/efiboot/loader/entries/01-stormux-linux.conf b/x86_64/efiboot/loader/entries/01-stormux-linux.conf new file mode 100644 index 0000000..ea26505 --- /dev/null +++ b/x86_64/efiboot/loader/entries/01-stormux-linux.conf @@ -0,0 +1,5 @@ +title Stormux Accessible Linux (%ARCH%, UEFI) with speech +sort-key 01 +linux /%INSTALL_DIR%/boot/%ARCH%/vmlinuz-linux +initrd /%INSTALL_DIR%/boot/%ARCH%/initramfs-linux.img +options archisobasedir=%INSTALL_DIR% archisolabel=%ARCHISO_LABEL% accessibility=on diff --git a/x86_64/efiboot/loader/entries/02-stormux-linux-no-speech.conf b/x86_64/efiboot/loader/entries/02-stormux-linux-no-speech.conf new file mode 100644 index 0000000..a8cf144 --- /dev/null +++ b/x86_64/efiboot/loader/entries/02-stormux-linux-no-speech.conf @@ -0,0 +1,5 @@ +title Stormux Accessible Linux (%ARCH%, UEFI) +sort-key 02 +linux /%INSTALL_DIR%/boot/%ARCH%/vmlinuz-linux +initrd /%INSTALL_DIR%/boot/%ARCH%/initramfs-linux.img +options archisobasedir=%INSTALL_DIR% archisolabel=%ARCHISO_LABEL% diff --git a/x86_64/efiboot/loader/loader.conf b/x86_64/efiboot/loader/loader.conf new file mode 100644 index 0000000..c64c3ed --- /dev/null +++ b/x86_64/efiboot/loader/loader.conf @@ -0,0 +1,3 @@ +timeout 15 +default 01-stormux-linux.conf +beep on diff --git a/x86_64/fix-live-iso-services.sh b/x86_64/fix-live-iso-services.sh new file mode 100755 index 0000000..61b606e --- /dev/null +++ b/x86_64/fix-live-iso-services.sh @@ -0,0 +1,33 @@ +#!/usr/bin/env bash +# Fix live ISO services for x86_64 + +set -e + +cd "$(dirname "$0")" + +echo "=== Fixing Live ISO Services for x86_64 ===" +echo + +# 1. Remove Pi-specific first boot script +if [ -f airootfs/etc/profile.d/stormux_first_boot.sh ]; then + echo "Removing Pi-specific first boot script..." + sudo rm airootfs/etc/profile.d/stormux_first_boot.sh +fi + +# 2. Mask systemd-firstboot (blocks boot with interactive prompts) +echo "Masking systemd-firstboot.service..." +sudo ln -sf /dev/null airootfs/etc/systemd/system/systemd-firstboot.service + +# 3. Install Fenrir audio configurations +echo "Installing Fenrir audio configurations..." +sudo ./setup-fenrir-audio-configs.sh + +# 4. Check/verify enabled services +echo +echo "=== Enabled Services ===" +ls -la airootfs/etc/systemd/system/multi-user.target.wants/ | grep -E "fenrir|speech|audio" || echo "No speech/audio services in multi-user.target.wants" +ls -la airootfs/etc/systemd/system/sound.target.wants/ | grep -E "audio|sound" || echo "No services in sound.target.wants" + +echo +echo "=== Configuration Complete ===" +echo "Next step: sudo ./build.sh -v" diff --git a/x86_64/grub/grub.cfg b/x86_64/grub/grub.cfg new file mode 100644 index 0000000..25ad967 --- /dev/null +++ b/x86_64/grub/grub.cfg @@ -0,0 +1,106 @@ +# Load partition table and file system modules +insmod part_gpt +insmod part_msdos +insmod fat +insmod iso9660 +insmod ntfs +insmod ntfscomp +insmod exfat +insmod udf + +# Use graphics-mode output +if loadfont "${prefix}/fonts/unicode.pf2" ; then + insmod all_video + set gfxmode="auto" + terminal_input console + terminal_output console +fi + +# Enable serial console +insmod serial +insmod usbserial_common +insmod usbserial_ftdi +insmod usbserial_pl2303 +insmod usbserial_usbdebug +if serial --unit=0 --speed=115200; then + terminal_input --append serial + terminal_output --append serial +fi + +# Get a human readable platform identifier +if [ "${grub_platform}" == 'efi' ]; then + archiso_platform='UEFI' +elif [ "${grub_platform}" == 'pc' ]; then + archiso_platform='BIOS' +else + archiso_platform="${grub_cpu}-${grub_platform}" +fi + +# Set default menu entry +default=stormux +timeout=15 +timeout_style=menu + + +# Menu entries + +menuentry "Stormux Accessible Linux (%ARCH%, ${archiso_platform})" --class stormux --class gnu-linux --class gnu --class os --id 'stormux' { + set gfxpayload=keep + linux /%INSTALL_DIR%/boot/%ARCH%/vmlinuz-linux archisobasedir=%INSTALL_DIR% archisosearchuuid=%ARCHISO_UUID% + initrd /%INSTALL_DIR%/boot/%ARCH%/initramfs-linux.img +} + + +if [ "${grub_platform}" == 'efi' -a "${grub_cpu}" == 'x86_64' -a -f '/boot/memtest86+/memtest.efi' ]; then + menuentry 'Run Memtest86+ (RAM test)' --class memtest86 --class memtest --class gnu --class tool { + set gfxpayload=800x600,1024x768 + linux /boot/memtest86+/memtest.efi + } +fi +if [ "${grub_platform}" == 'pc' -a -f '/boot/memtest86+/memtest' ]; then + menuentry 'Run Memtest86+ (RAM test)' --class memtest86 --class memtest --class gnu --class tool { + set gfxpayload=800x600,1024x768 + linux /boot/memtest86+/memtest + } +fi +if [ "${grub_platform}" == 'efi' ]; then + if [ "${grub_cpu}" == 'x86_64' -a -f '/shellx64.efi' ]; then + menuentry 'UEFI Shell' --class efi { + chainloader /shellx64.efi + } + elif [ "${grub_cpu}" == 'i386' -a -f '/shellia32.efi' ]; then + menuentry 'UEFI Shell' --class efi { + chainloader /shellia32.efi + } + elif [ "${grub_cpu}" == 'arm64' -a -f '/shellaa64.efi' ]; then + menuentry 'UEFI Shell' --class efi { + chainloader /shellaa64.efi + } + elif [ "${grub_cpu}" == 'riscv64' -a -f '/shellriscv64.efi' ]; then + menuentry 'UEFI Shell' --class efi { + chainloader /shellriscv64.efi + } + elif [ "${grub_cpu}" == 'loongarch64' -a -f '/shellloongarch64.efi' ]; then + menuentry 'UEFI Shell' --class efi { + chainloader /shellloongarch64.efi + } + fi + + menuentry 'UEFI Firmware Settings' --id 'uefi-firmware' { + fwsetup + } +fi + +menuentry 'System shutdown' --class shutdown --class poweroff { + echo 'System shutting down...' + halt +} + +menuentry 'System restart' --class reboot --class restart { + echo 'System rebooting...' + reboot +} + + +# GRUB init tune for accessibility +play 600 988 1 1319 4 diff --git a/x86_64/grub/loopback.cfg b/x86_64/grub/loopback.cfg new file mode 100644 index 0000000..1a48fc5 --- /dev/null +++ b/x86_64/grub/loopback.cfg @@ -0,0 +1,85 @@ +# https://www.supergrubdisk.org/wiki/Loopback.cfg + +# Search for the ISO volume +search --no-floppy --set=archiso_img_dev --file "${iso_path}" +probe --set archiso_img_dev_uuid --fs-uuid "${archiso_img_dev}" + +# Get a human readable platform identifier +if [ "${grub_platform}" == 'efi' ]; then + archiso_platform='UEFI' +elif [ "${grub_platform}" == 'pc' ]; then + archiso_platform='BIOS' +else + archiso_platform="${grub_cpu}-${grub_platform}" +fi + +# Set default menu entry +default=archlinux +timeout=15 +timeout_style=menu + + +# Menu entries + +menuentry "Arch Linux install medium (%ARCH%, ${archiso_platform})" --class arch --class gnu-linux --class gnu --class os --id 'archlinux' { + set gfxpayload=keep + linux /%INSTALL_DIR%/boot/%ARCH%/vmlinuz-linux archisobasedir=%INSTALL_DIR% img_dev=UUID=${archiso_img_dev_uuid} img_loop="${iso_path}" + initrd /%INSTALL_DIR%/boot/%ARCH%/initramfs-linux.img +} + +menuentry "Arch Linux install medium with speakup screen reader (%ARCH%, ${archiso_platform})" --hotkey s --class arch --class gnu-linux --class gnu --class os --id 'archlinux-accessibility' { + set gfxpayload=keep + linux /%INSTALL_DIR%/boot/%ARCH%/vmlinuz-linux archisobasedir=%INSTALL_DIR% img_dev=UUID=${archiso_img_dev_uuid} img_loop="${iso_path}" accessibility=on + initrd /%INSTALL_DIR%/boot/%ARCH%/initramfs-linux.img +} + + +if [ "${grub_platform}" == 'efi' -a "${grub_cpu}" == 'x86_64' -a -f '/boot/memtest86+/memtest.efi' ]; then + menuentry 'Run Memtest86+ (RAM test)' --class memtest86 --class memtest --class gnu --class tool { + set gfxpayload=800x600,1024x768 + linux /boot/memtest86+/memtest.efi + } +fi +if [ "${grub_platform}" == 'pc' -a -f '/boot/memtest86+/memtest' ]; then + menuentry 'Run Memtest86+ (RAM test)' --class memtest86 --class memtest --class gnu --class tool { + set gfxpayload=800x600,1024x768 + linux /boot/memtest86+/memtest + } +fi +if [ "${grub_platform}" == 'efi' ]; then + if [ "${grub_cpu}" == 'x86_64' -a -f '/shellx64.efi' ]; then + menuentry 'UEFI Shell' --class efi { + chainloader /shellx64.efi + } + elif [ "${grub_cpu}" == 'i386' -a -f '/shellia32.efi' ]; then + menuentry 'UEFI Shell' --class efi { + chainloader /shellia32.efi + } + elif [ "${grub_cpu}" == 'arm64' -a -f '/shellaa64.efi' ]; then + menuentry 'UEFI Shell' --class efi { + chainloader /shellaa64.efi + } + elif [ "${grub_cpu}" == 'riscv64' -a -f '/shellriscv64.efi' ]; then + menuentry 'UEFI Shell' --class efi { + chainloader /shellriscv64.efi + } + elif [ "${grub_cpu}" == 'loongarch64' -a -f '/shellloongarch64.efi' ]; then + menuentry 'UEFI Shell' --class efi { + chainloader /shellloongarch64.efi + } + fi + + menuentry 'UEFI Firmware Settings' --id 'uefi-firmware' { + fwsetup + } +fi + +menuentry 'System shutdown' --class shutdown --class poweroff { + echo 'System shutting down...' + halt +} + +menuentry 'System restart' --class reboot --class restart { + echo 'System rebooting...' + reboot +} diff --git a/x86_64/mask-firstboot.sh b/x86_64/mask-firstboot.sh new file mode 100644 index 0000000..920d621 --- /dev/null +++ b/x86_64/mask-firstboot.sh @@ -0,0 +1,10 @@ +#!/usr/bin/env bash +# Mask systemd-firstboot for live ISO (it blocks boot) + +cd airootfs/etc/systemd/system + +# Create mask symlink +ln -sf /dev/null systemd-firstboot.service + +echo "Masked systemd-firstboot.service" +ls -la systemd-firstboot.service diff --git a/x86_64/packages.x86_64 b/x86_64/packages.x86_64 new file mode 100644 index 0000000..1344f88 --- /dev/null +++ b/x86_64/packages.x86_64 @@ -0,0 +1,151 @@ +alsa-firmware +alsa-utils +amd-ucode +arch-install-scripts +base +base-devel +bash-completion +bcachefs-tools +bind +bluez +bluez-utils +bolt +brltty +broadcom-wl +btrfs-progs +clonezilla +cloud-init +cryptsetup +darkhttpd +ddrescue +dhcpcd +diffutils +dmidecode +dmraid +dnsmasq +dosfstools +e2fsprogs +edk2-shell +efibootmgr +espeak-ng +ethtool +exfatprogs +f2fs-tools +fatresize +fenrir +foot-terminfo +fsarchiver +git +gpart +gpm +gptfdisk +grub +hdparm +hyperv +intel-ucode +irssi +iw +iwd +jfsutils +kitty-terminfo +ldns +less +lftp +libfido2 +libusb-compat +linux +linux-atm +linux-firmware +linux-firmware-marvell +lsscsi +lvm2 +lynx +magic-wormhole +man-db +man-pages +mc +mdadm +memtest86+ +memtest86+-efi +mkinitcpio +mkinitcpio-archiso +mkinitcpio-nfs-utils +mmc-utils +modemmanager +mtools +nano +nbd +ndisc6 +networkmanager +nfs-utils +nilfs-utils +nmap +ntfs-3g +nvme-cli +open-iscsi +open-vm-tools +openconnect +openpgp-card-tools +openssh +openvpn +partclone +parted +partimage +pcsclite +pipewire +pipewire-alsa +pipewire-jack +pipewire-pulse +poppler +ppp +pptpclient +pv +python-dbus +python-pyenchant +python-pyte +python-pyperclip +qemu-guest-agent +realtime-privileges +refind +reflector +rhvoice-voice-bdl +rsync +rxvt-unicode-terminfo +screen +speech-dispatcher +sdparm +sequoia-sq +sg3_utils +smartmontools +socat +sof-firmware +sox +squashfs-tools +sudo +syslinux +systemd-resolvconf +tcpdump +terminus-font +testdisk +tmux +tpm2-tools +tpm2-tss +udftools +usb_modeswitch +usbmuxd +usbutils +vim +virtualbox-guest-utils-nox +vpnc +w3m-git +wget +wireless-regdb +wireless_tools +wireplumber +wpa_supplicant +wvdial +xdg-user-dirs +xdg-utils +xfsprogs +xl2tpd +yay diff --git a/x86_64/pacman.conf b/x86_64/pacman.conf new file mode 100644 index 0000000..00fe68e --- /dev/null +++ b/x86_64/pacman.conf @@ -0,0 +1,104 @@ +# +# /etc/pacman.conf +# +# See the pacman.conf(5) manpage for option and repository directives + +# +# GENERAL OPTIONS +# +[options] +# The following paths are commented out with their default values listed. +# If you wish to use different paths, uncomment and update the paths. +#RootDir = / +#DBPath = /var/lib/pacman/ +#CacheDir = /var/cache/pacman/pkg/ +#LogFile = /var/log/pacman.log +#GPGDir = /etc/pacman.d/gnupg/ +#HookDir = /etc/pacman.d/hooks/ +HoldPkg = pacman glibc +#XferCommand = /usr/bin/curl -L -C - -f -o %o %u +#XferCommand = /usr/bin/wget --passive-ftp -c -O %o %u +#CleanMethod = KeepInstalled +Architecture = auto + +# Pacman won't upgrade packages listed in IgnorePkg and members of IgnoreGroup +#IgnorePkg = +#IgnoreGroup = + +#NoUpgrade = +#NoExtract = + +# Misc options +#UseSyslog +#Color +#NoProgressBar +# We cannot check disk space from within a chroot environment +#CheckSpace +#VerbosePkgLists +ParallelDownloads = 5 +#DownloadUser = alpm +#DisableSandbox + +# By default, pacman accepts packages signed by keys that its local keyring +# trusts (see pacman-key and its man page), as well as unsigned packages. +SigLevel = Required DatabaseOptional +LocalFileSigLevel = Optional +#RemoteFileSigLevel = Required + +# NOTE: You must run `pacman-key --init` before first using pacman; the local +# keyring can then be populated with the keys of all official Arch Linux +# packagers with `pacman-key --populate archlinux`. + +# +# REPOSITORIES +# - can be defined here or included from another file +# - pacman will search repositories in the order defined here +# - local/custom mirrors can be added here or in separate files +# - repositories listed first will take precedence when packages +# have identical names, regardless of version number +# - URLs will have $repo replaced by the name of the current repo +# - URLs will have $arch replaced by the name of the architecture +# +# Repository entries are of the format: +# [repo-name] +# Server = ServerName +# Include = IncludePath +# +# The header [repo-name] is crucial - it must be present and +# uncommented to enable the repo. +# + +# The testing repositories are disabled by default. To enable, uncomment the +# repo name header and Include lines. You can add preferred servers immediately +# after the header, and they will be used before the default mirrors. + +#[core-testing] +#Include = /etc/pacman.d/mirrorlist + +[stormux] +SigLevel = Required DatabaseOptional +Server = https://packages.stormux.org/$arch + +[core] +Include = /etc/pacman.d/mirrorlist + +#[extra-testing] +#Include = /etc/pacman.d/mirrorlist + +[extra] +Include = /etc/pacman.d/mirrorlist + +# If you want to run 32 bit applications on your x86_64 system, +# enable the multilib repositories as required here. + +#[multilib-testing] +#Include = /etc/pacman.d/mirrorlist + +#[multilib] +#Include = /etc/pacman.d/mirrorlist + +# An example of a custom package repository. See the pacman manpage for +# tips on creating your own repositories. +#[custom] +#SigLevel = Optional TrustAll +#Server = file:///home/custompkgs diff --git a/x86_64/profiledef.sh b/x86_64/profiledef.sh new file mode 100644 index 0000000..850c390 --- /dev/null +++ b/x86_64/profiledef.sh @@ -0,0 +1,31 @@ +#!/usr/bin/env bash +# shellcheck disable=SC2034 + +iso_name="stormux" +iso_label="STORMUX_X64" +iso_publisher="Stormux " +iso_application="Stormux Accessible Linux Live/Install DVD" +iso_version="$(date --date="@${SOURCE_DATE_EPOCH:-$(date +%s)}" +%Y.%m.%d)" +install_dir="stormux" +buildmodes=('iso') +bootmodes=('bios.syslinux' + 'uefi.systemd-boot') +arch="x86_64" +pacman_conf="pacman.conf" +airootfs_image_type="squashfs" +airootfs_image_tool_options=('-comp' 'xz' '-Xbcj' 'x86' '-b' '1M' '-Xdict-size' '1M') +bootstrap_tarball_compression=('zstd' '-c' '-T0' '--auto-threads=logical' '--long' '-19') +file_permissions=( + ["/etc/shadow"]="0:0:400" + ["/root"]="0:0:750" + ["/root/.automated_script.sh"]="0:0:755" + ["/root/.gnupg"]="0:0:700" + ["/root/.config"]="0:0:700" + ["/usr/local/bin/choose-mirror"]="0:0:755" + ["/usr/local/bin/Installation_guide"]="0:0:755" + ["/usr/local/bin/livecd-sound"]="0:0:755" + ["/usr/local/bin/configure-stormux"]="0:0:755" + ["/usr/local/bin/stormux-setup.sh"]="0:0:755" + ["/usr/local/bin/init-pipewire-sound.sh"]="0:0:755" + ["/home/stormux"]="1000:1000:755" +) diff --git a/x86_64/qemu-boot.sh b/x86_64/qemu-boot.sh new file mode 100755 index 0000000..327e11a --- /dev/null +++ b/x86_64/qemu-boot.sh @@ -0,0 +1,87 @@ +#!/usr/bin/env bash +# +# Copyright 2025, Stormux, +# +# This is free software; you can redistribute it and/or modify it under the +# terms of the GNU General Public License as published by the Free +# Software Foundation; either version 3, or (at your option) any later +# version. +# +# This software is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this package; see the file COPYING. If not, write to the Free +# Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +# 02110-1301, USA. +# +# Boot Stormux x86_64 ISO in QEMU with audio support + +set -e + +# Get the directory where this script is located +scriptDir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +outDir="${scriptDir}/out" +logDir="${scriptDir}/logs" + +# Create logs directory if it doesn't exist +mkdir -p "$logDir" + +# Generate timestamp for log files +timestamp=$(date +%Y%m%d_%H%M%S) +qemuLog="${logDir}/qemu-boot_${timestamp}.log" +serialLog="${logDir}/serial-console_${timestamp}.log" + +# Find the most recent ISO in the out directory +if [[ ! -d "$outDir" ]]; then + echo "Error: Output directory not found: $outDir" + echo "Please build an ISO first using: sudo ./build.sh" + exit 1 +fi + +# Find the most recent ISO file +isoFile=$(find "$outDir" -name "*.iso" -type f -printf '%T@ %p\n' 2>/dev/null | sort -rn | head -1 | cut -d' ' -f2-) + +if [[ -z "$isoFile" ]]; then + echo "Error: No ISO file found in $outDir" + echo "Please build an ISO first using: sudo ./build.sh" + exit 1 +fi + +echo "Found ISO: $isoFile" +echo "Booting Stormux in QEMU with audio support..." +echo +echo "Logging to:" +echo " QEMU log: $qemuLog" +echo " Serial console: $serialLog" +echo +echo "Note: After boot, press Ctrl+Alt+F2 to switch to tty2" +echo " where the stormux user will be logged in with Fenrir screen reader." +echo " You can monitor the serial console log in real-time with:" +echo " tail -f $serialLog" +echo + +# Export DISPLAY for console usage +export DISPLAY="${DISPLAY:-:0}" + +# Boot QEMU with audio support and logging +# -D: QEMU debug log (shows QEMU errors, device issues) +# -d: Debug categories (guest_errors, cpu_reset) +# -serial: Capture guest serial console (systemd messages, boot logs) +# -audiodev: PulseAudio backend for audio +# -device intel-hda: Intel HD Audio controller +# -device hda-duplex: HD Audio codec with input/output, connected to audiodev +exec qemu-system-x86_64 \ + -enable-kvm \ + -m 2048 \ + -cdrom "$isoFile" \ + -boot d \ + -audiodev pa,id=snd0 \ + -device intel-hda \ + -device hda-duplex,audiodev=snd0 \ + -serial file:"$serialLog" \ + -D "$qemuLog" \ + -d guest_errors,cpu_reset \ + -display gtk diff --git a/x86_64/setup-fenrir-audio-configs.sh b/x86_64/setup-fenrir-audio-configs.sh new file mode 100755 index 0000000..995527b --- /dev/null +++ b/x86_64/setup-fenrir-audio-configs.sh @@ -0,0 +1,26 @@ +#!/usr/bin/env bash +# Setup Fenrir audio configurations for the live ISO + +set -e + +# Create directories +mkdir -p airootfs/etc/skel/.config/pipewire/pipewire-pulse.conf.d +mkdir -p airootfs/etc/skel/.config/wireplumber/main.conf.d +mkdir -p airootfs/etc/skel/.config/wireplumber/bluetooth.conf.d +mkdir -p airootfs/root/.config/pulse + +# Copy user configs to skel +cp 50-fenrir-console.conf airootfs/etc/skel/.config/pipewire/pipewire-pulse.conf.d/ +cp 50-fenrir-no-suspend.conf airootfs/etc/skel/.config/wireplumber/main.conf.d/ +cp 50-fenrir-bluez.conf airootfs/etc/skel/.config/wireplumber/bluetooth.conf.d/ + +# Copy root config +cp client.conf airootfs/root/.config/pulse/ + +echo "Fenrir audio configurations installed successfully!" +echo "" +echo "Created:" +echo " - User pipewire-pulse config (50-fenrir-console.conf)" +echo " - User wireplumber suspend config (50-fenrir-no-suspend.conf)" +echo " - User wireplumber bluetooth config (50-fenrir-bluez.conf)" +echo " - Root pulse client config (client.conf)" diff --git a/x86_64/stormux_repo.pub b/x86_64/stormux_repo.pub new file mode 100644 index 0000000..28edfe6 --- /dev/null +++ b/x86_64/stormux_repo.pub @@ -0,0 +1,29 @@ +-----BEGIN PGP PUBLIC KEY BLOCK----- + +mQINBGhTtIcBEADTCqY/+das1n52HTTlp3Uf5+ER5r0fNA2HgJq4GzEeFBdqdgSF +y05P9B94d4JWtWvt0ckjsNfku19O9IquKiYP5x9/sYT8RGeRUrTlN9qlCrytTsdM +a8ij9esGQOXDeyRJQTs5igbFWQ26MrJpOkmO8xMXGmfD29yOppRLzVS8Jed0mokk +aEajui3QSWcefDnFMBYNaMF04iuWgVxv/7102adh3u3+V632+fQQhFtu+x92iosU +GtWlGGe3UkEhWJIb6wf/VCYIYQAjxTQBLul2WByXqwCXmobzc7DJbte3FSEPvPis +nJiUmT0fsIIC9c1UbTJt5Gqb6o/oI61tEJEeXieBViXFE7HwBI7FUxaIXoozgiYA +BxaLHQT0Qv9k1SXbBm82xNydjqFHIAolYSp5s1wRIhErlOaG9w3+Tb8zFSekPsbg +cgS/b3PpWmnigXBJQ94Ee+6KoPMVrwEKIu/IHexRUVAm+66Xs55ccgMY+MUupIjX +Bdn9jCYB8NwpC3UNWoSv2oQ7F2hVbXZYC/dx7gKmyvzfrw5MLOX7yEoSGlJJp2iK +fLLP8nw+x7LnDFEnAjPjtmeH7e+JANH1scP/7YMKDszO1THSK3hBAK1aeq0aEFs8 +9AO++xZrNbCrF2MnqcGaXs/753k6kf8zyrW6t7A1opxjPHIz3WrQ8SbXXwARAQAB +tExTdG9ybXV4IChGb3Igc2lnbmluZyBzdG9ybXV4IHJlcG9zaXRvcnkgcGFja2Fn +ZXMpIDxzdG9ybV9kcmFnb25Ac3Rvcm11eC5vcmc+iQJOBBMBCgA4FiEEUq2kkADx +/wRW+K7vtM3hzVbvjoIFAmhTtIcCGwMFCwkIBwMFFQoJCAsFFgIDAQACHgECF4AA +CgkQtM3hzVbvjoLiLQ/9HJzlwr2JNGdR/LaM1Y6VuhASGDZsUsi5XLJ7qKUKN/eA +kq0LMO7TzHO++otsEolodMr8fTkthQTPqSnbLZsW9Y3wK9U2vajryblRSEBaY6VB +1ds0pAg5SXz7O2eI2Ne05dkYB176G72KcjrOiSanKjI9sqh6pdTHcQM3XbRxxEVn +or7fKbLs/eveFWRPW3EAwuVnWI1aw3Xw9BQ3TE1eEDPvBh2GVKZ6qskbzdwfZtUB +kxAa30M+ftlNDaV7d6mNfREefEJfZjYFrY2XiqTK3+w1Q1ZaugK0Bbd/YdAoGMdt +6gbd2h/IZtxduWW/HhvWX2wtKqn4fNxAyYcY3aWm8kuq0pXlyEZ96gZas6a2lu+f ++yLvIh3UtC1IimFMDMQnKCTbWgdhd0HMnG9ULnoOroXVGltnBQwlO0hrHSVD+qmy +NVPUxkzS3ZhqSmoW2G8hSvXpMjt/w5fhC0FJhFb/uM/7LqJWSl5aAkUHupN3t/nG +9o7chBQzzXwbpiS6DQuIt6ouyPpwNjeELFPNBjZDf0auVWj6ZZ5+B/bmyHXQ4wFS +bYKZdO9VeXhBxRUMfGpIKvIw/Lnc+1Toan1RTWoUoRH+HuK2D/LAuvsam36gtLrQ +XV3//7Mh4oQ0Zg4REG3SEfG9i3rav8wMtRmaJaSbwmMVpC6mT/uiEzCSgQhO/0c= +=HIM9 +-----END PGP PUBLIC KEY BLOCK----- diff --git a/x86_64/syslinux/archiso_head.cfg b/x86_64/syslinux/archiso_head.cfg new file mode 100644 index 0000000..671ab4e --- /dev/null +++ b/x86_64/syslinux/archiso_head.cfg @@ -0,0 +1,28 @@ +SERIAL 0 115200 +UI vesamenu.c32 +MENU TITLE Arch Linux +MENU BACKGROUND splash.png + +MENU WIDTH 78 +MENU MARGIN 4 +MENU ROWS 7 +MENU VSHIFT 10 +MENU TABMSGROW 14 +MENU CMDLINEROW 14 +MENU HELPMSGROW 16 +MENU HELPMSGENDROW 29 + +# Refer to https://wiki.syslinux.org/wiki/index.php/Comboot/menu.c32 + +MENU COLOR border 30;44 #40ffffff #a0000000 std +MENU COLOR title 1;36;44 #9033ccff #a0000000 std +MENU COLOR sel 7;37;40 #e0ffffff #20ffffff all +MENU COLOR unsel 37;44 #50ffffff #a0000000 std +MENU COLOR help 37;40 #c0ffffff #a0000000 std +MENU COLOR timeout_msg 37;40 #80ffffff #00000000 std +MENU COLOR timeout 1;37;40 #c0ffffff #00000000 std +MENU COLOR msg07 37;40 #90ffffff #a0000000 std +MENU COLOR tabmsg 31;40 #30ffffff #00000000 std + +MENU CLEAR +MENU IMMEDIATE diff --git a/x86_64/syslinux/archiso_pxe-linux.cfg b/x86_64/syslinux/archiso_pxe-linux.cfg new file mode 100644 index 0000000..872aae8 --- /dev/null +++ b/x86_64/syslinux/archiso_pxe-linux.cfg @@ -0,0 +1,32 @@ +LABEL arch_nbd +TEXT HELP +Boot the Arch Linux install medium using NBD. +It allows you to install Arch Linux or perform system maintenance. +ENDTEXT +MENU LABEL Arch Linux install medium (%ARCH%, NBD) +LINUX ::/%INSTALL_DIR%/boot/%ARCH%/vmlinuz-linux +INITRD ::/%INSTALL_DIR%/boot/%ARCH%/initramfs-linux.img +APPEND archisobasedir=%INSTALL_DIR% archisosearchuuid=%ARCHISO_UUID% archiso_nbd_srv=${pxeserver} cms_verify=y +SYSAPPEND 3 + +LABEL arch_nfs +TEXT HELP +Boot the Arch Linux live medium using NFS. +It allows you to install Arch Linux or perform system maintenance. +ENDTEXT +MENU LABEL Arch Linux install medium (%ARCH%, NFS) +LINUX ::/%INSTALL_DIR%/boot/%ARCH%/vmlinuz-linux +INITRD ::/%INSTALL_DIR%/boot/%ARCH%/initramfs-linux.img +APPEND archisobasedir=%INSTALL_DIR% archiso_nfs_srv=${pxeserver}:/run/archiso/bootmnt cms_verify=y +SYSAPPEND 3 + +LABEL arch_http +TEXT HELP +Boot the Arch Linux live medium using HTTP. +It allows you to install Arch Linux or perform system maintenance. +ENDTEXT +MENU LABEL Arch Linux install medium (%ARCH%, HTTP) +LINUX ::/%INSTALL_DIR%/boot/%ARCH%/vmlinuz-linux +INITRD ::/%INSTALL_DIR%/boot/%ARCH%/initramfs-linux.img +APPEND archisobasedir=%INSTALL_DIR% archiso_http_srv=http://${pxeserver}/ cms_verify=y +SYSAPPEND 3 diff --git a/x86_64/syslinux/archiso_pxe.cfg b/x86_64/syslinux/archiso_pxe.cfg new file mode 100644 index 0000000..b4c9a80 --- /dev/null +++ b/x86_64/syslinux/archiso_pxe.cfg @@ -0,0 +1,5 @@ +INCLUDE archiso_head.cfg + +INCLUDE archiso_pxe-linux.cfg + +INCLUDE archiso_tail.cfg diff --git a/x86_64/syslinux/archiso_sys-linux.cfg b/x86_64/syslinux/archiso_sys-linux.cfg new file mode 100644 index 0000000..c85a142 --- /dev/null +++ b/x86_64/syslinux/archiso_sys-linux.cfg @@ -0,0 +1,9 @@ +LABEL stormux +TEXT HELP +Boot the Stormux accessible Linux live system on BIOS. +Fenrir screen reader starts automatically for accessibility. +ENDTEXT +MENU LABEL Stormux Accessible Linux (%ARCH%, BIOS) +LINUX /%INSTALL_DIR%/boot/%ARCH%/vmlinuz-linux +INITRD /%INSTALL_DIR%/boot/%ARCH%/initramfs-linux.img +APPEND archisobasedir=%INSTALL_DIR% archisolabel=%ARCHISO_LABEL% accessibility=on console=tty0 console=ttyS0,115200 diff --git a/x86_64/syslinux/archiso_sys.cfg b/x86_64/syslinux/archiso_sys.cfg new file mode 100644 index 0000000..a300885 --- /dev/null +++ b/x86_64/syslinux/archiso_sys.cfg @@ -0,0 +1,8 @@ +INCLUDE archiso_head.cfg + +DEFAULT stormux +TIMEOUT 150 + +INCLUDE archiso_sys-linux.cfg + +INCLUDE archiso_tail.cfg diff --git a/x86_64/syslinux/archiso_tail.cfg b/x86_64/syslinux/archiso_tail.cfg new file mode 100644 index 0000000..e84897c --- /dev/null +++ b/x86_64/syslinux/archiso_tail.cfg @@ -0,0 +1,35 @@ +LABEL existing +TEXT HELP +Boot an existing operating system. +Press TAB to edit the disk and partition number to boot. +ENDTEXT +MENU LABEL Boot existing OS +COM32 chain.c32 +APPEND hd0 0 + +# https://www.memtest.org/ +LABEL memtest +MENU LABEL Run Memtest86+ (RAM test) +LINUX /boot/memtest86+/memtest + +# https://wiki.syslinux.org/wiki/index.php/Hdt_(Hardware_Detection_Tool) +LABEL hdt +MENU LABEL Hardware Information (HDT) +COM32 hdt.c32 +APPEND modules_alias=hdt/modalias.gz pciids=hdt/pciids.gz + +LABEL reboot +TEXT HELP +Reboot computer. +The computer's firmware must support APM. +ENDTEXT +MENU LABEL Reboot +COM32 reboot.c32 + +LABEL poweroff +TEXT HELP +Power off computer. +The computer's firmware must support APM. +ENDTEXT +MENU LABEL Power Off +COM32 poweroff.c32 diff --git a/x86_64/syslinux/splash.png b/x86_64/syslinux/splash.png new file mode 100644 index 0000000..64b959a Binary files /dev/null and b/x86_64/syslinux/splash.png differ diff --git a/x86_64/syslinux/syslinux.cfg b/x86_64/syslinux/syslinux.cfg new file mode 100644 index 0000000..cbda72f --- /dev/null +++ b/x86_64/syslinux/syslinux.cfg @@ -0,0 +1,11 @@ +DEFAULT select + +LABEL select +COM32 whichsys.c32 +APPEND -pxe- pxe -sys- sys -iso- sys + +LABEL pxe +CONFIG archiso_pxe.cfg + +LABEL sys +CONFIG archiso_sys.cfg