Questo articolo è tratto dal capitolo 15 di Linux in Action, pubblicato da Manning.
Linux gestisce le periferiche hardware utilizzando i moduli del kernel. Ecco come funziona.
Un kernel Linux in esecuzione è una di quelle cose che non vuoi sconvolgere. Dopotutto, il kernel è il software che guida tutto ciò che fa il tuo computer. Considerando quanti dettagli devono essere gestiti contemporaneamente su un sistema live, è meglio lasciare che il kernel faccia il suo lavoro con il minor numero di distrazioni possibile. Ma se è impossibile apportare anche piccole modifiche all'ambiente di elaborazione senza riavviare l'intero sistema, il collegamento di una nuova webcam o stampante potrebbe causare una dolorosa interruzione del flusso di lavoro. Dover riavviare ogni volta che aggiungi un dispositivo per fare in modo che il sistema lo riconosca è poco efficiente.
Per creare un equilibrio efficace tra le virtù opposte della stabilità e dell'usabilità, Linux isola il kernel, ma consente di aggiungere funzionalità specifiche al volo tramite i moduli del kernel caricabili (LKM). Come mostrato nella figura seguente, puoi pensare a un modulo come a un pezzo di software che dice al kernel dove trovare un dispositivo e cosa farne. A sua volta, il kernel rende il dispositivo disponibile per utenti e processi e ne supervisiona il funzionamento.
Non c'è niente che ti impedisca di scrivere il tuo modulo per supportare un dispositivo esattamente come vorresti, ma perché preoccuparsi? La libreria dei moduli Linux è già così robusta che di solito non è necessario crearne una propria. E la stragrande maggioranza delle volte, Linux caricherà automaticamente il modulo di un nuovo dispositivo senza che tu te ne accorga.
Tuttavia, ci sono momenti in cui, per qualche motivo, non accade da solo. (Non vuoi lasciare quel responsabile delle assunzioni che aspetta con impazienza che la tua faccia sorridente si unisca al colloquio di lavoro in videoconferenza per troppo tempo.) Per aiutare le cose, vorrai capire un po' di più sui moduli del kernel e, in particolare , come trovare il modulo effettivo che eseguirà la tua periferica e quindi come attivarlo manualmente.
Trovare i moduli del kernel
Per convenzione accettata, i moduli sono file con estensione .ko (oggetto kernel) che risiedono sotto il /lib/modules/
directory. Prima di navigare fino a quei file, tuttavia, probabilmente dovrai fare una scelta. Poiché all'avvio viene data la possibilità di caricarne uno da un elenco di rilasci, il software specifico necessario per supportare la propria scelta (inclusi i moduli del kernel) deve esistere da qualche parte. Bene, /lib/modules
/ è uno di quelli da qualche parte. Ed è lì che troverai le directory piene di moduli per ogni versione disponibile del kernel Linux; ad esempio:
$ ls /lib/modules
4.4.0-101-generic
4.4.0-103-generic
4.4.0-104-generic
Nel mio caso, il kernel attivo è la versione con il numero di rilascio più alto (4.4.0-104-generico), ma non vi è alcuna garanzia che sarà lo stesso per te (i kernel vengono aggiornati frequentemente). Se hai intenzione di lavorare con i moduli che vorresti utilizzare su un sistema live, devi assicurarti di avere l'albero di directory giusto.
Più risorse Linux
- Comandi Linux cheat sheet
- Cheat sheet sui comandi avanzati di Linux
- Corso online gratuito:Panoramica tecnica RHEL
- Cheat sheet della rete Linux
- Cheat sheet di SELinux
- Cheat sheet dei comandi comuni di Linux
- Cosa sono i container Linux?
- I nostri ultimi articoli su Linux
Buone notizie:c'è un trucco affidabile. Invece di identificare la directory per nome e sperare di ottenere quella giusta, usa la variabile di sistema che punta sempre al nome del kernel attivo. Puoi invocare quella variabile usando uname -r
(il -r
specifica il numero di versione del kernel dall'interno delle informazioni di sistema che verrebbero normalmente visualizzate):
$ uname -r
4.4.0-104-generic
Con queste informazioni, puoi incorporare uname
nei riferimenti del tuo filesystem usando un processo noto come sostituzione di comando . Per navigare nella directory giusta, ad esempio, la aggiungi a /lib/modules
. Per dire a Linux che "uname" non è una posizione del filesystem, racchiudere uname
parte in backtick, come questo:
$ ls /lib/modules/`uname -r`
build modules.alias modules.dep modules.softdep
initrd modules.alias.bin modules.dep.bin modules.symbols
kernel modules.builtin modules.devname modules.symbols.bin
misc modules.builtin.bin modules.order vdso
Troverai la maggior parte dei moduli organizzati nelle loro sottodirectory sotto il kernel/
directory. Dedica qualche minuto a sfogliare queste directory per avere un'idea di come sono organizzate le cose e cosa è disponibile. I nomi dei file di solito ti danno una buona idea di cosa stai guardando.
$ ls /lib/modules/`uname -r`/kernel
arch crypto drivers fs kernel lib mm
net sound ubuntu virt zfs
Questo è un modo per individuare i moduli del kernel; in realtà, è il modo rapido e sporco per farlo. Ma non è l'unico modo. Se vuoi ottenere il set completo, puoi elencare tutti i moduli attualmente caricati, insieme ad alcune informazioni di base, utilizzando lsmod
. La prima colonna di questo output troncato (ce ne sarebbero troppi da elencare qui) è il nome del modulo, seguito dalla dimensione e dal numero del file, e poi dai nomi degli altri moduli da cui ciascuno dipende:
$ lsmod
[...]
vboxdrv 454656 3 vboxnetadp,vboxnetflt,vboxpci
rt2x00usb 24576 1 rt2800usb
rt2800lib 94208 1 rt2800usb
[...]
Quanti sono troppi? Bene, eseguiamo lsmod
ancora una volta, ma questa volta reindirizzando l'output a wc -l
per ottenere un conteggio delle righe:
$ lsmod | wc -l
113
Questi sono i moduli caricati. Quanti sono disponibili in totale? Esecuzione di modprobe -c
e contare le righe ci darà quel numero:
$ modprobe -c | wc -l
33350
Ci sono 33.350 moduli disponibili!?! Sembra che qualcuno abbia lavorato duramente nel corso degli anni per fornirci il software per eseguire i nostri dispositivi fisici.
Più risorse Linux
- Comandi Linux cheat sheet
- Cheat sheet sui comandi avanzati di Linux
- Corso online gratuito:Panoramica tecnica RHEL
- Cheat sheet della rete Linux
- Cheat sheet di SELinux
- Cheat sheet dei comandi comuni di Linux
- Cosa sono i container Linux?
- I nostri ultimi articoli su Linux
Nota:su alcuni sistemi, potresti incontrare moduli personalizzati a cui viene fatto riferimento con le loro voci univoche in /etc/modules
o come file di configurazione salvato in /etc/modules-load.d/
. È probabile che tali moduli siano il prodotto di progetti di sviluppo locale, magari con esperimenti all'avanguardia. In ogni caso, è bene avere un'idea di cosa stai guardando.
È così che trovi i moduli. Il tuo prossimo compito è capire come caricare manualmente un modulo inattivo se, per qualche motivo, non è successo da solo.
Caricamento manuale dei moduli del kernel
Prima che tu possa caricare un modulo del kernel, la logica impone che dovrai confermarne l'esistenza. E prima di poterlo fare, devi sapere come si chiama. Ottenere quella parte a volte richiede parti uguali di magia e fortuna e un po' di aiuto dal duro lavoro degli autori di documentazione online.
Illustrerò il processo descrivendo un problema in cui mi sono imbattuto qualche tempo fa. Un bel giorno, per un motivo che ancora mi sfugge, l'interfaccia WiFi su un laptop ha smesso di funzionare. Proprio così. Forse un aggiornamento del software lo ha eliminato. Chi lo sa? Ho eseguito lshw -c network
ed è stato trattato con queste informazioni molto strane:
network UNCLAIMED
AR9485 Wireless Network Adapter
Linux ha riconosciuto l'interfaccia (l'Atheros AR9485) ma l'ha elencata come non rivendicata. Bene, come si suol dire, "Quando il gioco si fa duro, i duri cercano su Internet". Ho eseguito una ricerca per modulo atheros ar9 linux e, dopo aver setacciato pagine e pagine di risultati di cinque e anche 10 anni che mi consigliavano di scrivere il mio modulo o semplicemente di rinunciare, ho finalmente scoperto che (con Ubuntu 16.04, almeno) esisteva un modulo funzionante. Il suo nome è ath9k.
Sì! La battaglia è buona come vinta! Aggiungere un modulo al kernel è molto più semplice di quanto sembri. Per verificare che sia disponibile, puoi eseguire find
contro l'albero delle directory del modulo, specificare -type f
per dire a Linux che stai cercando un file, quindi aggiungi la stringa ath9k
insieme a un asterisco glob per includere tutti i nomi di file che iniziano con la tua stringa:
$ find /lib/modules/$(uname -r) -type f -name ath9k*
/lib/modules/4.4.0-97-generic/kernel/drivers/net/wireless/ath/ath9k/ath9k_common.ko
/lib/modules/4.4.0-97-generic/kernel/drivers/net/wireless/ath/ath9k/ath9k.ko
/lib/modules/4.4.0-97-generic/kernel/drivers/net/wireless/ath/ath9k/ath9k_htc.ko
/lib/modules/4.4.0-97-generic/kernel/drivers/net/wireless/ath/ath9k/ath9k_hw.ko
Ancora un passaggio, carica il modulo:
# modprobe ath9k
Questo è tutto. Nessun riavvio. Nessun problema.
Ecco un altro esempio per mostrarti come lavorare con i moduli attivi che sono stati danneggiati. C'è stato un tempo in cui l'utilizzo della mia webcam Logitech con un particolare software rendeva la fotocamera inaccessibile a qualsiasi altro programma fino al successivo avvio del sistema. A volte avevo bisogno di aprire la fotocamera in un'applicazione diversa, ma non avevo il tempo di spegnere e riavviare. (Eseguo molte applicazioni e metterle tutte a posto dopo l'avvio richiede del tempo.)
Perché questo modulo è presumibilmente attivo, usando lsmod
per cercare la parola video dovrebbe darmi un suggerimento sul nome del modulo pertinente. In effetti, è meglio di un suggerimento:l'unico modulo descritto con la parola video è uvcvideo (come puoi vedere di seguito):
$ lsmod | grep video
uvcvideo 90112 0
videobuf2_vmalloc 16384 1 uvcvideo
videobuf2_v4l2 28672 1 uvcvideo
videobuf2_core 36864 2 uvcvideo,videobuf2_v4l2
videodev 176128 4 uvcvideo,v4l2_common,videobuf2_core,videobuf2_v4l2
media 24576 2 uvcvideo,videodev
Probabilmente c'era qualcosa che avrei potuto controllare per la causa dell'incidente, e immagino che avrei potuto scavare un po' più a fondo per vedere se potevo sistemare le cose nel modo giusto. Ma sai com'è; a volte non ti interessa la teoria e vuoi solo che il tuo dispositivo funzioni. Quindi ho usato rmmod
per uccidere il modulo uvcvideo e modprobe
per ricominciare tutto bello e fresco:
# rmmod uvcvideo
# modprobe uvcvideo
Di nuovo:nessun riavvio. Nessuna macchia di sangue ostinata.