[successivo] [precedente] [inizio] [fine] [indice generale] [indice ridotto] [translators] [docinfo] [indice analitico] [volume] [parte]
Quando si ha una certa dimestichezza con la ricompilazione del kernel, si potrebbe considerare l'utilizzo dei moduli come una complicazione inutile. Tuttavia, ci sono situazioni in cui l'uso dei moduli è una necessità, specie quando si vorrebbero includere molte funzionalità, ma il file principale del kernel non può superare una certa dimensione massima.
Questo capitolo, pur trovandosi in una posizione iniziale di questo documento, non è rivolto ai principianti che potrebbero trovare alcuni punti particolarmente complessi (come il problema del disco RAM iniziale). Tuttavia, quando si installa GNU/Linux, potrebbe essere necessario conoscere l'uso dei parametri di alcuni moduli.
In questo capitolo vengono mostrati anche i parametri di alcuni tipi di moduli, mentre nel capitolo 52 ne sono riepilogati altri in modo sintetico.
I moduli del kernel sono porzioni di questo che possono essere caricate in memoria quando se ne presenta la necessità e scaricate subito dopo. I moduli del kernel Linux sono quello che in altri sistemi viene definito driver. Nella sezione 49.1.2 è descritto in che modo può essere compilato un kernel di questo tipo e anche come generare i moduli relativi.
Se si dispone di una distribuzione GNU/Linux organizzata con un kernel modulare, è consigliabile sfruttare quel kernel già predisposto, assieme ai suoi moduli.
Il minimo indispensabile per attivare e disattivare i moduli è costituito da due programmi di servizio specifici: insmod e rmmod. Il primo serve per caricare i moduli, il secondo per scaricarli.
L'operazione di caricamento dei moduli deve essere fatta tenendo presente le eventuali dipendenze che ci possono essere. Per esempio, se il modulo «C» richiede la presenza del modulo «B», il quale a sua volta richiede la presenza del modulo «A», occorre caricare ordinatamente i moduli «A», «B» e «C». Nello stesso modo, lo scarico dei moduli può essere fatto solo se si rispettano le dipendenze. Nel caso appena descritto, per scaricare il modulo «A» occorre prima scaricare «C» e «B».
I moduli sono generalmente file che terminano con l'estensione .o
e si collocano al di sotto della directory /lib/modules/versione/
, dove la versione si riferisce al kernel per il quale sono stati predisposti. Per esempio, /lib/modules/2.4.2/
, si riferisce ai moduli del kernel 2.4.2.
Per facilitare l'individuazione e il caricamento dei moduli, viene creato generalmente un file, modules.dep
, nella directory iniziale di questi, attraverso il programma depmod.
#
depmod -a
[Invio]
Generalmente questo comando viene inserito nella procedura di inizializzazione del sistema, in modo da aggiornare sistematicamente questo file.
Il file contiene l'elenco dei moduli presenti, con l'indicazione precisa delle dipendenze. L'esempio seguente mostra il caso del modulo della scheda di rete NE2000, ne.o
, il quale dipende dal modulo 8390.o
.
|
Invece di caricare i moduli con il programma insmod, che richiede attenzione nella sequenza di caricamento a causa delle dipendenze, si può utilizzare modprobe che si avvale del file modules.dep
e si arrangia a caricare tutto quello che serve nel modo corretto. Per esempio, utilizzando il comando seguente si ottiene prima il caricamento del modulo 8390.o
e successivamente di ne.o
:
#
modprobe ne
[Invio]
Come accade già con i kernel monolitici, alcuni dispositivi possono essere individuati e gestiti correttamente solo se si forniscono delle informazioni aggiuntive. Per questo, alcuni moduli richiedono l'indicazione di parametri composti dalla sintassi
simbolo[=valore] |
Quando si caricano i moduli di questo tipo con insmod è necessario fornire anche i parametri, nella parte finale della riga di comando. La stessa cosa vale per modprobe, solo che in questo caso si può realizzare un file di configurazione, /etc/modules.conf
, contenente le informazioni sui parametri dei moduli utilizzati e altre indicazioni eventuali.
Per esempio, attraverso la riga seguente del file /etc/modules.conf
, si vuole specificare che l'indirizzo di I/O del dispositivo relativo al modulo ne.o
è 30016:
|
Gli strumenti e la configurazione descritti nelle sezioni precedenti, possono essere gestiti in modo automatico attraverso il demone, kerneld, oppure in modo integrato nei kernel 2.2.* e successivi (in questo caso si parla del thread kmod).
Quando è utilizzato kerneld, questo viene avviato generalmente dalla procedura di inizializzazione del sistema, dopo che è stato eseguito depmod per la rigenerazione del file delle dipendenze tra i moduli. Nel momento in cui il kernel ha bisogno di una funzione che non trova al suo interno, prova a interrogare kerneld, il quale a sua volta di avvale di modprobe per il caricamento del modulo necessario. In questa situazione, il carico e lo scarico dei moduli in modo manuale non è più necessario: è kerneld che provvede. Ci possono essere comunque situazioni in cui il meccanismo non funziona, ma resta sempre la possibilità di usare modprobe in quei casi.
L'automazione della gestione dei moduli richiede che il file /etc/modules.conf
sia configurato correttamente per quei dispositivi che si intendono usare.
Come accennato, i kernel 2.2.* incorporano kmod che si sostituisce alle funzionalità fondamentali di kerneld. In questo caso, si può osservare la presenza del file virtuale /proc/sys/kernel/modprobe
, il cui scopo è quello di informare il kernel sulla posizione in cui si trova il programma modprobe. Per questo, la procedura di inizializzazione del sistema dovrebbe provvedere a definirlo utilizzando un comando simile a quello seguente.
#
echo "/sbin/modprobe" > /proc/sys/kernel/modprobe
[Invio]
Dal momento che kmod non è efficiente quanto kerneld, occorre provvedere (ammesso che lo si voglia) a eliminare periodicamente i moduli che non sono più utilizzati. Per farlo si può usare il sistema Cron attraverso una direttiva simile a quella seguente che si riferisce al file crontab dell'utente root:
|
Nel caso si voglia utilizzare il file crontab di sistema, ovvero /etc/crontab
, la cosa cambia leggermente, come nell'esempio seguente:
|
Il programma insmod permette di caricare un modulo nel kernel. Il nome del modulo può essere indicato specificando il nome del file completo di estensione ed eventualmente di percorso (path), oppure specificando semplicemente il nome del file del modulo senza l'estensione: in questo ultimo caso, insmod cerca il file (con la sua estensione naturale) all'interno delle directory standard per i moduli.
insmod [opzioni] file_oggetto [simbolo=valore...] |
Quando nel kernel è attivato il supporto del kernel daemon e il demone kerneld è in funzione, oppure si tratta di un kernel ≥ 2.2.* ed è disponibile kmod, non dovrebbe essere necessario l'utilizzo di insmod per caricare i moduli.
Segue la descrizione di alcuni esempi.
#
insmod /lib/modules/2.0.30/net/plip.o
[Invio]
Attiva il modulo plip rappresentato dal file /lib/modules/2.0.30/net/plip.o
.
#
insmod plip
[Invio]
Come nell'esempio precedente, ma si lascia a insmod il compito di cercare il file.
Il programma rmmod permette di scaricare uno o più moduli dal kernel, sempre che questi non siano in uso e non ci siano altri moduli caricati che vi fanno riferimento.
rmmod [opzioni] modulo... |
Nella riga di comando vengono indicati i nomi dei moduli e non i nomi dei file dei moduli. Se vengono indicati più moduli, questi vengono scaricati nell'ordine in cui appaiono.
Se viene usata l'opzione -a, vengono scaricati tutti i moduli che risultano essere inattivi, senza bisogno di specificarli nella riga di comando.
Quando nel kernel è attivato il supporto del kernel daemon e il demone kerneld è in funzione, non dovrebbe essere necessario l'utilizzo di rmmod per scaricare i moduli. Se invece si utilizza un kernel ≥ 2.2.* con il supporto per kmod, si deve provvedere periodicamente a eseguire il comando rmmod -a.
rmmod è in realtà solo un collegamento a insmod che quindi cambia il suo comportamento quando viene avviato utilizzando quel nome. |
Segue la descrizione di alcuni esempi.
#
rmmod plip
[Invio]
Scarica il modulo plip.
#
rmmod -a
[Invio]
Scarica tutti i moduli inutilizzati.
Il programma lsmod permette di visualizzare la situazione sull'utilizzo dei moduli. Le stesse informazioni ottenibili da lsmod si possono avere dal contenuto del file /proc/modules
. Utilizzando lsmod si ottiene una tabellina di tre colonne:
|
Supponendo di avere appena caricato il modulo plip si può ottenere quanto segue:
#
lsmod
[Invio]
Module Pages Used by plip 3 0 |
Il programma depmod serve a generare un file di dipendenze tra i moduli, che poi viene utilizzato da modprobe per caricarli rispettando le dipendenze. Precisamente, viene creato il file /lib/modules/versione/modules.dep
.
depmod [opzioni] |
|
Segue la descrizione di alcuni esempi.
#
depmod -a
[Invio]
Genera il file /lib/modules/versione/modules.dep
.
#
depmod -a 2.1.99
[Invio]
Genera il file /lib/modules/2.1.99/modules.dep
, riferito appunto ai moduli del kernel della versione 2.1.99.
|
Si tratta di un pezzo di uno degli script della procedura di inizializzazione del sistema, in cui si avvia la generazione del file delle dipendenze tra i moduli solo se il programma esiste.
Il programma modprobe è fatto per agevolare il caricamento dei moduli del kernel.
modprobe [opzioni] file_oggetto [simbolo=valore...] |
Quando viene usato senza l'indicazione di alcuna opzione, cioè solo con il nome del modulo e l'eventuale aggiunta dei parametri, modprobe carica prima i moduli necessari a soddisfare le dipendenze, quindi provvede al caricamento del modulo richiesto. Se l'operazione fallisce, tutti i moduli superflui vengono scaricati nuovamente.
Tra le altre cose, modprobe permette di tentare il caricamento del modulo «giusto» a partire da un gruppo, quando non si conosce bene quale sia il modulo adatto a un certo tipo di dispositivo o di servizio. Per farlo è necessario indicare il tipo di modulo e il modello. Il tipo è rappresentato dalla directory che lo contiene (fs/
, misc/
, net/
, scsi/
, ecc.) e il modello si esprime utilizzando i consueti caratteri jolly (? e *).
modprobe fa uso di un file di configurazione, attraverso cui è possibile modificare le sue impostazioni predefinite e in particolare si possono definire i parametri normali necessari ad alcuni tipi di moduli. Il file in questione è /etc/modules.conf
.
|
Segue la descrizione di alcuni esempi.
#
modprobe -l
[Invio]
Elenca tutti i moduli disponibili.
#
modprobe -l -t net
[Invio]
Elenca tutti i moduli di tipo net, cioè quelli contenuti nella directory omonima.
#
modprobe -l -t net '3c*'
[Invio]
Elenca i moduli il cui nome inizia per 3c, di tipo net; in pratica elenca i moduli delle schede di rete 3Com.
#
modprobe -c
[Invio]
Emette la configurazione attuale della gestione dei moduli di modprobe.
#
modprobe plip
[Invio]
Carica il modulo /lib/modules/versione/kernel/drivers/net/plip.o
.
#
modprobe -t net 'p*'
[Invio]
Tenta di caricare un modulo che inizi con la lettera p, dalla directory /lib/modules/versione/kernel/drivers/net/
.
Nei kernel 2.0.*, kerneld è il demone che si occupa di gestire automaticamente i moduli, sempre che il kernel sia stato compilato in modo da includere questa possibilità di gestione automatizzata.
kerneld [debug] [keep] [delay=secondi] [type=numero_messaggio] |
Il demone kerneld viene attivato normalmente attraverso la procedura di inizializzazione del sistema, dopo che è stato rigenerato il file delle dipendenze tra i moduli. In pratica, l'avvio potrebbe avvenire nel modo seguente:
|
Si veda eventualmente la pagina di manuale kerneld(1).
Il file /etc/modules.conf
permette di configurare il comportamento di modprobe. Le righe vuote e quanto preceduto dal simbolo # viene ignorato. Le righe possono essere continuate utilizzando la barra obliqua inversa (\) alla fine, subito prima del codice di interruzione di riga.
Le righe di questo file vengono interpretate attraverso una shell, permettendo così di utilizzare le tecniche di sostituzione fornite comunemente da queste, come i caratteri jolly e con la sostituzione di comando.
Questo file di configurazione può contenere diversi tipi di direttive; nelle sezioni seguenti se ne mostrano solo alcune. Per la descrizione completa si veda la pagina di manuale depmod(1).
In linea di massima, si possono accumulare più direttive dello stesso tipo.
La direttiva alias permette di indicare un nome alternativo a un nome di un modulo reale:
alias alias modulo_reale |
Ciò può essere utile a vario titolo e in ogni caso sono stabiliti molti alias già in modo predefinito. Lo si può osservare con il comando seguente:
#
modprobe -l
[Invio]
... # Aliases alias binfmt-2 binfmt_aout alias binfmt-0107 binfmt_aout ... alias block-major-2 floppy alias block-major-3 ide-probe ... alias char-major-4 serial alias char-major-5 serial alias char-major-6 lp ... alias dos msdos ... alias iso9660 isofs ... alias plip0 plip alias plip1 plip alias ppp0 ppp alias ppp1 ppp ... |
In questo caso, si può osservare che è possibile fare riferimento al modulo isofs anche attraverso il nome iso9660. Tuttavia, gli alias non sono semplicemente di aiuto agli «smemorati», ma anche una necessità. Si osservi la configurazione seguente tratta da un ipotetico file /etc/modules.conf
.
|
L'alias eth0 (ovvero la prima interfaccia Ethernet) permette di fare in modo che, quando si configura l'interfaccia di rete con ifconfig venga avviato automaticamente il modulo corretto: in questo caso ne.
Ogni modulo ha le sue particolarità, quindi deve essere valutata caso per caso l'opportunità di utilizzare un alias adatto a qualche scopo.
La direttiva options permette di definire i parametri di utilizzo di un modulo, identificato attraverso il suo nome reale, oppure un alias:
options nome simbolo=valore... |
L'esempio seguente definisce che il modulo ne (Ethernet NE2000) deve essere utilizzato per un dispositivo che si raggiunge con il canale di I/O 30016 e l'IRQ 11:
|
Attraverso questa direttiva si indicano solo le opzioni che non possono essere determinate altrimenti dal sistema. Questo significa che non è necessaria una riga options per tutti i dispositivi che si intende utilizzare attraverso i moduli.
Per evitare che gli utenti debbano gestire manualmente il file /etc/modules.conf
, le distribuzioni GNU/Linux tendono a fare in modo che questo venga ricostruito automaticamente a partire da una serie di file che ne contengono le diverse porzioni necessarie. A titolo di esempio si descrive quanto fa la distribuzione GNU/Linux Debian.
La directory /etc/modutils/
contiene una serie di file che descrivono ognuno una porzione del file /etc/modules.conf
; ogni volta che viene modificato qualcosa all'interno di questa directory si avvia il programma update-modules per ricreare il file /etc/modules.conf
.
I nomi dei file inseriti nella directory /etc/modutils/
hanno valore in quanto dall'ordine lessicografico dei loro nomi dipende la sequenza con cui questi vengono presi per creare il file /etc/modules.conf
. Naturalmente, vengono esclusi da questa aggregazione quei nomi che sembrano essere solo delle copie di sicurezza di versioni precedenti o alternative.
Nella directory /etc/modutils/arch/
sono presenti altri file, uno per ogni tipo di architettura gestite, da accodare alla fine del file /etc/modules.conf
.
Volendo semplificare il procedimento di creazione del file /etc/modules.conf
per un'architettura i386, si potrebbe riassumere nel comando seguente, dove si presume che non ci siano file da escludere nella directory /etc/modutils/
:
#
cat /etc/modutils/* /etc/modutils/arch/i386 > /etc/modules.conf
[Invio]
Quando si realizza un kernel modulare standardizzato, si rischia di lasciare fuori dalla parte monolitica qualcosa che poi può rivelarsi indispensabile per l'avvio del sistema, prima di poter innestare il file system principale.
Per fare un esempio concreto, basta pensare alla realizzazione di un kernel tuttofare per una distribuzione GNU/Linux. È impensabile che si realizzi un kernel in grado di innestare il file system principale contenuto in un disco fisso SCSI. Infatti, per farlo, occorrerebbe che il codice per la gestione delle diverse schede SCSI esistenti fosse incorporato nel kernel di partenza, perché non ci sarebbe modo di accedere ai file dei moduli.
Si può risolvere il problema attraverso un disco RAM iniziale (capitolo 54), o initrd, ma naturalmente il kernel deve essere in grado di innestare un tale file system (sezione 49.2.10).
Il kernel è il risultato degli apporti di un gran numero di collaboratori e non potrebbe essere altrimenti data la mole di lavoro che c'è dietro. Tenendo conto anche del fatto che i dispositivi hardware esistenti non sono tutti uguali, spesso è necessario annotare qualche trucco per riuscire a ottenere dei risultati particolari.
Il modulo ne permette di gestire una scheda di rete NE2000 o NE1000, ma soltanto una. Se si dispone di due schede, è generalmente necessario compilare un kernel apposito e utilizzare un parametro di avvio adatto a farle riconoscere entrambe.
Con i moduli si può tentare di risolvere il problema facendo una copia del modulo e configurando i due moduli a seconda delle esigenze delle due schede. Nell'esempio si suppone di utilizzare il kernel 2.0.33.
#
cp /lib/modules/2.0.33/net/ne.o /lib/modules/2.0.33/net/ne2.o
[Invio]
In tal modo si ottiene una copia del modulo, così da poter disporre sia di ne, sia di ne2. Il file /etc/modules.conf
va configurato di conseguenza: si suppone che la prima scheda utilizzi l'indirizzo I/O 28016 con l'IRQ 10 e che la seconda utilizzi l'indirizzo I/O 30016 con l'IRQ 11.
|
Questo dovrebbe bastare a rendere automatica la gestione dei due moduli nel momento in cui si utilizza il programma ifconfig per configurare le schede.
Il modulo plip permette di gestire una o più porte parallele per una connessione punto-punto attraverso un cavo parallelo apposito. Generalmente è opportuno non indicare alcuna configurazione nel file /etc/modules.conf
: il modulo dovrebbe essere in grado di accedere a tutte le porte parallele disponibili.
Convenzionalmente, si tende ad assegnare l'alias scsi_hostadapter al modulo necessario per pilotare l'eventuale adattatore SCSI presente nel proprio elaboratore.
|
L'esempio mostra una riga del file /etc/modules.conf
in cui si dichiara l'alias in questione e lo si abbina al modulo aic7xxx. Il problema degli adattatori SCSI può essere più complesso se si intende utilizzare un sistema che si avvia a partire da un disco fisso SCSI gestito attraverso un modulo. Il problema è già stato affrontato nella discussione sul disco RAM iniziale.
Con i kernel ≥ 2.2.*, la gestione dei dispositivi che fanno uso della porta parallela richiede prima l'individuazione della porta e quindi l'uso di altri moduli che se ne servono.
La gestione della porta parallela, a livello di modulo, è scissa in due parti: quella generica e quella specifica per il tipo di hardware. |
Modulo generico per la gestione della porta parallela.
parport |
Il modulo generico non richiede parametri, ma è poi necessario caricare il modulo specifico per il tipo di hardware utilizzato.
Modulo specifico per l'hardware PC.
parport_pc io=indirizzo_i/o[,indirizzo_i/o]... irq=irq[,irq]... |
In tal modo possono essere specificate tutte le porte parallele in stile «PC» (i386) che si vogliono gestire, elencando gli indirizzi di I/O e i livelli di IRQ.
I dispositivi o le interfacce di rete che fanno uso della porta parallela, possono indicare la porta, o le porte, a cui vogliono fare riferimento al caricamento del modulo relativo.
Definizione esplicita delle stampanti.
lp parport=n[,n]... |
Definisce che le porte specificate attraverso l'elenco di numeri, sono collegate a una stampante.
Segue la descrizione di alcuni esempi.
|
Porte parallele per i386: indirizzi di I/O 3BC16, 37816 e 27816; per quanto riguarda i livelli di IRQ, il primo non viene definito, il secondo è 7, l'ultimo deve essere determinato automaticamente.
|
Due stampanti parallele che utilizzano rispettivamente la prima e la terza porta parallela.
Quando si vuole realizzare un sistema GNU/Linux generalizzato, ovvero adatto per un discreto numero di elaboratori, pur restando nell'ambito della stessa architettura, si può tentare di utilizzare il pacchetto Kudzu, (1) per cercare di individuare l'hardware esistente e di conseguenza determinare automaticamente quali sono i moduli che dovrebbero essere caricati per la sua gestione.(2)
Kudzu è un sistema molto sofisticato, che prevederebbe anche un uso interattivo con l'utente, ma qui si vuole mostrare soltanto il suo funzionamento non interattivo, con l'ausilio delle opzioni -q e -s:
kudzu -q -s |
Per la precisione, l'opzione -q richiede espressamente un funzionamento non interattivo, mentre l'opzione -s serve a evitare la scansione di porte seriali e altri componenti delicate.
Dopo la sua analisi, Kudzu aggiorna due file: /etc/sysconfig/hwconf
e /etc/modutils/kudzu
. Il primo di questi due file contiene informazioni sull'hardware trovato, con annotazioni simili all'estratto seguente, mentre il secondo contiene direttive che vanno aggiunte al file /etc/modules.conf
.
|
Per sfruttare Kudzu allo scopo di individuare l'hardware e caricare conseguentemente i moduli necessari, si potrebbe procedere schematicamente secondo la scansione seguente:
avviare Kudzu in modo non interattivo per aggiornare i file menzionati;
ricostruire o aggiornare il file /etc/modules.conf
, probabilmente attraverso lo script update-modules, oppure attraverso il programma specifico di Kudzu denominato module_upgrade;
estrarre dal file /etc/sysconfig/hwconf
i nomi dei moduli abbinati all'hardware identificato (le righe che iniziano per driver:);
utilizzare modprobe per tentare di caricare i moduli identificati.
Per estrarre dal file /etc/modules.conf
le righe contenenti la stringa driver: basta usare grep nel modo seguente:
#
grep "driver" ...
[Invio]
Tra queste righe se ne trovano anche alcune a cui manca l'indicazione di un modulo e al suo posto si trova invece la parola chiave ignore o unknown. Queste righe vanno eliminato, ripassando altre due volte il file con grep, usando l'opzione -v:
#
grep -v "ignore" ...
[Invio]
#
grep -v "unknown" ...
[Invio]
Al termine, il file che si ottiene va modificato in modo da eliminare la stringa driver: :
#
sed "s/driver: //" ...
[Invio]
Si potrebbe realizzare uno script simile a quello seguente da inserire nella procedura di inizializzazione del sistema, solo nella fase di avvio:
|
Le informazioni più aggiornate sull'uso dei moduli si possono trovare all'interno degli stessi sorgenti del kernel, nelle directory successive a sorgenti_linux/drivers/
e all'interno di sorgenti_linux/Documentation/
(può trattarsi dei commenti iniziali ai file dei sorgenti, o file di testo separati).
File di configurazione dei moduli.
Si può analizzare il file module-info
che potrebbe trovarsi in /boot/
o /etc/
.
Lauri Tischler, Module HOWTO
<http://www.linux.org/docs/ldp/howto/HOWTO-INDEX/howtos.html>
Paul Gortmaker, BootPrompt HOWTO
<http://www.linux.org/docs/ldp/howto/HOWTO-INDEX/howtos.html>
Appunti di informatica libera 2006.07.01 --- Copyright © 2000-2006 Daniele Giacomini -- <daniele (ad) swlibero·org>
2) Kudzu è sviluppato da Red Hat, ma si può trovare anche in altre distribuzioni GNU/Linux.
Dovrebbe essere possibile fare riferimento a questa pagina anche con il nome moduli_del_kernel_linux.htm
[successivo] [precedente] [inizio] [fine] [indice generale] [indice ridotto] [translators] [docinfo] [indice analitico]