Reduce user prompts: firmware & graphics updates

- Rewrote `modules/firmware.sh` with unified detection and installation flow, reducing user interactions from multiple prompts to single confirmation across all hardware types.
- Enhanced `_detect_all_network_devices()` to scan full PCI device lists without truncation (`head -n1` removed) and filter USB devices by keyword patterns (`wireless`, `wifi`, `802.11`, `bluetooth`, `wlan`) to eliminate false positives from card readers/Realtek audio devices.
- Implemented Broadcom 3-tier firmware strategy: Tier 1 (`brcmsmac`, 8 device IDs) auto-installs without extra confirmation; Tier 2 (`b43`/`b43legacy`, ranges 0x4301–0x4331) requires contrib package warnings; Tier 3 (`broadcom-sta-dkms`) needs DKMS compilation approval with explicit precedence handling for overlapping device ID ranges.
- Streamlined `modules/gpu.sh` flow from 169 to 154 lines, cutting user clicks from 4 (intro → proceed → plan → install) to 2 (plan → install), removing redundant intro message before plan display while preserving Intel/AMD firmware auto-installation and Mesa prompting logic.
- Added Bullseye compatibility hook in `modules/bullseye/extras.sh` (`type _handle_wireless &>/dev/null && _handle_wireless`) to ensure Broadcom wireless handling works correctly in Debian 11 environment with lazy detection fallback for empty PCI network devices.
- Fixed whiptail UI spacing issues in message paragraphs for improved readability and standardized dialog geometry across firmware/graphics dialogs.
This commit is contained in:
stornic56
2026-06-17 15:57:07 -05:00
committed by GitHub
parent 3a652c28e6
commit 002a888b46
4 changed files with 285 additions and 95 deletions
+1
View File
@@ -49,6 +49,7 @@ Instalar?"; then
"Installing firmware-linux-nonfree..."
echo -e "${GREEN}Firmware installed.${NC}"
fi
type _handle_wireless &>/dev/null && _handle_wireless
}
# ======================================================================
+255 -51
View File
@@ -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,10 +271,7 @@ main menu to install proprietary firmwares." 10 65
else
echo "$fw_pkg already installed."
fi
handle_wifi_firmware
return
fi
else
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
@@ -41,8 +280,7 @@ main menu to install proprietary firmwares." 10 65
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+=" 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..."
@@ -56,49 +294,15 @@ main menu to install proprietary firmwares." 10 65
_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."
else
echo "Skipping Broadcom driver installation."
fi
fi
else
echo "No special WiFi firmware needed for this adapter."
fi
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}"
}
+6 -21
View File
@@ -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
+6 -6
View File
@@ -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