Administració de Sistemes Linux · Nivell Expert
Model de mòduls del kernel, DKMS, drivers propietaris vs lliures i procediment de troubleshooting documentat amb evidències reals.
Quan un SO detecta maquinari, el procés passa per diverses capes: bus de comunicació (USB, PCIe, I²C), subsistema d'enumeració del kernel i finalment el driver que parla el protocol del dispositiu. Linux detecta correctament la majoria de dispositius perquè el seu kernel inclou milers de mòduls, però hi ha escenaris en què la detecció falla:
linux-firmware no es pre-instal·la$ lsusb Bus 001 Device 003: ID 0bda:8179 Realtek Semiconductor Corp. RTL8188EUS 802.11n $ lspci -nn | grep -i net 03:00.0 Network controller [0280]: Intel Corporation Wi-Fi 6 AX200 [8086:2723] $ dmesg | grep -E "(usb|firmware|driver)" | tail -20 [ 3.142] usb 1-1: new high-speed USB device number 3 using xhci_hcd [ 3.298] usb 1-1: New USB device found, idVendor=0bda, idProduct=8179 [ 3.299] usb 1-1: 8179: could not find firmware rtl8188eufw.bin # → El kernel troba el VID:PID però no té el firmware associat
usb:v0BDAp8179). El dimoni udev llegeix aquest modalias i consulta la base de dades modules.alias per saber quin mòdul carregar. Si no hi ha cap entrada, el dispositiu queda sense driver.
$ cat /sys/bus/usb/devices/1-1/modalias usb:v0BDAp8179d0000dc00dsc00dp00icFFiscFFipFFin00 $ modprobe --resolve-alias usb:v0BDAp8179d0000dc00dsc00dp00icFFiscFFipFFin00 # Sense sortida = cap mòdul al kernel actual cobreix aquest modalias $ grep 8179 /lib/modules/$(uname -r)/modules.alias # Línia buida = confirmació que no hi ha mòdul registrat
| Dimensió | Driver lliure (GPL) | Driver propietari (blob) |
|---|---|---|
| Codi font | Auditable, contribuïble upstream | No disponible; caixa negra |
| Estabilitat del kernel | Alta; integrat a l'arbre oficial | Variable; depèn del vendor |
| Actualitzacions | Automàtiques amb el kernel | Manuals o via DKMS |
| Rendiment | Bo; optimitzat per la comunitat | Pot ser superior en GPU/WiFi |
| Seguretat | Auditoria pública; CVEs ràpids | Opac; CVEs lents o no publicats |
| Exemples típics | r8169, ath9k, brcmfmac |
NVIDIA, Broadcom WiFi, alguns Realtek |
r8188eu, nvidia, v4l2libusb, cups (impressores), sane (escàners).ko. Gestiona'l amb DKMS per automatitzar recompilacions.
/lib/firmware/). Instal·la linux-firmware o el paquet específic del vendor.
DKMS (Dynamic Kernel Module Support) és un framework que manté mòduls out-of-tree compilats i reinstal·lats automàticament quan el kernel s'actualitza. És essencial per a drivers propietaris o mòduls experimentals que no s'han fusionat a l'arbre principal.
/usr/src/
└── r8188eu-5.2.2.4/ ← Codi font del mòdul
├── dkms.conf ← Configuració DKMS
├── Makefile
└── *.c / *.h
/var/lib/dkms/
└── r8188eu/5.2.2.4/
├── source → /usr/src/r8188eu-5.2.2.4
└── 6.8.0-60-generic/ ← Binari compilat per cada kernel
└── x86_64/
└── module/
└── r8188eu.ko
PACKAGE_NAME="r8188eu"
PACKAGE_VERSION="5.2.2.4"
BUILT_MODULE_NAME[0]="r8188eu"
DEST_MODULE_LOCATION[0]="/kernel/drivers/net/wireless"
AUTOINSTALL="yes" # ← Recompila automàticament en update del kernel
# 1. Afegir el mòdul a DKMS # dkms add -m r8188eu -v 5.2.2.4 # 2. Compilar per al kernel actiu # dkms build -m r8188eu -v 5.2.2.4 # 3. Instal·lar # dkms install -m r8188eu -v 5.2.2.4 # 4. Verificar estat # dkms status r8188eu/5.2.2.4, 6.8.0-60-generic, x86_64: installed # 5. Comprovar que el mòdul és al directori del kernel $ modinfo r8188eu | grep -E "(filename|version|depends)" filename: /lib/modules/6.8.0-60-generic/updates/dkms/r8188eu.ko version: 5.2.2.4 depends: cfg80211
| Opció | Risc principal | Compromís | Recomanació |
|---|---|---|---|
| In-tree (mainline) | Cap risc addicional | Disponibilitat limitada a HW suportat | Preferent |
| DKMS out-of-tree | Incompatibilitat en ABI change; build fallida post-update | Manteniment manual si el vendor abandona | Acceptable |
| Driver propietari (DKMS) | Codi no auditable; pot tenir backdoors | Rendiment òptim (ex: NVIDIA) | Quan no hi ha alternativa |
| Módulo compilat manualment | No es re-instal·la automàticament; risc de kernel panic | Control total però molt fràgil | Evitar |
| Driver userspace (libusb) | Latència superior; possible limitació de funcions | Seguretat i portabilitat excel·lents | Ideal per perifèrics |
# Generar clau MOK (Machine Owner Key) # openssl req -new -x509 -newkey rsa:2048 -keyout /var/lib/shim-signed/mok/MOK.priv \ -out /var/lib/shim-signed/mok/MOK.der -days 36500 -subj "/CN=DKMS signing key/" # Importar la clau al firmware # mokutil --import /var/lib/shim-signed/mok/MOK.der input password: **** ← Contrasenya temporal per confirmar en el pròxim reinici # Configurar DKMS per signar automàticament # echo 'sign_tool="/etc/kernel/sign-modules"' >> /etc/dkms/framework.conf
Entorn: Ubuntu 24.04 LTS, kernel 6.8.0-60-generic. L'adaptador USB apareix a lsusb però no s'assigna cap interfície de xarxa. La xarxa sense fil no apareix ni a ip link ni a NetworkManager.
$ lsusb | grep Realtek Bus 001 Device 004: ID 0bda:8179 Realtek Semiconductor Corp. RTL8188EUS 802.11n $ ip link show 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 2: enp3s0: <BROADCAST,MULTICAST,UP> mtu 1500 # Sense cap interfície wlan → el mòdul no s'ha carregat $ dmesg | grep -i "8179\|8188\|rtl" [ 5.441] usb 1-1.4: could not find firmware rtl8188eufw.bin [ 5.442] r8188eu: probe of 1-1.4:1.0 failed with error -2 $ lsmod | grep r8188 # Sense sortida → mòdul no carregat
$ ls /lib/firmware/rtlwifi/rtl8188eufw.bin ls: no s'ha pogut accedir a '/lib/firmware/rtlwifi/rtl8188eufw.bin': No existeix $ dpkg -l | grep linux-firmware ii linux-firmware 20240909.git7ece246b-0ubuntu2 amd64 Firmware for Linux kernel drivers # El paquet és instal·lat però el firmware del RTL8188EUS no hi és inclòs en Ubuntu 24.04
# Prerequesits: headers del kernel actiu i DKMS # apt install -y dkms linux-headers-$(uname -r) git build-essential # Clonar el driver de la font oficial mantenida per la comunitat # git clone https://github.com/aircrack-ng/rtl8188eus /usr/src/r8188eu-5.3.9 # Afegir i compilar amb DKMS # dkms add -m r8188eu -v 5.3.9 Creating symlink /var/lib/dkms/r8188eu/5.3.9/source -> /usr/src/r8188eu-5.3.9 # dkms build -m r8188eu -v 5.3.9 Kernel preparation unnecessary for this kernel. Skipping... Building module: cleaning build area... make -j4 KERNELRELEASE=6.8.0-60-generic...... BUILD SUCCESSFUL # dkms install -m r8188eu -v 5.3.9 r8188eu.ko installed into /lib/modules/6.8.0-60-generic/updates/dkms/ # Bloquejar el mòdul antic (si hi fos) i carregar el nou # echo "blacklist r8188eu" > /etc/modprobe.d/blacklist-r8188eu-old.conf # modprobe r8188eu $ dkms status r8188eu/5.3.9, 6.8.0-60-generic, x86_64: installed
$ ip link show wlan0
3: wlan0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP
link/ether aa:bb:cc:dd:ee:ff brd ff:ff:ff:ff:ff:ff
$ iw dev wlan0 scan | grep SSID | head -5
SSID: XarxaOficina
SSID: Veí_5G
SSID: MobileHotspot
$ nmcli device wifi connect "XarxaOficina" password "contrasenya123"
Device 'wlan0' successfully activated.
$ ping -c 3 8.8.8.8
PING 8.8.8.8 (8.8.8.8) 56(84) bytes of data.
64 bytes from 8.8.8.8: icmp_seq=1 ttl=118 time=12.4 ms
64 bytes from 8.8.8.8: icmp_seq=2 ttl=118 time=11.9 ms
64 bytes from 8.8.8.8: icmp_seq=3 ttl=118 time=12.1 ms
rtt min/avg/max = 11.9/12.1/12.4 ms
wlan0, detecta xarxes i connecta correctament. DKMS assegura que el mòdul es recompili automàticament en el pròxim apt upgrade del kernel.
Entorn: Debian 12 (Bookworm). La impressora connecta per USB, apareix a lsusb com a dispositiu HP, però CUPS no mostra cap impressora disponible i hp-detect falla amb error de firmware.
$ lsusb | grep -i hp Bus 001 Device 005: ID 03f0:3d17 HP, Inc LaserJet M1136 MFP $ lpstat -p No destinations added. $ hp-detect error: No devices found. error: Unable to communicate with device (code=-12) $ dmesg | grep -i hp | tail -5 [ 8.812] usb 1-2: new full-speed USB device number 5 [ 8.954] usb 1-2: New USB device: idVendor=03f0, idProduct=3d17 [ 8.955] usb 1-2: no compatible firmware found for HP LaserJet M1136
$ apt show hplip | grep Version Version: 3.22.10+dfsg0-1 $ hp-check -t 2>&1 | grep -E "(FAIL|error|missing)" FAIL: hpaio plugin not installed (required for scan on M1136) FAIL: /usr/share/hplip/data/firmware/sihp1136.fw missing # El plugin propietari HP (hplip-plugin) és necessari per al M1136 però no és a Debian non-free
# Descarregar la versió més recent d'hplip des de HP $ wget https://developers.hp.com/sites/default/files/hplip-3.24.4.run --2024-10-15 10:23:41-- https://developers.hp.com/.../hplip-3.24.4.run Saved: hplip-3.24.4.run [16.3MB] # Verificar la integritat (hash oficial publicat per HP) $ sha256sum hplip-3.24.4.run a3f7b2e91c4d... hplip-3.24.4.run # Instal·lar prerequesits # apt install -y python3-dev libcups2-dev libdbus-1-dev libssl-dev \ libusb-1.0-0-dev udev libsane-dev # Executar l'instal·lador interactiu # sh hplip-3.24.4.run --no-docs ✓ Checking dependencies... ✓ Compiling HPLIP... ✓ Installing HPLIP 3.24.4... ✓ Restarting CUPS... ✓ Installation completed.
# hp-plugin -i HP Linux Imaging and Printing System (ver. 3.24.4) HP Device Plugin Installer Checking for plug-in... Downloading plug-in: hplip-3.24.4-plugin.run (2.7MB) Verifying plugin integrity... OK Installing plugin files... HPLIP Plugin installation successful! # Afegir l'usuari al grup lp per accés sense sudo # usermod -aG lp usuari
# hp-setup -i HP Linux Imaging and Printing System (ver. 3.24.4) Device URI: hp:/usb/HP_LaserJet_M1136_MFP?serial=VNB3L09069 Found PPD: HP-LaserJet_M1136_MFP-hpijs.ppd Adding printer: HP_LaserJet_M1136_MFP Printer added successfully. $ lpstat -p printer HP_LaserJet_M1136_MFP is idle. enabled since Tue 15 Oct 2024 10:45:00
$ hp-check -t 2>&1 | grep -E "(OK|PASS)" OK: HPLIP 3.24.4 OK: hpaio plugin installed OK: /usr/share/hplip/data/firmware/sihp1136.fw present PASS: M1136 found on hp:/usb/HP_LaserJet_M1136_MFP?serial=VNB3L09069 $ echo "Prova d'impressió Linux" | lp -d HP_LaserJet_M1136_MFP request id is HP_LaserJet_M1136_MFP-42 (1 file(s)) $ lpstat -W completed | head -3 HP_LaserJet_M1136_MFP-42 usuari 1024 Tue 15 Oct 10:47:12 2024
El following procediment és aplicable a qualsevol perifèric no detectat automàticament en sistemes Linux.
$ lsusb # Dispositius USB $ lspci -nn # Dispositius PCIe $ dmesg | tail -30 # Missatges del kernel en connexió
$ cat /sys/bus/usb/devices/X-Y/modalias $ modprobe --resolve-alias <modalias> $ grep <pid> /lib/modules/$(uname -r)/modules.alias
Per ordre de preferència:
apt search <chipset>, modinfo <modul>apt install linux-firmware firmware-<vendor>ppa:<vendor> o GitHub oficial# modprobe <modul> # Carregar sense reinici $ lsmod | grep <modul> # Confirmar que és carregat $ dmesg | tail -10 # Verificar sense errors
# Carregar automàticament en l'arrencada # echo "<modul>" >> /etc/modules # Si DKMS: verificar que s'actualitzarà # dkms status # Si cal blacklist d'un mòdul conflictiu # echo "blacklist <modul-vell>" > /etc/modprobe.d/blacklist-custom.conf # update-initramfs -u
Executar la prova funcional específica del dispositiu (ping, lp, scan, etc.) i guardar la sortida com a evidència. Documentar: versió de kernel, versió del driver i comandes utilitzades per a futures reutilitzacions.
| Situació | Comanda |
|---|---|
| Veure dispositius USB | lsusb -v |
| Veure dispositius PCIe | lspci -nn |
| Errors de detecció | dmesg | grep -E "(error|fail|firmware)" |
| Mòduls carregats | lsmod | grep <nom> |
| Info d'un mòdul | modinfo <modul> |
| Carregar mòdul manualment | modprobe <modul> |
| Bloquejar mòdul | echo "blacklist X" > /etc/modprobe.d/X.conf |
| Estat DKMS | dkms status |
| Compilar mòdul DKMS | dkms build/install -m nom -v versio |
| Recompilar initramfs | update-initramfs -u |
linux-hardware.org, el repositori linux/drivers/ a kernel.org, i la wiki de la distribució (Arch Wiki és excel·lent per a investigació encara que s'usi Ubuntu/Debian).