From e8d5e41ef4e026d52cc9255097abb39fd493c19f Mon Sep 17 00:00:00 2001 From: "prompt.ac/@jeffrey" Date: Sun, 5 Apr 2026 21:34:49 -0700 Subject: [PATCH] =?UTF-8?q?fix:=20nix=20usb=20boot=20improvements=20?= =?UTF-8?q?=E2=80=94=20silent=20boot,=20cursor,=20shutdown,=20mic?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Continuing from 2acb823e7 which enabled wifi/sound/kidlisp on nix: NixOS boot: - Switch GRUB → systemd-boot (cut loader from 2min to ~55s) - EFI-only partition table (no BIOS boot, fixes ThinkPad 11e) - Silent boot: console=tty2, quiet, initrd.verbose=false - Filter build/ dir from nix source (device nodes crash nix eval) ac-native (C): - Hide Wayland cursor via wl_pointer_set_cursor(NULL) on enter - Use systemctl poweroff/reboot when not PID 1 (fixes "failed to execute shutdown binary" under systemd) - Aggressive mic compressor: threshold 0.15 (was 0.5), ratio 12:1 (was 4:1), hard limiter at 0.9 to prevent clipping Kiosk service: - Add ALSA_CONFIG_PATH for NixOS alsa-lib store path - WLR_NO_HARDWARE_CURSORS + XCURSOR_SIZE=1 env vars - Quieter kernel params in base configuration Co-Authored-By: Claude Opus 4.6 (1M context) --- fedac/native/src/ac-native.c | 45 ++++++++++++++++++++++++----------- fedac/native/src/audio.c | 20 ++++++++++------ fedac/native/src/input.c | 4 +++- fedac/nixos/configuration.nix | 6 +---- fedac/nixos/flake.nix | 5 +++- fedac/nixos/modules/image.nix | 31 ++++++++++++++---------- fedac/nixos/modules/kiosk.nix | 3 +++ 7 files changed, 74 insertions(+), 40 deletions(-) diff --git a/fedac/native/src/ac-native.c b/fedac/native/src/ac-native.c index 09bbdbbb18..cf09f9f30e 100644 --- a/fedac/native/src/ac-native.c +++ b/fedac/native/src/ac-native.c @@ -148,6 +148,31 @@ static void sigterm_handler(int sig) { poweroff_requested = 1; } +// Shutdown/reboot that works both as PID 1 (bare metal) and under systemd (NixOS). +static void ac_poweroff(void) { + sync(); + usleep(500000); + sync(); + if (getpid() == 1) { + reboot(LINUX_REBOOT_CMD_POWER_OFF); + } else { + system("systemctl poweroff"); + _exit(0); + } +} + +static void ac_reboot(void) { + sync(); + usleep(500000); + sync(); + if (getpid() == 1) { + reboot(LINUX_REBOOT_CMD_RESTART); + } else { + system("systemctl reboot"); + _exit(2); + } +} + static void signal_handler(int sig) { running = 0; @@ -2091,7 +2116,7 @@ int main(int argc, char *argv[]) { // Write diagnostics to USB too system("cat /proc/cmdline >> /mnt/ac-init.log 2>/dev/null"); system("dmesg 2>/dev/null | grep -i 'drm\\|i915\\|display' >> /mnt/ac-init.log 2>/dev/null"); - if (getpid() == 1) { sleep(30); reboot(LINUX_REBOOT_CMD_POWER_OFF); } + sleep(30); ac_poweroff(); return 1; } @@ -2252,10 +2277,7 @@ int main(int argc, char *argv[]) { audio_shutdown_sound(audio); usleep(500000); sync(); - // sysrq reboot (reliable under initramfs) - FILE *sr = fopen("/proc/sysrq-trigger", "w"); - if (sr) { fputs("b", sr); fclose(sr); } - reboot(LINUX_REBOOT_CMD_RESTART); + ac_reboot(); while (running) sleep(1); } } @@ -2395,7 +2417,7 @@ int main(int argc, char *argv[]) { if (display) drm_destroy(display); if (logfile) { fclose(logfile); logfile = NULL; } sync(); - if (getpid() == 1) reboot(LINUX_REBOOT_CMD_POWER_OFF); + ac_poweroff(); return 1; } @@ -2603,14 +2625,12 @@ int main(int argc, char *argv[]) { if (reboot_requested) { ac_log("[cage-transition] Reboot requested by cage child\n"); ac_log_flush(); - sync(); usleep(500000); sync(); - reboot(LINUX_REBOOT_CMD_RESTART); + ac_reboot(); } if (poweroff_requested) { ac_log("[cage-transition] Poweroff requested by cage child\n"); ac_log_flush(); - sync(); usleep(500000); sync(); - reboot(LINUX_REBOOT_CMD_POWER_OFF); + ac_poweroff(); } // Reclaim DRM and continue in DRM mode (fallback) @@ -3494,10 +3514,7 @@ int main(int argc, char *argv[]) { fb_destroy(screen); if (display) drm_destroy(display); - if (getpid() == 1) { - sync(); - reboot(LINUX_REBOOT_CMD_POWER_OFF); - } + ac_poweroff(); return 0; } diff --git a/fedac/native/src/audio.c b/fedac/native/src/audio.c index 48377e5085..c13f8959c2 100644 --- a/fedac/native/src/audio.c +++ b/fedac/native/src/audio.c @@ -1211,13 +1211,15 @@ static void *capture_thread_func(void *arg) { } float peak = 0.0f; - // Simple compressor: track envelope, apply gain reduction + // Aggressive compressor + hard limiter to prevent clipping. + // Matches the note compression style in the synth output. static float env = 0.0f; // envelope follower static float comp_gain = 1.0f; // current gain - const float threshold = 0.5f; // compress above this - const float ratio = 4.0f; // 4:1 compression - const float attack = 0.002f; // fast attack - const float release = 0.0001f; // slow release + const float threshold = 0.15f; // compress early (mic input is often hot) + const float ratio = 12.0f; // aggressive compression + const float attack = 0.005f; // fast attack + const float release = 0.00005f; // slow release (smooth) + const float limiter = 0.9f; // hard limiter ceiling for (int s = 0; s < n; s++) { float sample; @@ -1240,11 +1242,15 @@ static void *capture_thread_func(void *arg) { float reduced = threshold + over / ratio; comp_gain = reduced / env; } else { - // Slowly return to unity - comp_gain += 0.0001f * (1.0f - comp_gain); + comp_gain += 0.0002f * (1.0f - comp_gain); } sample *= comp_gain; + + // Hard limiter — prevent any clipping + if (sample > limiter) sample = limiter; + else if (sample < -limiter) sample = -limiter; + if (abs_s > peak) peak = abs_s; // Always write to ring buffer diff --git a/fedac/native/src/input.c b/fedac/native/src/input.c index 8f49532fff..ab15ac8900 100644 --- a/fedac/native/src/input.c +++ b/fedac/native/src/input.c @@ -906,10 +906,12 @@ static const struct wl_keyboard_listener keyboard_listener = { // Wayland pointer listener static void wl_pointer_enter(void *data, struct wl_pointer *ptr, uint32_t serial, struct wl_surface *surface, wl_fixed_t sx, wl_fixed_t sy) { - (void)ptr; (void)serial; (void)surface; + (void)surface; ACInput *input = data; input->pointer_x = wl_fixed_to_int(sx); input->pointer_y = wl_fixed_to_int(sy); + // Hide the Wayland compositor cursor — ac-native renders its own. + wl_pointer_set_cursor(ptr, serial, NULL, 0, 0); } static void wl_pointer_leave(void *data, struct wl_pointer *ptr, uint32_t serial, diff --git a/fedac/nixos/configuration.nix b/fedac/nixos/configuration.nix index 2eb0bcbd49..fa3dde1215 100644 --- a/fedac/nixos/configuration.nix +++ b/fedac/nixos/configuration.nix @@ -19,13 +19,9 @@ in boot.loader.grub.timeoutStyle = lib.mkDefault "menu"; boot.kernelPackages = pkgs.linuxPackages_latest; boot.kernelParams = [ - "loglevel=7" - "systemd.show_status=1" - "rd.systemd.show_status=1" - "udev.log_priority=info" "consoleblank=0" ]; - boot.consoleLogLevel = 7; + boot.consoleLogLevel = 0; # Minimal system — no desktop, no SSH, no docs documentation.enable = false; diff --git a/fedac/nixos/flake.nix b/fedac/nixos/flake.nix index e63ca394f5..6bd84438e5 100644 --- a/fedac/nixos/flake.nix +++ b/fedac/nixos/flake.nix @@ -18,6 +18,9 @@ builtins.path { path = nativeSrcPath; name = "ac-native-source"; + # Exclude build artifacts (device nodes in initramfs-root/dev/ crash nix) + filter = path: type: + !(lib.hasInfix "/build/" (toString path)); } else throw "AC_NIX_NATIVE_SRC is required for fedac/nixos builds; run nix with --impure and point it at fedac/native."; @@ -60,7 +63,7 @@ config = imageSystem.config; format = "raw"; onlyNixStore = false; - partitionTableType = "hybrid"; + partitionTableType = "efi"; installBootLoader = true; touchEFIVars = false; copyChannel = false; diff --git a/fedac/nixos/modules/image.nix b/fedac/nixos/modules/image.nix index b3507a8e87..2c2bb605bd 100644 --- a/fedac/nixos/modules/image.nix +++ b/fedac/nixos/modules/image.nix @@ -1,22 +1,29 @@ { lib, ... }: { - # Raw disk image builds need a full installed bootloader, not the live ISO path. - boot.loader.systemd-boot.enable = lib.mkForce false; + # Use systemd-boot for fast EFI boot (GRUB adds ~2min on USB drives). + boot.loader.systemd-boot.enable = lib.mkForce true; + boot.loader.grub.enable = lib.mkForce false; boot.loader.efi.canTouchEfiVariables = lib.mkForce false; - boot.loader.grub = { - enable = true; - devices = [ "/dev/vda" ]; - efiSupport = true; - efiInstallAsRemovable = true; - configurationLimit = 1; - }; boot.loader.timeout = lib.mkForce 0; - boot.loader.grub.timeoutStyle = lib.mkForce "hidden"; boot.growPartition = lib.mkDefault true; - # Make early boot text visible on the real display for debug + fallback boot paths. - boot.kernelParams = lib.mkAfter [ "console=tty0" ]; + # Quiet boot — suppress kernel/systemd text, go straight to ac-native. + # Suppress NixOS initrd "stage 1" / "stage 2" banners + boot.initrd.verbose = false; + + # Silent boot: send all kernel/initrd/systemd output to tty2 (invisible). + # tty1 stays black until cage takes over with ac-native. + boot.kernelParams = lib.mkAfter [ + "console=tty2" + "quiet" + "loglevel=0" + "rd.systemd.show_status=false" + "systemd.show_status=false" + "vt.global_cursor_default=0" + "splash" + ]; + boot.consoleLogLevel = lib.mkForce 0; # Match nixpkgs raw-disk expectations so the installed image can boot on # real hardware and expand cleanly after flashing. diff --git a/fedac/nixos/modules/kiosk.nix b/fedac/nixos/modules/kiosk.nix index 45689519c5..aa3b88fe16 100644 --- a/fedac/nixos/modules/kiosk.nix +++ b/fedac/nixos/modules/kiosk.nix @@ -125,6 +125,9 @@ in SSL_CERT_FILE = "${pkgs.cacert}/etc/ssl/certs/ca-bundle.crt"; ALSA_PLUGIN_DIR = "${pkgs.alsa-plugins}/lib/alsa-lib"; ALSA_CONFIG_PATH = "${pkgs.alsa-lib}/share/alsa/alsa.conf"; + # Hide the Wayland compositor cursor — ac-native renders its own. + WLR_NO_HARDWARE_CURSORS = "1"; + XCURSOR_SIZE = "1"; }; serviceConfig = { -- knotmirror 0.0.1