Single-script builder (nosignal.sh) that turns a stock Arch Linux ISO into a fully-offline installer for a themed Hyprland + caelestia (Quickshell) desktop: matching SDDM greeter, Btrfs/Limine bootable snapshots, chwd-style GPU detection, and a curated "os updates" layer (keybind cheatsheet, settings panels, system polish, on-box management skill). See README.md. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
57 lines
2.6 KiB
Bash
Executable file
57 lines
2.6 KiB
Bash
Executable file
#!/bin/sh
|
|
# fix-limine-uki-entry.sh — idempotent. REQUIRES ROOT.
|
|
#
|
|
# With ENABLE_UKI=yes, limine removes /boot/vmlinuz-linux and
|
|
# /boot/initramfs-linux.img (UKI-only), but the installer-seeded first entry
|
|
# "/NoSignal (Arch Linux)" in limine.conf still uses `protocol: linux` ->
|
|
# boot():/vmlinuz-linux. That entry is the default auto-boot target and now
|
|
# dead-boots to a TTY. This converts it to a `protocol: efi` entry that boots
|
|
# the UKI, keeping the same label (so it stays first = default) and cmdline.
|
|
#
|
|
# Idempotent: if the entry is already protocol:efi (no vmlinuz path), it's a
|
|
# no-op. Always backs up limine.conf first. Refuses if the UKI is missing.
|
|
#
|
|
# NOTE: the durable fix belongs in the ISO installer's seeded limine.conf /
|
|
# limine config — see README. This repairs an already-installed system.
|
|
set -eu
|
|
|
|
ESP_PATH=/boot
|
|
UKI_NAME=nosignal
|
|
[ -r /etc/default/limine ] && . /etc/default/limine 2>/dev/null || true
|
|
[ -n "${ESP_PATH:-}" ] || ESP_PATH=/boot
|
|
[ -n "${CUSTOM_UKI_NAME:-}" ] && UKI_NAME="$CUSTOM_UKI_NAME"
|
|
|
|
CONF="$ESP_PATH/limine.conf"
|
|
UKI_REL="/EFI/Linux/${UKI_NAME}_linux.efi"
|
|
UKI_ABS="$ESP_PATH$UKI_REL"
|
|
|
|
[ "$(id -u)" -eq 0 ] || { echo "must run as root (edits $CONF)" >&2; exit 1; }
|
|
[ -f "$CONF" ] || { echo "no $CONF" >&2; exit 1; }
|
|
[ -f "$UKI_ABS" ] || { echo "UKI not found at $UKI_ABS — aborting (won't point at a missing file)" >&2; exit 1; }
|
|
|
|
# Already fixed? (the seeded entry no longer references vmlinuz)
|
|
if ! grep -q 'path: boot():/vmlinuz-linux' "$CONF"; then
|
|
echo "limine.conf has no dead vmlinuz entry — nothing to do"
|
|
exit 0
|
|
fi
|
|
|
|
cp -a "$CONF" "$CONF.bak.$(date +%Y%m%d%H%M%S)"
|
|
|
|
# Rewrite ONLY the manual entry's body: protocol:linux + vmlinuz + module_path
|
|
# lines become protocol:efi + UKI path. Keeps the `cmdline:` line as-is.
|
|
awk -v uki="$UKI_REL" '
|
|
/^\/NoSignal \(Arch Linux\)/ { print; inblk=1; next }
|
|
inblk && /^[^[:space:]]/ { inblk=0 } # next top-level entry ends the block
|
|
inblk && /^[[:space:]]*protocol:[[:space:]]*linux/ { print " protocol: efi"; next }
|
|
inblk && /^[[:space:]]*path:[[:space:]]*boot\(\):\/vmlinuz-linux/ { print " path: boot():" uki; next }
|
|
inblk && /^[[:space:]]*module_path:/ { next } # drop ucode/initramfs modules (UKI is self-contained)
|
|
{ print }
|
|
' "$CONF" > "$CONF.tmp"
|
|
|
|
# sanity: must still contain our UKI path and no vmlinuz path
|
|
grep -q "path: boot():$UKI_REL" "$CONF.tmp" && ! grep -q 'boot():/vmlinuz-linux' "$CONF.tmp" \
|
|
|| { echo "rewrite sanity check failed — leaving $CONF untouched" >&2; rm -f "$CONF.tmp"; exit 1; }
|
|
|
|
mv "$CONF.tmp" "$CONF"
|
|
sync
|
|
echo "fixed: '/NoSignal (Arch Linux)' now protocol:efi -> $UKI_REL (backup kept)"
|