[successivo] [precedente] [inizio] [fine] [indice generale] [violazione GPL] [translators] [docinfo] [indice analitico] [volume] [parte]


Capitolo 31.   Moduli

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à, prima tra tutte l'installazione di GNU/Linux attraverso le distribuzioni che fanno uso di moduli per ottenere un dischetto di avvio unico, oppure per ridurne la scelta a pochi. D'altro canto, la conoscenza dei meccanismi legati alla gestione dei moduli del kernel è utile per sfruttare un sistema già ben organizzato dalla propria distribuzione GNU/Linux.

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 31.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/conf.modules 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 32 ne sono riepilogati altri in modo sintetico.

31.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 29.1.2 è già stato descritto in che modo possa 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.

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

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

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: (segue)
  /lib/modules/2.4.2/kernel/drivers/net/8390.o

31.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,

modprobe ne

si ottiene prima il caricamento del modulo 8390.o e successivamente di ne.o.

31.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/conf.modules, contenente le informazioni sui parametri dei moduli utilizzati e altre indicazioni eventuali.

Per esempio, attraverso la riga seguente del file /etc/conf.modules, si vuole specificare che l'indirizzo di I/O del dispositivo relativo al modulo ne.o è 30016.

options ne io=0x0300 

31.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/conf.modules 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

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

31.1.6   # insmod

insmod [opzioni] file_oggetto [simbolo=valore...] 

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.

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.

Esempi

insmod /lib/modules/2.0.30/net/plip.o

Attiva il modulo plip rappresentato dal file /lib/modules/2.0.30/net/plip.o.

insmod plip

Come nell'esempio precedente, ma si lascia a insmod il compito di cercare il file.

31.1.7   # rmmod

rmmod [opzioni] modulo...

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.

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.

Esempi

rmmod plip

Scarica il modulo plip.

rmmod -a

Scarica tutti i moduli inutilizzati.

31.1.8   $ lsmod

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:

Esempi

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

lsmod[Invio]

Module         Pages    Used by
plip               3            0

31.1.9   # depmod

depmod [opzioni]

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.

Alcune opzioni

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

Esempi

depmod -a

Genera il file /lib/modules/versione/modules.dep.

depmod -a 2.1.99

Genera il file /lib/modules/2.1.99/modules.dep, riferito appunto ai moduli del kernel della versione 2.1.99.


if [ -x /sbin/depmod ]
then
    echo "Analisi delle dipendenze tra i moduli"
    /sbin/depmod -a
fi

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.

31.1.10   # modprobe

modprobe [opzioni] file_oggetto [simbolo=valore...] 

modprobe è un programma fatto per agevolare il caricamento dei moduli del kernel. 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/conf.modules.

Alcune opzioni

-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/conf.modules).

-l | --list

Elenca i moduli disponibili.

-r | --remove

Scarica i moduli dal kernel, eliminando anche quelli che erano 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.

Esempi

modprobe -l

Elenca tutti i moduli disponibili.

modprobe -l -t net

Elenca tutti i moduli di tipo net, cioè quelli contenuti nella directory omonima.

modprobe -l -t net '3c*'

Elenca i moduli il cui nome inizia per 3c, di tipo net; in pratica elenca i moduli delle schede di rete 3Com.

modprobe -c

Emette la configurazione attuale della gestione dei moduli di modprobe.

modprobe plip

Carica il modulo /lib/modules/versione/kernel/drivers/net/plip.o.

modprobe -t net 'p*'

Tenta di caricare un modulo che inizi con la lettera p, dalla directory /lib/modules/versione/kernel/drivers/net/.

31.1.11   # kerneld

kerneld [debug] [keep] [delay=secondi] [type=numero_messaggio] 

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

Vedere eventualmente la pagina di manuale kerneld(1).

31.2   Configurazione dei moduli

Il file /etc/conf.modules 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.

31.2.1   alias

alias alias modulo_reale

La direttiva alias permette di indicare un nome alternativo a un nome di un 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
...

Per esempio, 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/conf.modules.

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, kerneld sappia quale modulo avviare: 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.

31.2.2   options

options nome simbolo=valore...

La direttiva options permette di definire i parametri di utilizzo di un modulo, identificato attraverso il suo nome reale, oppure un alias. Per esempio,

alias eth0 ne
options ne io=0x300 irq=11

definisce che il modulo ne (Ethernet NE2000) dovrà 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.

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

31.3.1   Disco RAM iniziale

Il metodo per realizzare un disco RAM iniziale è descritto nella documentazione allegata ai sorgenti del kernel: /usr/src/linux/Documentation/initrd.txt. In breve si tratta di predisporre un disco RAM con un file system Second-extended (Ext2) o Minix, contenente il minimo indispensabile per caricare i moduli necessari prima del montaggio del file system principale. Serviranno quindi i moduli e il programma insmod. A parte questo, serve una shell minima e le eventuali librerie.

Il disco RAM realizzato per questo scopo deve contenere il programma (o lo script) /linuxrc, che verrà avviato appena montato il disco RAM. Generalmente, quando /linuxrc termina la sua esecuzione il disco RAM viene smontato.

Di solito, il disco RAM è un file compresso attraverso gzip. Per fare in modo che venga caricato all'avvio, occorre avvisare il kernel. Per Loadlin, LILO e SYSLINUX si può usare la direttiva seguente:

initrd=file_initrd

Nel caso di GRUB si deve usare il comando seguente, dove il file in questione va indicato secondo le regole di GRUB stesso:

initrd file_initrd

Nel caso di LILO la direttiva va collocata al di sotto di una dichiarazione image, mentre nel caso di GRUB, questo comando va inserito o impartito dopo un comando kernel.

31.3.2   Un esempio

La distribuzione Red Hat, come altre, utilizza questa tecnica per avviare il modulo necessario alla gestione della scheda SCSI quando si dispone di un disco fisso SCSI contenente il file system principale. Il file del disco RAM viene collocato nella directory /boot/. Si tratta di un disco RAM in formato Second-extended, compresso con gzip. Per analizzarne il contenuto si deve decomprimere e montare come file-immagine.

cat /boot/initrd-2.0.33.img | gzip -d > /tmp/initrd.img

mount -o loop -t ext2 /tmp/initrd.img /mnt

La struttura seguente si riferisce al caso di un disco RAM iniziale per il caricamento del modulo aic7xxx.

.
|-- bin
|   |-- insmod
|   `-- sh
|-- dev
|   |-- console
|   |-- null
|   |-- ram
|   |-- systty
|   |-- tty1
|   |-- tty2
|   |-- tty3
|   `-- tty4
|-- etc
|-- lib
|   `-- aic7xxx.o
`-- linuxrc

Si può osservare l'assenza di librerie, ma questo è giustificato dal fatto che gli unici due programmi esistenti, sh e insmod, sono in versione statica, cioè includono le librerie. Il file /linuxrc è uno script che si limita semplicemente a caricare il modulo già visto.

#!/bin/sh

insmod /lib/aic7xxx.o

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

31.4.1   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 è ottenuta una copia del modulo. Adesso si dispone sia di ne che di ne2. Il file /etc/conf.modules andrà configurato opportunamente: 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.

31.4.2   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/conf.modules: il modulo dovrebbe essere in grado di accedere a tutte le porte parallele disponibili.

31.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/conf.modules 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.

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

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.

parport_pc io=0x3bc,0x378,0x278 irq=none,7,auto

Due stampanti parallele che utilizzano rispettivamente la prima e la terza porta parallela.

lp parport=0,2

31.5   Riferimenti

Appunti di informatica libera 2003.01.01 --- Copyright © 2000-2003 Daniele Giacomini -- daniele @ swlibero.org

Dovrebbe essere possibile fare riferimento a questa pagina anche con il nome moduli.html

[successivo] [precedente] [inizio] [fine] [indice generale] [violazione GPL] [translators] [docinfo] [indice analitico]