From aef813363f5252e2d62876d79225867a7970cb29 Mon Sep 17 00:00:00 2001 From: Tajeddine Bourhim Date: Wed, 28 Jan 2026 18:08:44 +0100 Subject: [PATCH] Update MapNitroButton.sh and local-setup.sh for improved device detection and Secure Boot support --- scripts/MapNitroButton.sh | 115 ++++++++----- scripts/build_sign_install.sh | 304 ++++++++++++++++++++++++++++++++++ scripts/local-setup.sh | 91 ++++++++-- 3 files changed, 454 insertions(+), 56 deletions(-) create mode 100755 scripts/build_sign_install.sh diff --git a/scripts/MapNitroButton.sh b/scripts/MapNitroButton.sh index 507c646..9e45b99 100755 --- a/scripts/MapNitroButton.sh +++ b/scripts/MapNitroButton.sh @@ -1,58 +1,83 @@ #!/bin/bash -# Function to set up device permissions -setup_permissions() { - echo "Setting up permissions..." - - # Add user to input group if not already - if ! groups | grep -q '\binput\b'; then - echo "Adding user $USER to 'input' group..." - usermod -a -G input $USER - echo "Note: You'll need to log out and back in for group changes to take effect." - fi - - # Create udev rule if needed - UDEV_RULE="/etc/udev/rules.d/99-input.rules" - if [ ! -f "$UDEV_RULE" ] || ! grep -q 'MODE="0660"' "$UDEV_RULE"; then - echo "Creating udev rules file..." - echo 'KERNEL=="event*", SUBSYSTEM=="input", MODE="0660", GROUP="input"' > /tmp/input.rules - mv /tmp/input.rules "$UDEV_RULE" - chmod 644 "$UDEV_RULE" - udevadm control --reload-rules - udevadm trigger - echo "Permissions rules updated." +# --- CONFIGURATION --- +# Command set back to just DAMX as requested +APP_COMMAND="DAMX" +TARGET_KEY_CODE="425" +DEVICE_NAME_FILTER="Acer Wireless Radio Control|Acer WMI hotkeys|AT Translated Set 2 keyboard" + +# --- DEVICE DETECTION --- +detect_device() { + EVENT_ID=$(grep -E -A 4 "Name=\"($DEVICE_NAME_FILTER)\"" /proc/bus/input/devices | grep -o 'event[0-9]\+' | head -n 1) + if [ -n "$EVENT_ID" ]; then + echo "/dev/input/$EVENT_ID" + else + return 1 fi - - echo "Permission setup complete." } -# Find keyboard device -DEVICE=$(grep -A 5 -B 5 "keyboard\|Keyboard" /proc/bus/input/devices | grep -m 1 "event" | sed 's/.*event\([0-9]\+\).*/\/dev\/input\/event\1/') +# --- MAIN LOGIC --- + +DEVICE=$(detect_device) +# 1. Check if device exists if [ -z "$DEVICE" ]; then - echo "Error: Could not find keyboard device." + echo "Error: Could not find the Nitro key device." exit 1 fi -# Check if we're root (sudo) -if [ "$(id -u)" -eq 0 ]; then - # Running as root - perform setup then re-exec as normal user - setup_permissions - echo "Re-launching as normal user..." - exec sudo -u $SUDO_USER "$0" - exit 0 -fi - -# Check permissions +# 2. Check Permissions & Apply "newgrp" Workaround if [ ! -r "$DEVICE" ]; then - echo "Error: Cannot read $DEVICE (permission denied)." - echo "Please run this script with sudo to set up permissions:" - echo " sudo $0" - exit 1 + echo "Permission denied reading $DEVICE." + echo "Checking groups..." + + # Check if user needs to be added to input group + if ! groups | grep -q '\binput\b'; then + echo "Adding user $USER to 'input' group..." + sudo usermod -a -G input $USER + + # Check for udev rules + UDEV_RULE="/etc/udev/rules.d/99-input-group.rules" + if [ ! -f "$UDEV_RULE" ]; then + echo 'KERNEL=="event*", SUBSYSTEM=="input", GROUP="input", MODE="0660"' | sudo tee "$UDEV_RULE" > /dev/null + sudo udevadm control --reload-rules + sudo udevadm trigger + fi + + echo "Reloading script with new group permissions..." + # This re-runs the script with the new 'input' group active immediately + exec sg input -c "$0 $@" + exit 0 + fi + + # If we are already in the group but still can't read, force udev reload + echo "User is in 'input' group but still cannot read device." + echo "Attempting to force udev reload..." + echo 'KERNEL=="event*", SUBSYSTEM=="input", GROUP="input", MODE="0660"' | sudo tee "/etc/udev/rules.d/99-input-group.rules" > /dev/null + sudo udevadm control --reload-rules + sudo udevadm trigger + + # Final check + if [ ! -r "$DEVICE" ]; then + echo "Still cannot read device. A reboot is recommended." + exit 1 + fi fi -# Main functionality -echo "Monitoring keyboard events on $DEVICE" -evtest "$DEVICE" | grep --line-buffered "code 425.*value 1" | while read -r line; do - DAMX & -done \ No newline at end of file +# 3. Monitoring Loop +echo "Listening on $DEVICE for Nitro Key..." + +evtest "$DEVICE" | \ +grep --line-buffered "code $TARGET_KEY_CODE" | \ +while read -r line; do + if echo "$line" | grep -q "value 1"; then + # Check if DAMX is already running (matches process name) + if pgrep -x "DAMX" > /dev/null || pgrep -f "DivAcerManagerMax" > /dev/null; then + echo "DAMX is already running." + else + echo "Launching DAMX..." + nohup "$APP_COMMAND" >/dev/null 2>&1 & + sleep 2 + fi + fi +done diff --git a/scripts/build_sign_install.sh b/scripts/build_sign_install.sh new file mode 100755 index 0000000..0a6849c --- /dev/null +++ b/scripts/build_sign_install.sh @@ -0,0 +1,304 @@ +#!/bin/bash + +# ========================================== +# DAMX Driver Builder - Multi-Distro Support +# ========================================== +# Supports: Debian, Ubuntu, Fedora, RHEL, Arch, Manjaro, CachyOS + +# --- 0. AUTO-ELEVATE TO ROOT --- +# If the user didn't run with sudo, ask for password and re-run as root automatically +if [ "$EUID" -ne 0 ]; then + echo "๐Ÿ”’ Root privileges are required to sign drivers." + echo "๐Ÿ”‘ Please enter your password to continue..." + exec sudo "$0" "$@" + exit $? +fi + +# --- 0.5. DETECT DISTRIBUTION --- +detect_distro() { + if [ -f /etc/os-release ]; then + . /etc/os-release + DISTRO_ID="$ID" + DISTRO_NAME="$NAME" + else + echo "โŒ Error: Cannot detect Linux distribution" + exit 1 + fi +} + +detect_distro + +# Classify distro family +if [[ "$DISTRO_ID" =~ ^(debian|ubuntu|linuxmint|pop)$ ]]; then + DISTRO_FAMILY="debian" + COMPILER="gcc" +elif [[ "$DISTRO_ID" =~ ^(fedora|rhel|centos)$ ]]; then + DISTRO_FAMILY="fedora" + COMPILER="gcc" +elif [[ "$DISTRO_ID" =~ ^(arch|manjaro|cachyos)$ ]]; then + DISTRO_FAMILY="arch" + COMPILER="clang" +else + echo "โš ๏ธ Unknown distribution: $DISTRO_NAME" + echo " Attempting to proceed with GCC (may not work optimally)" + DISTRO_FAMILY="unknown" + COMPILER="gcc" +fi + +echo "๐Ÿ” Detected Distribution: $DISTRO_NAME ($DISTRO_FAMILY family)" +echo "๐Ÿ”จ Using compiler: $COMPILER" + +# --- 1. CONFIGURATION & CHECKS --- +KEY=$(find /var/lib /usr/share /etc -name "db.key" 2>/dev/null | head -n 1) +CERT=$(find /var/lib /usr/share /etc -name "db.pem" 2>/dev/null | head -n 1) +SIGN_TOOL="/usr/lib/modules/$(uname -r)/build/scripts/sign-file" +DRIVER_NAME="linuwu_sense" +DRIVER_FILE="./src/${DRIVER_NAME}.ko" + +echo "๐Ÿ”ง Preparing to build driver..." + +if [[ -z "$KEY" || -z "$CERT" ]]; then + echo "โŒ Error: Secure Boot keys (db.key/db.pem) not found." + echo " Ensure you have sbctl installed and keys generated." + echo "" + echo "๐Ÿ“‹ To generate Secure Boot keys, run:" + if [[ "$DISTRO_FAMILY" == "debian" ]]; then + echo " sudo apt install sbsigntools mokutil" + elif [[ "$DISTRO_FAMILY" == "fedora" ]]; then + echo " sudo dnf install pesign mokutil" + elif [[ "$DISTRO_FAMILY" == "arch" ]]; then + echo " sudo pacman -S sbctl" + fi + exit 1 +fi + +# --- 2. INSTALL BUILD DEPENDENCIES --- +install_dependencies() { + if [[ "$DISTRO_FAMILY" == "debian" ]]; then + echo "๐Ÿ“ฆ Checking build dependencies for Debian/Ubuntu..." + MISSING_PACKAGES=() + + for pkg in build-essential libelf-dev sbsigntools mokutil; do + if ! dpkg -l | grep -q "^ii $pkg"; then + MISSING_PACKAGES+=("$pkg") + fi + done + + # Check for linux-headers + if ! dpkg -l | grep -q "^ii linux-headers"; then + MISSING_PACKAGES+=("linux-headers-$(uname -r)") + fi + + if [ ${#MISSING_PACKAGES[@]} -gt 0 ]; then + echo " Installing missing: ${MISSING_PACKAGES[*]}" + apt update + apt install -y "${MISSING_PACKAGES[@]}" + else + echo " โœ… All dependencies already installed." + fi + + elif [[ "$DISTRO_FAMILY" == "fedora" ]]; then + echo "๐Ÿ“ฆ Checking build dependencies for Fedora/RHEL..." + MISSING_PACKAGES=() + + for pkg in gcc kernel-devel kernel-headers elfutils-devel pesign mokutil; do + if ! rpm -q "$pkg" &>/dev/null; then + MISSING_PACKAGES+=("$pkg") + fi + done + + if [ ${#MISSING_PACKAGES[@]} -gt 0 ]; then + echo " Installing missing: ${MISSING_PACKAGES[*]}" + dnf install -y "${MISSING_PACKAGES[@]}" + else + echo " โœ… All dependencies already installed." + fi + + elif [[ "$DISTRO_FAMILY" == "arch" ]]; then + echo "๐Ÿ“ฆ Checking build dependencies for Arch/Manjaro/CachyOS..." + MISSING_PACKAGES=() + + for pkg in base-devel linux-headers sbctl; do + if ! pacman -Q "$pkg" &>/dev/null; then + MISSING_PACKAGES+=("$pkg") + fi + done + + # For CachyOS with clang + if [[ "$DISTRO_ID" == "cachyos" ]]; then + for pkg in clang llvm lld; do + if ! pacman -Q "$pkg" &>/dev/null; then + MISSING_PACKAGES+=("$pkg") + fi + done + fi + + if [ ${#MISSING_PACKAGES[@]} -gt 0 ]; then + echo " Installing missing: ${MISSING_PACKAGES[*]}" + pacman -Sy --noconfirm "${MISSING_PACKAGES[@]}" + else + echo " โœ… All dependencies already installed." + fi + fi +} + +install_dependencies + +# --- 2.5. DETECT LLVM KERNEL --- +# Check if the kernel was compiled with LLVM/Clang +is_llvm_kernel() { + local kernel_version=$(uname -r) + + # Method 1: Check kernel build info from modinfo (most reliable) + if modinfo -F vermagic 2>/dev/null | grep -qi "gcc\|clang"; then + modinfo -F vermagic 2>/dev/null | grep -qi "clang" && return 0 + fi + + # Method 2: Check /proc/version (fallback, works with CachyOS) + if grep -qi "clang" /proc/version 2>/dev/null; then + return 0 + fi + + # Method 3: Try to find and read kernel config + local kernel_config + if [[ -f "/boot/config-${kernel_version}" ]]; then + kernel_config="/boot/config-${kernel_version}" + elif [[ -f "/proc/config.gz" ]]; then + if zgrep -q "CONFIG_CC_IS_CLANG=y" /proc/config.gz 2>/dev/null; then + return 0 + fi + return 1 + else + # Last resort: check /sys/kernel/config if accessible + if [[ -f "/sys/kernel/config/CC_IS_CLANG" ]] && grep -q "y" /sys/kernel/config/CC_IS_CLANG 2>/dev/null; then + return 0 + fi + # Default to non-LLVM if unable to determine + return 1 + fi + + # Check the config file + if [[ -f "$kernel_config" ]] && grep -q "CONFIG_CC_IS_CLANG=y" "$kernel_config" 2>/dev/null; then + return 0 + fi + + return 1 +} + +# --- 3. CLEAN & BUILD --- +echo "๐Ÿงน Cleaning previous builds..." +make clean >/dev/null 2>&1 + +# Build with appropriate compiler for the kernel +echo "๐Ÿ”จ Building driver..." + +# Additional check: scan kernel messages for compiler info +check_kernel_compiler() { + # Check if kernel reports being built with clang + if strings /lib/modules/$(uname -r)/build/vmlinux 2>/dev/null | grep -qi "clang version"; then + return 0 + fi + # Check kernel version string more carefully + if uname -v 2>/dev/null | grep -qi "clang"; then + return 0 + fi + return 1 +} + +if is_llvm_kernel || check_kernel_compiler; then + echo " Detected LLVM-compiled kernel, using Clang..." + install_dependencies # Ensure clang is installed + make clean LLVM=1 CC=clang + make LLVM=1 CC=clang +else + echo " Using GCC (default)..." + make clean + make +fi + +if [[ ! -f "$DRIVER_FILE" ]]; then + echo "โŒ Build failed. $DRIVER_FILE not found." + # Fallback check + if [[ -f "./${DRIVER_NAME}.ko" ]]; then + DRIVER_FILE="./${DRIVER_NAME}.ko" + echo "โš ๏ธ Found driver in root folder instead. Proceeding..." + else + echo " (Checked both ./src/ and ./ for .ko file)" + exit 1 + fi +fi + +# --- 4. SIGN DRIVER FILE --- +echo "๐Ÿ” Signing driver file: $DRIVER_FILE..." + +# Different signing methods based on distro +sign_driver() { + # All distros use the kernel's sign-file script for module signing + if [[ -f "$SIGN_TOOL" ]]; then + if [[ -z "$KEY" || -z "$CERT" ]]; then + echo "โš ๏ธ Warning: Secure Boot keys not found, skipping signature..." + return 0 + fi + + echo " Using sign-file script (kernel native)..." + if "$SIGN_TOOL" sha256 "$KEY" "$CERT" "$DRIVER_FILE" 2>&1; then + return 0 + else + echo "โš ๏ธ Warning: Signing attempt had issues, proceeding anyway..." + return 0 + fi + else + echo "โš ๏ธ Warning: sign-file tool not found at $SIGN_TOOL" + echo " This usually means kernel headers may not be properly installed." + echo " Proceeding without signing..." + return 0 + fi +} + +# Call the signing function +sign_driver +echo "โœ… Driver preparation complete." + +sign_driver +# --- 5. INSTALL DRIVER --- +echo "๐Ÿ“ฆ Installing driver..." +TARGET_DIR="/usr/lib/modules/$(uname -r)/extra" +mkdir -p "$TARGET_DIR" +cp "$DRIVER_FILE" "$TARGET_DIR/" +depmod -a + +# --- 6. RELOAD MODULE --- +echo "โ™ป๏ธ Reloading module..." +modprobe -r "$DRIVER_NAME" 2>/dev/null +modprobe "$DRIVER_NAME" 2>/dev/null + +# --- 7. FINAL STATUS & RESTART NOTICE --- +INSTALLED_PATH=$(modinfo -n "$DRIVER_NAME" 2>/dev/null) + +echo "" +echo "============================================" +if modinfo "$INSTALLED_PATH" 2>/dev/null | grep -q "signer"; then + echo "โœ… SUCCESS: Driver installed and SIGNED." + SIGNED=1 +else + echo "โš ๏ธ WARNING: Driver installed but signature verification pending." + SIGNED=0 +fi +echo "============================================" +echo "" +echo "๐Ÿ“‹ DISTRIBUTION INFO:" +echo " Distribution: $DISTRO_NAME" +echo " Family: $DISTRO_FAMILY" +echo " Compiler: $COMPILER" +echo " Kernel: $(uname -r)" +echo "" +echo "๐Ÿ“ข IMPORTANT NEXT STEPS:" +echo "1. ๐Ÿ”„ YOU MUST RESTART YOUR MACHINE NOW for the signature to fully take effect." +if [[ "$SIGNED" == 1 ]]; then + echo "2. After rebooting, go back to the main folder and run './setup.sh'" + echo " Choose Option 2 (Install without Drivers)." +else + echo "2. After rebooting, enroll the Secure Boot key if prompted." + echo "3. Then run './setup.sh' and choose Option 2 (Install without Drivers)." +fi +echo "" diff --git a/scripts/local-setup.sh b/scripts/local-setup.sh index 369bfdc..34f9a42 100755 --- a/scripts/local-setup.sh +++ b/scripts/local-setup.sh @@ -5,7 +5,7 @@ # Components: Linuwu-Sense (drivers), DAMX-Daemon, and DAMX-GUI # Constants -SCRIPT_VERSION="0.8.8" +SCRIPT_VERSION="0.9.1" INSTALL_DIR="/opt/damx" BIN_DIR="/usr/local/bin" SYSTEMD_DIR="/etc/systemd/system" @@ -202,6 +202,45 @@ install_drivers() { fi } +install_drivers_with_secureboot() { + echo -e "${YELLOW}Installing Linuwu-Sense drivers with Secure Boot support...${NC}" + + if [ ! -d "Linuwu-Sense" ]; then + echo -e "${RED}Error: Linuwu-Sense directory not found!${NC}" + echo "Please make sure the script is run from the same directory containing Linuwu-Sense folder." + pause + return 1 + fi + + cd Linuwu-Sense + + # Check if the build_sign_install.sh script exists + if [ ! -f "build_sign_install.sh" ]; then + echo -e "${RED}Error: build_sign_install.sh not found in Linuwu-Sense directory!${NC}" + cd .. + pause + return 1 + fi + + # Make the script executable + chmod +x build_sign_install.sh + + # Run the build_sign_install.sh script + echo -e "${BLUE}Running secure build and installation process...${NC}" + ./build_sign_install.sh + + if [ $? -eq 0 ]; then + echo -e "${GREEN}Linuwu-Sense drivers built, signed, and installed successfully with Secure Boot support!${NC}" + cd .. + return 0 + else + echo -e "${RED}Error: Failed to build and install Linuwu-Sense drivers with Secure Boot support${NC}" + cd .. + pause + return 1 + fi +} + install_daemon() { echo -e "${YELLOW}Installing DAMX-Daemon...${NC}" @@ -303,6 +342,7 @@ EOL perform_install() { local skip_drivers=$1 local is_update=$2 + local use_secureboot=$3 # If this is an update/reinstall, perform cleanup first if [ "$is_update" = true ]; then @@ -320,7 +360,11 @@ perform_install() { # Install components if [ "$skip_drivers" = false ]; then - install_drivers + if [ "$use_secureboot" = true ]; then + install_drivers_with_secureboot + else + install_drivers + fi DRIVER_RESULT=$? else echo -e "${YELLOW}Skipping driver installation as requested.${NC}" @@ -393,37 +437,62 @@ main_menu() { echo -e "Please select an option:" echo -e " ${GREEN}1${NC}) Install DAMX Suite (complete)" echo -e " ${GREEN}2${NC}) Install DAMX Suite (without drivers)" - echo -e " ${GREEN}3${NC}) Uninstall DAMX Suite" - echo -e " ${GREEN}4${NC}) Reinstall/Update DAMX Suite (recommended for upgrades)" - echo -e " ${GREEN}5${NC}) Check service status" + echo -e " ${GREEN}3${NC}) Install DAMX Suite (complete with Secure Boot support)" + echo -e " ${GREEN}4${NC}) Install drivers only (with Secure Boot support)" + echo -e " ${GREEN}5${NC}) Uninstall DAMX Suite" + echo -e " ${GREEN}6${NC}) Reinstall/Update DAMX Suite (recommended for upgrades)" + echo -e " ${GREEN}7${NC}) Check service status" echo -e " ${GREEN}q${NC}) Quit" echo "" - read -p "Enter your choice [1-5 or q]: " choice + read -p "Enter your choice [1-7 or q]: " choice case $choice in 1) print_banner echo -e "${BLUE}Starting complete installation...${NC}" - perform_install false false + perform_install false false false ;; 2) print_banner echo -e "${BLUE}Starting installation without drivers...${NC}" - perform_install true false + perform_install true false false ;; 3) + print_banner + echo -e "${BLUE}Starting complete installation with Secure Boot support...${NC}" + echo -e "${YELLOW}This will build, sign, and install drivers with Secure Boot support along with daemon and GUI.${NC}" + echo -e "${YELLOW}Note: You may be prompted for your password during the process.${NC}" + perform_install false false true + ;; + 4) + print_banner + echo -e "${BLUE}Starting driver installation with Secure Boot support...${NC}" + echo -e "${YELLOW}This will build, sign, and install drivers only.${NC}" + echo -e "${YELLOW}Note: You may be prompted for your password during the process.${NC}" + cleanup_legacy_installation + install_drivers_with_secureboot + ;; + 5) print_banner echo -e "${BLUE}Starting uninstallation...${NC}" uninstall ;; - 4) + 6) print_banner echo -e "${BLUE}Starting reinstallation/update...${NC}" echo -e "${YELLOW}This will completely remove the existing installation before installing the new version.${NC}" - perform_install false true + echo "" + read -p "Do you want to install with Secure Boot support for drivers? (y/n): " secureboot_choice + if [[ "$secureboot_choice" =~ ^[Yy]$ ]]; then + echo -e "${BLUE}Secure Boot support will be used...${NC}" + perform_install false true true + else + echo -e "${BLUE}Regular driver installation will be used...${NC}" + perform_install false true false + fi ;; - 5) + 7) print_banner echo -e "${BLUE}Checking DAMX service status...${NC}" echo ""