[successivo] [precedente] [inizio] [fine] [indice generale] [indice ridotto] [indice analitico] [volume] [parte]


Capitolo 74.   Moduli del kernel Linux

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.

Tabella 74.1. Riepilogo dei programmi e dei file per la gestione dei moduli.

Nome Descrizione
insmod Carica manualmente i moduli del kernel.
rmmod Scarica manualmente i moduli del kernel.
lsmod Elenca i moduli caricati nel kernel.
depmod Rigenera il file delle dipendenze tra i moduli.
modprobe Carica un modulo rispettando le dipendenze.
/etc/modules.conf Configurazione dei moduli utilizzati.
kerneld Programma demone per il carico e lo scarico automatico dei moduli.

In questo capitolo vengono mostrati anche i parametri di alcuni tipi di moduli, mentre nel capitolo 75 ne sono riepilogati altri in modo sintetico.

74.1   Gestione dei moduli

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 72.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.

74.1.1   Funzionamento in breve

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».

74.1.2   Aspetto e collocazione

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.

/lib/modules/2.4.2/kernel/drivers/net/ne.o:\
  \/lib/modules/2.4.2/kernel/drivers/net/8390.o

74.1.3   Caricamento guidato

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]

74.1.4   Parametri

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:

options ne io=0x0300 

74.1.5   Gestione automatica

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:

0-59/5 * * * * /sbin/rmmod -a

Nel caso si voglia utilizzare il file crontab di sistema, ovvero /etc/crontab, la cosa cambia leggermente, come nell'esempio seguente:

0-59/5 * * * * root /sbin/rmmod -a

74.1.6   Utilizzo di «insmod»

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.

74.1.7   Utilizzo di «rmmod»

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.

74.1.8   Utilizzo di «lsmod»

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:

Module rappresenta il nome del modulo;
Pages rappresenta il numero di pagine di memoria utilizzate (una pagina è un blocco di 4 Kibyte);
Used by rappresenta l'utilizzo da parte di altri moduli (lo zero indica che non è utilizzato).

Supponendo di avere appena caricato il modulo plip si può ottenere quanto segue:

lsmod[Invio]

Module         Pages    Used by
plip               3            0

74.1.9   Utilizzo di «depmod»

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]

Tabella 74.8. Alcune opzioni.

Opzione Descrizione
-a [versione]
--all [versione]
Scandisce tutti i moduli della versione del kernel in funzione. depmod viene utilizzato generalmente con questa opzione per creare il file delle dipendenze. Se si desidera creare il file delle dipendenze per i moduli di un'altra versione di kernel, si può specificare espressamente tale versione.
-s
--system-log
Invia le segnalazioni di errore al registro del sistema.

Segue la descrizione di alcuni esempi.

74.1.10   Utilizzo di «modprobe»

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.

Tabella 74.10. Alcune opzioni.

Opzione Descrizione
-a
--all
Carica tutti i moduli (generalmente non viene utilizzata questa opzione).
-c
--show-conf
Emette la configurazione attuale per la gestione dei moduli; ciò comprende sia la parte predefinita che il contenuto del file di configurazione (/etc/modules.conf).
-l
--list
Elenca i moduli disponibili.
-r
--remove
Scarica i moduli dal kernel, eliminando anche quelli che sono stati caricati per soddisfare le dipendenze, sempre che ciò sia possibile.
-t tipo modello
--type tipo modello
Permette di definire il tipo di modulo, attraverso il nome usato per la directory che lo contiene (fs/, misc/, net/, scsi/,...) e attraverso un modello espresso con dei caratteri jolly. Utilizzando questa opzione, occorre fare attenzione a proteggere i caratteri jolly dall'interpretazione da parte della shell, per esempio con l'uso di apici singoli o doppi.

Segue la descrizione di alcuni esempi.

74.1.11   Avvio di «kerneld»

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:

if [ -x /sbin/depmod ]
then
    echo "Analisi delle dipendenze tra i moduli"
    /sbin/depmod -a
fi
...
...
if [ -x /sbin/kerneld ]
then
    echo "Avvio del demone per la gestione dei moduli"
    /sbin/kerneld
fi

Si veda eventualmente la pagina di manuale kerneld(1).

74.2   Configurazione dei moduli

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.

74.2.1   Direttiva alias

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.

alias eth0 ne
...

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.

74.2.2   Direttiva options

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:

alias eth0 ne
options ne io=0x300 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.

74.2.3   Gestione automatica del file di configurazione dei 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 x86, 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]

74.3   Avvio e Initrd

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 77), o initrd, ma naturalmente il kernel deve essere in grado di innestare un tale file system (sezione 72.2.10).

74.4   Casi particolari

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.

74.4.1   Modulo «ne»

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.

alias eth0 ne
alias eth1 ne2
options ne io=0x280 irq=10
options ne2 io=0x300 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.

74.4.2   Modulo «plip»

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.

74.4.3   Adattatori SCSI

Convenzionalmente, si tende ad assegnare l'alias scsi_hostadapter al modulo necessario per pilotare l'eventuale adattatore SCSI presente nel proprio elaboratore.

alias scsi_hostadapter aic7xxx

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.

74.4.4   Porta parallela

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.

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.

Segue la descrizione di alcuni esempi.

74.5   Riferimenti

Appunti di informatica libera 2007.02 --- Copyright © 2000-2007 Daniele Giacomini -- <daniele (ad) swlibero·org>


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] [indice analitico]

Valid ISO-HTML!

CSS validator!