diff --git a/modules/bullseye/extras.sh b/modules/bullseye/extras.sh index 14c87f1..9b5962e 100644 --- a/modules/bullseye/extras.sh +++ b/modules/bullseye/extras.sh @@ -49,6 +49,7 @@ Instalar?"; then "Installing firmware-linux-nonfree..." echo -e "${GREEN}Firmware installed.${NC}" fi + type _handle_wireless &>/dev/null && _handle_wireless } # ====================================================================== diff --git a/modules/firmware.sh b/modules/firmware.sh index ce2855d..c662098 100644 --- a/modules/firmware.sh +++ b/modules/firmware.sh @@ -1,9 +1,235 @@ #!/usr/bin/env bash +# ── Global arrays ── +PCI_NET_DEVS=() +USB_WIFI_DEVS=() +_DETECTED_FW_PKGS=() +_FW_PLAN_HW_LINES=() +_FW_PLAN_PKG_LINES=() + +# ── Network device detection (PCI + USB) ── +_detect_all_network_devices() { + ! is_installed pciutils && _run_install_pkg pciutils + ! is_installed usbutils && _run_install_pkg usbutils + + PCI_NET_DEVS=() + while IFS= read -r line; do + PCI_NET_DEVS+=("$line") + done < <(lspci -nn 2>/dev/null | grep -iE 'network controller|ethernet controller' || true) + + USB_WIFI_DEVS=() + while IFS= read -r line; do + if echo "$line" | grep -qiE 'wireless|wifi|802\.11|bluetooth|wlan'; then + USB_WIFI_DEVS+=("$line") + fi + done < <(lsusb 2>/dev/null || true) + + _FW_PLAN_HW_LINES=() + for dev in "${PCI_NET_DEVS[@]}"; do + local desc dev_type + desc=$(echo "$dev" | sed -E 's/^[^ ]+ [^:]+: //; s/ \[[0-9a-fA-F]{4}:[0-9a-fA-F]{4}\]//; s/ \(rev.*\)//') + if echo "$dev" | grep -qiE 'network controller|wireless|wi-fi|wlan|802\.11'; then + dev_type="WiFi PCI" + else + dev_type="Ethernet PCI" + fi + _FW_PLAN_HW_LINES+=(" \xe2\x97\x8f ${desc} (${dev_type})") + done + for dev in "${USB_WIFI_DEVS[@]}"; do + local desc + desc=$(echo "$dev" | sed 's/^.*ID //') + _FW_PLAN_HW_LINES+=(" \xe2\x97\x8f ${desc} (USB)") + + done +} + +# ── Firmware package mapping ── +_detect_firmware_needs() { + local -A pkg_info + _DETECTED_FW_PKGS=() + _FW_PLAN_PKG_LINES=() + + local dev_list + dev_list=("${PCI_NET_DEVS[@]}" "${USB_WIFI_DEVS[@]}") + + for dev in "${dev_list[@]}"; do + local raw_desc vendor_lc pkg + raw_desc=$(echo "$dev" | sed -E 's/^[^ ]+ [^:]+: //; s/ \[[0-9a-fA-F]{4}:[0-9a-fA-F]{4}\]//; s/ \(rev.*\)//') + vendor_lc=$(echo "$dev" | sed -n 's/^.*]: //p' | awk '{print $1}' | tr '[:upper:]' '[:lower:]') + + [[ "$vendor_lc" != *intel* && "$vendor_lc" != *realtek* && "$vendor_lc" != *atheros* && "$vendor_lc" != *qualcomm* && "$vendor_lc" != *mediatek* ]] && continue + + case "$vendor_lc" in + *intel*) + if echo "$dev" | grep -qiE 'wireless|wi-fi|wlan|802\.11'; then + pkg="firmware-iwlwifi" + else + pkg="firmware-intel-misc" + fi + ;; + *realtek*) pkg="firmware-realtek" ;; + *atheros*|*qualcomm*) pkg="firmware-atheros" ;; + *mediatek*) pkg="firmware-mediatek" ;; + esac + + local short_dev + short_dev=$(echo "$raw_desc" | sed 's/ *\[[^]]*\]//g; s/ */ /g') + if [ -z "${pkg_info[$pkg]-}" ]; then + pkg_info[$pkg]="$short_dev" + else + pkg_info[$pkg]+=", $short_dev" + fi + done + + for pkg in "${!pkg_info[@]}"; do + _DETECTED_FW_PKGS+=("$pkg") + _FW_PLAN_PKG_LINES+=(" [+] ${pkg} \xe2\x86\x90 ${pkg_info[$pkg]}") + done + + mapfile -t _DETECTED_FW_PKGS < <(printf '%s\n' "${_DETECTED_FW_PKGS[@]}" | sort -u) +} + +# ── Broadcom chip classification helpers ── +_is_broadcom_brcm() { + local id="$1" + for supported in 4357 4358 4360 4727 43a0 43a1 43a2 43b1; do + [ "$id" = "$supported" ] && return 0 + done + return 1 +} + +_is_broadcom_b43() { + local id="$1" + _is_broadcom_brcm "$id" && return 1 + local dec=$((16#$id)) + if [ "$dec" -ge $((16#4301)) ] && [ "$dec" -le $((16#4331)) ]; then return 0; fi + if [ "$dec" -ge $((16#4336)) ] && [ "$dec" -le $((16#4338)) ]; then return 0; fi + case "$id" in 4352|4357|4358|4360|4727) return 0 ;; esac + return 1 +} + +_is_broadcom_b43legacy() { + [ "$1" = "4302" ] || [ "$1" = "4306" ] +} + +# ── Build plan string ── +_build_firmware_plan() { + local plan="" + plan+="This section installs the essential non-free firmware stack\n" + plan+="for Debian (including CPU microcode, GPU, network, and core\n" + plan+="drivers). The script has scanned your hardware to prepare\n" + plan+="the setup:\n\n" + + plan+="Detected controllers:\n" + if [ ${#_FW_PLAN_HW_LINES[@]} -eq 0 ]; then + plan+=" (none detected)\n" + else + for line in "${_FW_PLAN_HW_LINES[@]}"; do + plan+="${line}\n" + done + fi + + plan+="\nPlanned firmware packages:\n" + local fw_line + if is_installed firmware-linux-nonfree; then + local cur_ver + cur_ver=$(dpkg -l firmware-linux-nonfree 2>/dev/null | awk '/^ii/{print $3}') + fw_line=" [+] firmware-linux-nonfree ${cur_ver} (already installed)" + else + fw_line=" [+] firmware-linux-nonfree (base meta-package)" + fi + plan+="${fw_line}\n" + + for line in "${_FW_PLAN_PKG_LINES[@]}"; do + plan+="${line}\n" + done + + plan+="\nInstallation order:\n" + plan+=" 1. Base firmware (firmware-linux-nonfree)\n" + plan+=" 2. Network firmware (realtek, iwlwifi, ...)\n" + plan+=" 3. Broadcom wireless (if detected)\n" + + echo -e "$plan" +} + +# ── Install detected firmware packages ── +_install_detected_firmware() { + local to_install=() + for pkg in "${_DETECTED_FW_PKGS[@]}"; do + if is_installed "$pkg"; then + echo " --> $pkg already installed." + continue + fi + local ver + ver=$(apt-cache policy "$pkg" 2>/dev/null | awk 'NR==3 {print $2; exit}') + if [ -z "$ver" ] || [ "$ver" = "(none)" ]; then + echo " --> $pkg not available in repositories, skipping." + continue + fi + to_install+=("$pkg") + done + if [ ${#to_install[@]} -gt 0 ]; then + _run_cmd "Firmware" "sudo DEBIAN_FRONTEND=noninteractive apt install -y ${to_install[*]}" \ + "Installing network firmware packages..." + fi +} + +# ── Wireless handler (Broadcom 3-tier) ── +_handle_wireless() { + local installed_any=false + if [ ${#PCI_NET_DEVS[@]} -eq 0 ] && [ ${#USB_WIFI_DEVS[@]} -eq 0 ]; then + _detect_all_network_devices + fi + + for dev in "${PCI_NET_DEVS[@]}"; do + local bcm_id + bcm_id=$(echo "$dev" | grep -oP '14e4:[0-9a-fA-F]+' || true) + [ -z "$bcm_id" ] && continue + local dev_id + dev_id=$(echo "$bcm_id" | cut -d: -f2 | tr '[:upper:]' '[:lower:]') + + if _is_broadcom_brcm "$dev_id"; then + if ! is_installed "firmware-brcm80211"; then + _run_cmd "Broadcom" "sudo DEBIAN_FRONTEND=noninteractive apt install -y firmware-brcm80211" \ + "Installing firmware-brcm80211..." + else + echo " --> firmware-brcm80211 already installed." + fi + installed_any=true + elif _is_broadcom_b43 "$dev_id"; then + _run_install_pkg firmware-b43-installer + installed_any=true + elif _is_broadcom_b43legacy "$dev_id"; then + _run_install_pkg firmware-b43legacy-installer + installed_any=true + else + local bcm_ver header_ver + bcm_ver=$(apt-cache policy broadcom-sta-dkms 2>/dev/null | awk 'NR==3 {print $2; exit}') + header_ver=$(apt-cache policy linux-headers-$(uname -r) 2>/dev/null | awk 'NR==3 {print $2; exit}') + if _confirm "Broadcom WiFi" "Install Broadcom driver?\n\nRequired for this chipset. Compiles a kernel module.\n\n broadcom-sta-dkms ${bcm_ver:-unknown}\n linux-headers-$(uname -r) ${header_ver:-unknown}\n\nProceed?"; then + _run_cmd "Broadcom" "sudo DEBIAN_FRONTEND=noninteractive apt install -y linux-headers-$(uname -r) broadcom-sta-dkms" \ + "Installing Broadcom driver..." + echo "Broadcom proprietary driver installed. A reboot may be required." + installed_any=true + fi + fi + done + + for dev in "${USB_WIFI_DEVS[@]}"; do + if echo "$dev" | grep -qi '0a5c'; then + _msg "USB Broadcom" "USB Broadcom adapter detected:\n\n ${dev}\n\nIf the adapter is not recognized after base firmware\ninstallation, ndiswrapper may be needed as a last\nresort.\n\nNote: Linux 5.15+ has improved support for many\nUSB Broadcom adapters." 12 65 + fi + done + + if ! $installed_any; then + echo "No special WiFi firmware needed -- base firmware-linux-nonfree covers this system." + fi +} + +# ── Main entry point ── install_firmware() { echo -e "${YELLOW}Base firmware check...${NC}" - # ── Safeguard: non-free repos must be enabled ── if ! grep -qr "non-free" /etc/apt/sources.list /etc/apt/sources.list.d/ 2>/dev/null; then _msg "Error" "Error: No 'non-free' repositories were detected.\n\ Please first run the 'Configure repositories' option in the\n\ @@ -11,6 +237,22 @@ main menu to install proprietary firmwares." 10 65 return 1 fi + # 1. Detect + _detect_all_network_devices + _detect_firmware_needs + + # 2. Plan + local plan + plan=$(_build_firmware_plan) + _msg "Firmware & Wireless Setup" "$plan" 22 72 + + # 3. Confirm + if ! _confirm "Firmware" "Apply the network & firmware plan?"; then + echo "Firmware installation skipped." + return + fi + + # 4. Install base firmware meta-package (unchanged logic) local fw_pkg="firmware-linux-nonfree" local fw_bpo fw_bpo=$(apt-cache madison "$fw_pkg" 2>/dev/null | \ @@ -29,76 +271,38 @@ main menu to install proprietary firmwares." 10 65 else echo "$fw_pkg already installed." fi - handle_wifi_firmware - return - fi - - local msg="firmware-linux-nonfree provides hardware drivers for:\n" - msg+=" WiFi, Bluetooth, GPU, audio, webcams, and more.\n\n" - if [ -n "$fw_bpo" ]; then - msg+=" ● Stable: ${fw_stable}\n" - msg+=" Ultra tested, but may lack support for\n" - msg+=" very recent hardware.\n\n" - msg+=" ● Backports: ${fw_bpo} (Recommended)\n" - msg+=" Updated firmware for modern hardware from\n" - msg+=" 2025/2026: recent GPUs (Intel Arc, Radeon,\n" - msg+=" NVIDIA), new processors, Wi-Fi 6E / Wi-Fi 7.\n\n" - msg+="Choose version:" - if _confirm_custom "Firmware" "$msg" "Backports" "Stable"; then - _run_cmd "Firmware" "sudo apt install -y -t ${DEBIAN_CODENAME}-backports $fw_pkg" "Installing firmware from backports..." - else - _run_cmd "Firmware" "sudo apt install -y $fw_pkg" "Installing firmware from stable..." - fi else - msg+=" Version: ${fw_stable}\n\n" - msg+="Install it?" - if _confirm "Firmware" "$msg"; then - _run_cmd "Firmware" "sudo apt install -y $fw_pkg" "Installing firmware..." - fi - fi - - echo -e "${GREEN}Base firmware installed.${NC}" - handle_wifi_firmware -} - -# --------------------------- -# Specific WiFi firmware -# --------------------------- -handle_wifi_firmware() { - if [ -z "$WIFI_CHIPSET" ] || [ "$WIFI_CHIPSET" = "No WiFi adapter found" ]; then - echo "No WiFi adapter to configure." - return - fi - - echo "Detected WiFi: $WIFI_CHIPSET" - - # Broadcom IDs often start with 14e4: - local broadcom_id - broadcom_id=$(lspci -nn | grep -i network | grep -oP '14e4:[0-9a-fA-F]+' | head -n1) - if [ -n "$broadcom_id" ]; then - echo -e "${YELLOW}Broadcom wireless device found (ID: $broadcom_id)${NC}" - - # List of device IDs supported by brcmsmac/brcmfmac - local supported_ids="4357 4358 4360 4727 43a0 43a1 43a2 43b1" - local device_id - device_id=$(echo "$broadcom_id" | cut -d: -f2) - - if echo "$supported_ids" | grep -qw "$device_id"; then - _run_install_pkg firmware-brcm80211 - else - # Offer to install broadcom-sta-dkms for older chips - local bcm_ver - bcm_ver=$(apt-cache policy broadcom-sta-dkms 2>/dev/null | awk 'NR==3 {print $2; exit}') - local header_ver - header_ver=$(apt-cache policy linux-headers-$(uname -r) 2>/dev/null | awk 'NR==3 {print $2; exit}') - if _confirm "Broadcom WiFi" "Install Broadcom driver?\n\nRequired for this chipset. Compiles a kernel module.\n\n broadcom-sta-dkms ${bcm_ver:-unknown}\n linux-headers-$(uname -r) ${header_ver:-unknown}\n\nProceed?"; then - _run_cmd "Broadcom" "sudo apt install -y linux-headers-$(uname -r) broadcom-sta-dkms" "Installing Broadcom driver..." - echo "Broadcom proprietary driver installed. A reboot may be required." + local msg="firmware-linux-nonfree provides hardware drivers for:\n" + msg+=" WiFi, Bluetooth, GPU, audio, webcams, and more.\n\n" + if [ -n "$fw_bpo" ]; then + msg+=" ● Stable: ${fw_stable}\n" + msg+=" Ultra tested, but may lack support for\n" + msg+=" very recent hardware.\n\n" + msg+=" ● Backports: ${fw_bpo} (Recommended)\n" + msg+=" Updated firmware for modern hardware from\n" + msg+=" 2025/2026: recent GPUs, processors, WiFi.\n\n" + msg+="Choose version:" + if _confirm_custom "Firmware" "$msg" "Backports" "Stable"; then + _run_cmd "Firmware" "sudo apt install -y -t ${DEBIAN_CODENAME}-backports $fw_pkg" "Installing firmware from backports..." else - echo "Skipping Broadcom driver installation." + _run_cmd "Firmware" "sudo apt install -y $fw_pkg" "Installing firmware from stable..." + fi + else + msg+=" Version: ${fw_stable}\n\n" + msg+="Install it?" + if _confirm "Firmware" "$msg"; then + _run_cmd "Firmware" "sudo apt install -y $fw_pkg" "Installing firmware..." fi fi - else - echo "No special WiFi firmware needed for this adapter." + echo -e "${GREEN}Base firmware installed.${NC}" fi + + # 5. Install specific network firmware packages + _install_detected_firmware + + # 6. Broadcom wireless handler + _handle_wireless + + # 7. Summary + echo -e "${GREEN}Network & firmware setup complete.${NC}" } diff --git a/modules/gpu.sh b/modules/gpu.sh index d0334ee..c1c9a64 100644 --- a/modules/gpu.sh +++ b/modules/gpu.sh @@ -10,23 +10,6 @@ source "${_GPU_DIR}/nvidia.sh" NVIDIA_DRIVER_MODE="" install_gpu_drivers() { - local info="This section installs the latest Mesa graphics stack\n" - info+="from Debian backports (or stable), plus GPU firmware\n" - info+="and monitoring tools tailored to your hardware.\n\n" - info+="Components:\n" - info+=" Mesa (OpenGL / Vulkan / VA-API)\n" - if [ "$GPU_TYPE" != "unknown" ]; then - info+=" GPU firmware\n" - fi - info+=" Monitoring tools (nvtop, vainfo, ...)" - - _msg "Graphics Stack" "$info" 16 70 - - if ! _confirm "Graphics Stack" "Proceed with the graphics stack setup?"; then - echo "Skipping Graphics Stack." - return - fi - # ── Unknown GPU / VM block ── if [ "$GPU_TYPE" = "unknown" ] || [ -z "$GPU_TYPE" ]; then local mesa_pkgs=(mesa-vulkan-drivers libgl1-mesa-dri libglx-mesa0 libegl-mesa0 mesa-va-drivers) @@ -68,7 +51,9 @@ install_gpu_drivers() { fi # ── Detectable GPU: build plan ── - local plan="" + local plan="The script has automatically detected your graphics hardware\n" + plan+="and prepared a personalized installation plan.\n\n" + plan+="Detected GPUs:\n" local gpu_count=0 while IFS= read -r gpu_line; do gpu_count=$((gpu_count + 1)) @@ -76,7 +61,7 @@ install_gpu_drivers() { desc=$(echo "$gpu_line" | sed -E 's/.*: //; s/ *\(rev.*//') plan+=" GPU ${gpu_count}: ${desc}\n" done < <(lspci -nn | grep -E "VGA|3D" || true) - plan+="\nComponents:\n" + plan+="\nPlanned components:\n" if $HAS_INTEL; then local _gen; _gen=$(get_intel_generation) local _va; [ "$_gen" = "gen7-" ] && _va="i965-va-driver-shaders" || _va="intel-media-va-driver-non-free" @@ -86,13 +71,13 @@ install_gpu_drivers() { plan+=" [+] AMD firmware (firmware-amd-graphics)\n" fi if $HAS_NVIDIA; then - plan+=" [+] NVIDIA driver\n" + plan+=" [+] NVIDIA driver (proprietary)\n" fi plan+=" [+] Mesa (version selected in next step)\n" _msg "Graphics Stack — Plan" "$plan" 16 70 - if ! _confirm "Graphics Stack" "Install the components shown above?"; then + if ! _confirm "Graphics Stack" "Install the planned components?"; then echo "Skipping Graphics Stack." return fi diff --git a/modules/repos.sh b/modules/repos.sh index 0839fc7..708ea4e 100644 --- a/modules/repos.sh +++ b/modules/repos.sh @@ -275,11 +275,11 @@ configure_repos() { # ── Informational banner ── _msg "Repositories" \ -"This section will automatically enable the 'contrib' and 'non-free'\n\ -branches in your official Debian repositories. (The 'non-free-firmware'\n\ -branch is already enabled by default in Debian 12 and 13.)\n\n\ +"This section will automatically enable the 'contrib' and \n\ +'non-free' branches in your official Debian repositories. \n\ +(The 'non-free-firmware' branch is already enabled by default in Debian 12 and 13.)\n\n\ This is CRUCIAL for obtaining proprietary software packages and\n\ -essential hardware drivers, including NVIDIA graphics drivers,\n\ +essential hardware drivers, including graphics drivers,\n\ Wi-Fi firmware, and CPU microcode." 14 70 # Detect current state @@ -309,7 +309,7 @@ harm your system, and the script will handle the transition safely if you accept. NOTE: 'NO' (default) is recommended to maintain the classic -linear format as it comes pre-configured in Debian 13 (Trixie)." 14 70; then +linear format as it comes pre-configured in Debian 13 (Trixie)." 16 70; then use_deb822=true fi elif [ "$current_format" = "deb822" ]; then @@ -324,7 +324,7 @@ next Debian testing branch, recompiled to run stably on your\n\ current system.\n\n\ This is HIGHLY RECOMMENDED if you have modern hardware, as it\n\ delivers newer Linux Kernels, updated display drivers, and modern\n\ -Mesa versions without compromising overall system stability." 15 70; then +Mesa versions without compromising overall system stability." 16 70; then enable_backports=true fi