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


Capitolo 77.   Disco RAM iniziale: Initrd

Un disco RAM iniziale, noto con il nome Initrd, è un file system speciale che viene realizzato in modo da essere innestato inizialmente dal kernel Linux, allo scopo di avviare un sistema minimo, con cui eseguire alcune operazioni preliminari. Al termine di queste operazioni, normalmente il sistema contenuto nel disco RAM iniziale innesta il file system standard e passa il controllo al programma Init.

La tecnica del disco RAM iniziale viene usata solitamente per caricare dei moduli prima di innestare il file system definitivo, per esempio quando il kernel richiede un modulo speciale per accedere a tale file system.

Si osservi che la realizzazione di un disco RAM iniziale è un'operazione complessa, dove occorre avere la capacità di realizzare un sistema GNU/Linux elementare, ma perfettamente autonomo.

77.1   Teoria e visione generale

La gestione del disco RAM iniziale deve essere abilitata nel kernel (sezione 72.2.10). Il file system del disco RAM che si realizza deve contenere il programma o lo script linuxrc, collocato nella directory radice. Questo programma deve svolgere tutte le funzioni che si desiderano, quindi deve innestare il file system principale previsto, spostando la directory radice all'inizio di questo, avviando lì il programma Init (/sbin/init).

Il kernel Linux deve essere avviato specificando il file system principale, il nome del programma Init, fornendo anche l'indicazione della collocazione del file-immagine contenente il disco RAM iniziale. Le prime due informazioni si possono dare facilmente tra le opzioni di avvio del kernel e dovrebbero corrispondere alle stringhe seguenti:

root=/dev/ram0 init=/linuxrc rw

Si osservi che il disco RAM iniziale deve essere accessibile inizialmente anche in scrittura, così come suggerisce il modello mostrato sopra con l'opzione rw.

Teoricamente, l'indicazione della collocazione del disco RAM iniziale potrebbe essere data «manualmente» tra le opzioni di avvio del kernel, però in pratica diventa difficile esprimere un percorso in un disco che è ancora da innestare, pertanto si usa normalmente una direttiva separata attraverso il sistema di avvio prescelto. Vengono mostrati alcuni esempi della configurazione di sistemi di avvio comuni.

Listato 77.1. Loadlin: il file-immagine è precisamente C:\LINUX\INITRD.GZ (la riga è spezzata in due per motivi di spazio).

LOADLIN C:\LINUX\VMLINUZ initrd=C:\LINUX\INITRD.GZ root=/dev/ram0 \
  \init=/linuxrc rw

Listato 77.2. LILO: nel momento in cui si installa il sistema di avvio, il file-immagine è /boot/initrd.gz.

image = /boot/vmlinuz
    initrd = /boot/initrd.gz
    append = "root=/dev/ram0 init=/linuxrc rw"

Listato 77.3. GRUB: il file-immagine initrd.gz si trova nella directory /boot/ della seconda partizione del primo disco.

title linux
kernel (hd0,1)/boot/vmlinuz root=/dev/ram0 init=/linuxrc rw
initrd (hd0,1)/boot/initrd.gz

Listato 77.4. Syslinux: il file-immagine initrd.gz si trova nella directory principale del dischetto.

LABEL linux
    KERNEL vmlinuz
    APPEND root=/dev/ram0 init=/linuxrc rw initrd=initrd.gz

Listato 77.5. Isolinux: il file-immagine initrd.gz si trova nella directory /isolinux/ del CD-ROM.

LABEL linux
    KERNEL vmlinuz
    APPEND root=/dev/ram0 init=/linuxrc rw initrd=initrd.gz

Si può vedere il disco RAM iniziale, come un file system contenente fondamentalmente un programma Init, che convenzionalmente corrisponde a /linuxrc. La difficoltà sta nel ridurre al minimo il sistema di questo disco RAM; eventualmente il file /linuxrc potrebbe essere un programma realizzato appositamente, senza bisogno di altro.

Una volta che il programma o lo script /linuxrc ha compiuto il suo lavoro, questo deve innestare il file system che deve in seguito diventare quello principale, in una directory, quindi deve eseguire la funzione pivot_root() (si veda la pagina di manuale pivot_root(2)) per scambiare i ruoli.

Figura 77.6. Scambio della directory principale e avvio del programma Init.

scambio della directory principale e avvio di Init

Convenzionalmente, la directory /initrd/ è quella che viene usata per lo scambio delle directory principali, in modo da ospitare il file system del disco RAM iniziale. Al termine, teoricamente, è possibile eseguire anche il distacco del disco RAM iniziale e liberare la memoria che lo contiene:

umount /initrd[Invio]

blockdev --flushbufs /dev/ram0[Invio]

In mancanza della possibilità di realizzare un programma linuxrc fatto su misura, la funzione pivot_root() può essere richiamata attraverso il programma pivot_root, (1) che fa parte del pacchetto Util-linux; anche il programma blockdev (2) fa parte dello stesso pacchetto.

77.2   Creazione automatica di un disco RAM iniziale

Esiste il pacchetto Initrd tools (3) che dovrebbe consentire di realizzare automaticamente un file-immagine da usare come disco RAM iniziale. Teoricamente, il comando seguente dovrebbe essere sufficiente per ottenere il risultato; si veda comunque la pagina di manuale mkinitrd(8) per studiare il suo utilizzo.

mkinitrd [opzioni]

Il pacchetto Initrd tools può essere molto utile se risulta già predisposto correttamente secondo l'organizzazione della propria distribuzione GNU/Linux. Diversamente, richiede la preparazione di una configurazione e probabilmente diventa più conveniente produrre a mano il proprio disco RAM iniziale.

77.3   Esempio di un disco RAM iniziale

Per comprendere il funzionamento di un disco RAM iniziale è necessario mostrare un esempio completo, che in parte si adegua al contenuto della figura 77.6. Si comincia preparando la struttura del file system del disco RAM a partire da una directory di lavoro:

cd[Invio]

mkdir radice-initrd[Invio]

cd radice-initrd[Invio]

mkdir bin dev etc lib proc nuova-root[Invio]

Si copiano i programmi che si ritiene siano indispensabili:

cp /bin/dash /bin/mkdir /bin/mount ./bin[Invio]

cp /sbin/insmod /sbin/pivot_root ./bin[Invio]

cp /usr/sbin/chroot ./bin[Invio]

In questo caso la shell è Dash e si preparano alcuni collegamenti simbolici:

cd ./bin[Invio]

ln -s dash ash[Invio]

ln -s dash sh[Invio]

cd ..[Invio]

Con l'aiuto di ldd si individuano i file delle librerie che richiedono i programmi copiati e si copiano a loro volta le librerie necessarie:

cp /lib/libc.so.6 /lib/ld-linux.so.2 ./lib[Invio]

Si crea un file /etc/fstab minimo:

echo "/dev/ram0 / auto defaults 0 0" > etc/fstab[Invio]

Si copiano i file dei moduli necessari (viene omesso il passaggio), quindi si creano i file di dispositivo che possono servire; qui viene usato lo script MAKEDEV:

cd ./dev[Invio]

/dev/MAKEDEV console[Invio]

/dev/MAKEDEV null[Invio]

/dev/MAKEDEV zero[Invio]

/dev/MAKEDEV ram[Invio]

/dev/MAKEDEV hd[Invio]

/dev/MAKEDEV sd[Invio]

cd ..[Invio]

Alla fine, si comincia la realizzazione dello script linuxrc, da collocare all'inizio della gerarchia (/linuxrc). Inizialmente, per verificare il funzionamento di massima del sistema, conviene fare una cosa molto semplice, come potrebbe essere questa:

#!/bin/sh

echo linuxrc di prova; premi [Invio] per terminare
read x

Una volta creato il file, occorre ricordare di dargli i permessi necessari all'esecuzione:

chmod 755 linuxrc[Invio]

Per la verifica, basta usare chroot:

chroot . /linuxrc[Invio]

linuxrc di prova; premi [Invio] per terminare

[Invio]

Seguendo l'esempio, si ottiene il messaggio che chiede di premere [Invio], quindi lo script termina di funzionare e si torna alla situazione normale. A questo punto si può modificare lo script in modo da produrre gli effetti che si desiderano. In questo caso, si vuole dare il tempo al kernel di accorgersi della presenza di un disco USB (/dev/sda2), che viene innestato per l'avvio vero e proprio del sistema:

#!/bin/sh
echo Quando il disco USB viene riconosciuto, premere [Invio]
read var

/bin/mount -t proc proc proc

/bin/mount -o ro /dev/sda2 /nuova-root

cd /nuova-root

/bin/mkdir initrd
/bin/pivot_root . initrd

exec chroot . /sbin/init < dev/console > dev/console 2>&1

A questo punto si può creare il file-immagine. Questo file può essere «normale», oppure compresso con Gzip, o con l'uso del file system Cramfs (purché il kernel sia poi in grado di leggerlo così). In questo caso si segue la strada della compressione con Gzip.

cd[Invio]

dd if=/dev/zero of=file-immagine bs=1024k count=2[Invio]

mkfs.ext2 -F file-immagine[Invio]

mkdir /tmp/immagine[Invio]

mount -o loop -t ext2 file-immagine /tmp/immagine[Invio]

cd radice-initrd[Invio]

cp -dpR * /tmp/immagine[Invio]

umount /tmp/immagine[Invio]

gzip -9 < file-immagine > initrd.gz[Invio]

Si ottiene così il file initrd.gz. Qui si omette di proposito di completare l'esempio con la spiegazione della procedura necessaria per fare in modo che il file preparato venga usato correttamente. Nella sezione teorica ci sono diversi esempi, tuttavia, questo esempio particolare avrebbe lo scopo di avviare un disco USB.

77.4   Riferimenti

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


1) util-linux: pivot_root   GNU GPL

2) util-linux: blockdev   GNU GPL

3) Initrd tools   GNU GPL


Dovrebbe essere possibile fare riferimento a questa pagina anche con il nome disco_nbsp_ram_iniziale_initrd.htm

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

Valid ISO-HTML!

CSS validator!