Repository 32bit  Forum
Repository 64bit  Wiki

Slackware su pennina USB: differenze tra le versioni

Da Slacky.eu.
(I pacchetti da installare)
(38 revisioni intermedie di 4 utenti non mostrate)
Riga 2: Riga 2:
[[Category:Install_e_Upgrade]]
[[Category:Install_e_Upgrade]]
=Introduzione=
=Introduzione=
Questo wiki vuole essere una guida, il più completa possibile, sui passi da fare per crearsi un propria distribuzione
+
Questo wiki vuole essere una guida, il più completa possibile, sui passi da fare per crearsi un propria distribuzione Slackware su un dispositivo di archiviazione di massa USB (che da ora in poi chiameremo più semplicemente, pennina).<BR>
Slackware su un dispositivo di archiviazione di massa USB (che da ora in poi chiameremo più semplicemente,
+
Affronteremo tutti i vari passaggi strettamente necessari a far partire un kernel installato sulla pennina ed a creare/configurare la distribuzione Slackware.<BR>
pennina).<BR>
+
Ovviamente, benché pensata e testata sulla Slackware, la teoria che acquisiremo alla fine di questo wiki sarà tale da permetterci di installare una qualsivoglia distribuzione, la differenza sarà solo sugli strumenti che useremo.
Affronteremo tutti i vari passaggi strettamente necessari a far partire un kernel installato sulla pennina ed a
 
creare/configurare la distribuzione Slackware.<BR>
 
Ovviamente, benché pensata e testata sulla Slackware, la teoria che acquisiremo alla fine di questo wiki sarà tale da
 
permetterci di installare una qualsivoglia distribuzione, la differenza sarà solo sugli strumenti che useremo.
 
Tutti o quasi tutti i comandi che eseguiremo durante il wiki devono poter godere dei diritti dall'utente root, e per
+
Tutti o quasi tutti i comandi che eseguiremo durante il wiki devono poter godere dei diritti dall'utente root, e per questo saranno caratterizzati dal carattere iniziale '#' che è tipico della shell del super-utente.
questo saranno caratterizzati dal carattere iniziale '#' che è tipico della shell del superutente.
 
I path e i comandi verranno evidenziati rispettivamente dallo style corsivo e dal font grassetto in questo modo:
+
I path e i comandi verranno evidenziati rispettivamente dallo stile corsivo e dal font grassetto in questo modo:
* ''/questo/è/un/path''
* ''/questo/è/un/path''
* '''questo è un comando'''
* '''questo è un comando'''
=Perchè installare la distribuzione su una pennina?=
+
=Perché installare la distribuzione su una pennina?=
Alcuni esempi d'uso verranno esposti alla fine del wiki, ma facciamo comunque alcune considerazioni importanti.<BR>
Alcuni esempi d'uso verranno esposti alla fine del wiki, ma facciamo comunque alcune considerazioni importanti.<BR>
Questa guida è rivolta a tutti coloro che sono curiosi, affamati di conoscenza, che usano il PC non solo come strumento
+
Questa guida è rivolta a tutti coloro che sono curiosi, affamati di conoscenza, che usano il PC non solo come strumento di lavoro, ma anche con la voglia di portare alla luce ciò che sembra arcano. Lo scopo del wiki non è la creazione della distribuzione tascabile, bensì la divulgazione della conoscenza, è importante che il lettore tenga presente questo concetto, perché è quello che ci preme rimanga più a lungo nella mente di chi legge questo wiki.<BR>
di lavoro, ma anche con la voglia di portare alla luce ciò che sembra arcano. Lo scopo del wiki non è la creazione della
+
Oltre ad avere una pennina da portare nei negozi di informatica per testare i PC che solitamente hanno installato solo lo scadente Windows, acquisiremo una conoscenza più o meno approfondita di tutti i programmi necessari all'avvio di una distribuzione GNU/Linux.
distribuzione tascabile, bensì la divulgazione della conoscenza, è importante che il lettore tenga presente questo
 
concetto, perchè è quello che ci preme rimanga più a lungo nella mente di chi legge questo wiki.<BR>
 
Oltre ad avere una pennina da portare nei negozi di informatica per testare i PC che solitamente hanno installato solo
 
lo scadente Windows, acquisiremo una conoscenza più o meno approfondita di tutti i programmi necessari all'avvio di una
 
distribuzione GNU/Linux.
 
=Software usato=
=Software usato=
Gli strumenti software che sono stati usati per testare questo wiki sono:
Gli strumenti software che sono stati usati per testare questo wiki sono:
* Slackware 12
+
* Slackware 12 (sebbene alcuni utenti l'abbiano testato con successo anche sulla 13.0, 13.1, 13.37 e sulla 14.0)
* kernel huge, presente nella directory della serie ''a/'' della Slackware
* kernel huge, presente nella directory della serie ''a/'' della Slackware
* comandi linux che verranno citati man mano, tutti comunque presenti nella distribuzione Slackware
* comandi linux che verranno citati man mano, tutti comunque presenti nella distribuzione Slackware
L'elenco sopra citato è da tenere a mente sia perchè citeremo nomi di pacchetti Slackware, sia perchè il kernel huge
+
L'elenco sopra citato è da tenere a mente sia perché citeremo nomi di pacchetti Slackware, sia perché il kernel huge fornisce un sopporto tale che alcuni problemi che si potrebbero incontrare verranno solo citati, in quanto risolti grazie alla sua configurazione statica.
fornisce un sopporto tale che alcuni problemi che si potrebbero incontrare verranno solo citati, in quanto risolti
 
grazie alla sua configurazione statica.
 
 
=Fase 0: preparazione della pennina=
=Fase 0: preparazione della pennina=
Noi installeremo la distribuzione Slackware direttamente sulla pennina, iniziamo allora preparando proprio il nostro
+
Noi installeremo la distribuzione Slackware direttamente sulla pennina, iniziamo allora preparando proprio il nostro supporto di archiviazione di massa USB.<BR>
supporto di archiviazione di massa USB.<BR>
+
L'unica cosa di cui abbiamo bisogno e di installarci dentro un file system ext3. Le pennine USB, proprio come gli hard disk, possono essere partizionate, supponiamo quindi che sulla pennina ci sia un unica partizione e che questa venga collegata dal kernel al device ''/dev/sda1''. Installiamoci dentro un file system ext3 con il seguente comando:
L'unica cosa di cui abbiamo bisogno e di installarci dentro un file system ext3. Le pennine USB, proprio come gli hard
 
disk, possono essere partizionate, supponiamo quindi che sulla pennina ci sia un unica partizione e che questa venga
 
collegata dal kernel al device ''/dev/sda1''.
 
Installiamoci dentro un file system ext3 con il seguente comando:
 
# mkfs.ext3 -L minislack /dev/sda1
# mkfs.ext3 -L minislack /dev/sda1
  +
Da Slackware 13 in poi è possibile usare ext4:
  +
# mkfs.ext4 -L minislack /dev/sda1
bene, quella che abbiamo appena creato sarà la directory radice della nostra distribuzione.
bene, quella che abbiamo appena creato sarà la directory radice della nostra distribuzione.
'''ATTENZIONE:''' tutti i file sulla pennina saranno ovviamente persi dopo l'esecuzione del comando '''mkfs.ext3''',
+
Per salvaguardare la salute della nostra perdrive è una buona idea disattivare il journaling, che è predefinitivamente attivo su questi filesystem, in modo da ridurre le scritture su disco:
quindi facciamo in modo che la pennina sia vuota prima di lanciare il comando.
+
# tune2fs -O ^has_journal /dev/sda1
+
'''ATTENZIONE:''' tutti i file sulla pennina saranno ovviamente persi dopo l'esecuzione del comando '''mkfs.ext3''' o '''mkfs.ext4''', quindi facciamo in modo che la pennina sia vuota prima di lanciare il comando.
'''Nota:''' si noti l'uso dell'opzione -L per impostare un etichetta al file system appena creato, vedremo dopo a cosa
 
ci servirà. L'etichetta del file system la si può impostare/modificare anche successivamente attraverso l'uso del
 
comando '''e2label'''.
 
  +
'''Nota:''' si noti l'uso dell'opzione -L per impostare un etichetta al file system appena creato, vedremo dopo a cosa ci servirà. L'etichetta del file system la si può impostare/modificare anche successivamente attraverso l'uso del comando '''e2label''' o '''tune2fs -L'''.
=Fase 1: creazione dell'initrd=
=Fase 1: creazione dell'initrd=
Più in là nel wiki, vedremo come far caricare il kernel di linux installato su una pennina, qui invece ci apprestiamo ad
+
Più in là nel wiki, vedremo come far caricare il kernel di linux installato su una pennina, qui invece ci apprestiamo ad affrontare un problema inerente proprio al fatto che la distribuzione si trova su una periferica USB.
affrontare un problema inerente proprio al fatto che la distribuzione si trova su una periferica USB.
 
==Perchè dobbiamo creare un initrd?==
+
==Perché dobbiamo creare un initrd?==
Una volta caricato il kernel, esso si preoccupa di attivare tutti i driver che sono stati compilati in maniera statica
+
Una volta caricato il kernel, esso si preoccupa di attivare tutti i driver che sono stati compilati in maniera statica al suo interno. L'attivazione avviene in maniera parallela, il kernel cioè non attiva un driver, aspetta che esso abbia finito di inizializzarsi e poi ne attiva un altro, ma li attiva tutti quanti "contemporaneamente". Dopo questa fase di inizializzazione dei driver il kernel deve montare quella che è la root directory (o directory radice) della distribuzione, la famosa directory ''/''. Una volta montata la directory radice, esegue quello che sarà l'unico processo avviato direttamente dal kernel (che in generale è il processo '''/sbin/init''').
al suo interno. L'attivazione avviene in maniera parallela, il kernel cioé non attiva un driver, aspetta che esso abbia
 
finito di inizializzarsi e poi ne attiva un altro, ma li attiva tutti quanti "contemporaneamente". Dopo questa fase di
 
inizializzazione dei driver il kernel deve montare quella che è la root directory (o directory radice) della
 
distribuzione, la famosa directory ''/''. Una volta montata la directory radice, esegue quello che sarà l'unico processo
 
avviato direttamente dal kernel (che in generale è il processo '''/sbin/init''').
 
* Ma i driver (o controller) USB potrebbero non essere stati compilati in maniera statica nel kernel, e senza i driver il kernel non si accorge neanche della presenza della pennina, come possiamo risolvere questo problema?
* Ma i driver (o controller) USB potrebbero non essere stati compilati in maniera statica nel kernel, e senza i driver il kernel non si accorge neanche della presenza della pennina, come possiamo risolvere questo problema?
* Non solo, ma anche ammesso che il kernel abbia i driver compilati in maniera statica, questi devono avere il tempo di accorgersi che al PC è collegata una pennina USB, come si può dire al kernel di aspettare visto che i driver sono attivati in maniera parallela?
* Non solo, ma anche ammesso che il kernel abbia i driver compilati in maniera statica, questi devono avere il tempo di accorgersi che al PC è collegata una pennina USB, come si può dire al kernel di aspettare visto che i driver sono attivati in maniera parallela?
* Ancora, come facciamo a sapere su quale device si verrà a trovare la directory radice? Il driver USB collegerà la pennina al device sda o sdb, oppure ad un altro?
+
* Ancora, come facciamo a sapere su quale device si verrà a trovare la directory radice? Il driver USB collegherà la pennina al device sda o sdb, oppure ad un altro?
* E infine, la directory radice che abbiamo creato sulla pennina usa il file system ext3, il kernel per poter riconoscere e di conseguenza usare questo file system ha bisogno del driver, e se questo driver non è compilato in maniera statica?
+
* E infine, la directory radice che abbiamo creato sulla pennina usa il file system ext3 (o ext4), il kernel per poter riconoscere e di conseguenza usare questo file system ha bisogno del driver, e se questo driver non è compilato in maniera statica?
Per tutti questi problemi esiste una soluzione unica, l'initrd. L'initrd fondamentalmente non è altro che una mini
+
Per tutti questi problemi esiste una soluzione unica, l'initrd. L'initrd fondamentalmente non è altro che una mini distribuzione la cui directory radice viene montata in ram, più precisamente collegata al device ''/dev/ram0'', con un programma o uno script (che si deve chiamare '''init''' o '''linuxrc''') che viene avviato dal kernel (il quale deve essere compilato con il supporto all'initrd) subito dopo aver inizializzato i driver. Il kernel in pratica non si occupa più di montare la root directory e di lanciare il processo '''/sbin/init''', ma semplicemente lancia il comando (o script) '''init''' che è nell'initrd e delega a lui tutto il resto.<BR>
distribuzione la cui directory radice viene montata in ram, più precisamente collegata al device ''/dev/ram0'', con un
 
programma o uno script (che si deve chiamare '''init''' o '''linuxrc''') che viene avviato dal kernel (il quale deve
 
essere compilato con il supporto all'initrd) subito dopo aver inizializzato i driver. Il kernel in pratica non si occupa
 
più di montare la root directory e di lanciare il processo '''/sbin/init''', ma semplicemente lancia il comando (o
 
script) '''init''' che è nell'initrd e delega a lui tutto il resto.<BR>
 
Questo semplice meccanismo ci permette in pratica di creare uno script per risolvere tutti i problemi sopra citati.
Questo semplice meccanismo ci permette in pratica di creare uno script per risolvere tutti i problemi sopra citati.
E' utile tener a mente questa semplice affermazione:"quando il kernel carica in memoria l'initrd e lancia il programma
+
'''Nota:''' Quando il kernel carica in memoria l'initrd e lancia il programma (o lo script) init, la root directory della nostra distribuzione non è ancora montata! Quindi la distribuzione non esiste, e con lei non esistono tutti i programmi usuali che uno pensa di usare nell'initrd. Se si vuole usare un programma, lo si deve copiare nell'ambiente dell'initrd e si devono copiare anche tutte quelle librerie condivise di cui il programma necessita.
(o lo script) init, la root directory della nostra distribuzione non è ancora montata! Quindi la distribuzione non
 
esiste, e con lei non esistono tutti i programmi usuali che uno pensa di usare nell'initrd. Se si vuole usare un
 
programma, lo si deve copiare nell'ambiente dell'initrd e si devono copiare anche tutte quelle librerie condivise di cui
 
il programma necessita".
 
==Initrd come archivio cpio==
==Initrd come archivio cpio==
Uno dei modi più semplici per creare un initrd è quello di inserire tutto il necessario in una directory vuota
+
Uno dei modi più semplici per creare un initrd è quello di inserire tutto il necessario in una directory vuota (programmi che si voglio usare nell'initrd, librerie di cui necessitano questi programmi, eventuali moduli del kernel, etc...etc...) e poi di creare un archivio cpio, magari compresso con gzip, di questa directory. Il kernel sarà poi in grado di decomprimere (se era compresso) l'archivio e di estrarne il contenuto.<BR>
(programmi che si voglio usare nell'initrd, librerie di cui necessitano questi programmi, eventuali moduli del kernel,
 
etc...etc...) e poi di creare un archivio cpio, magari compresso con gzip, di questa directory. Il kernel sarà poi in
 
grado di decomprire (se era compresso) l'archivio e di estrarne il contenuto.<BR>
 
Creiamoci allora una directory vuota ed entriamoci dentro con:
Creiamoci allora una directory vuota ed entriamoci dentro con:
# mkdir /tmp/initrd
# mkdir /tmp/initrd
Riga 59: Riga 62:
==Il pacchetto mkinitrd e la busybox==
==Il pacchetto mkinitrd e la busybox==
Il pacchetto mkinitrd della Slackware (che si trova nella directory ''a/'') contiene lo script omonimo '''mkinitrd''',
+
Il pacchetto mkinitrd della Slackware (che si trova nella directory ''a/'') contiene lo script omonimo '''mkinitrd''', che generalmente viene usato da coloro che necessitano di un initrd e non vogliono (o non hanno le competenze adatte a) crearsene uno a mano.<BR>
che generalmente viene usato da coloro che necessitano di un initrd e non vogliono (o non hanno le competenze adatte a)
+
Noi useremo il pacchetto, che quindi deve essere installato, non per lanciare l''''mkinitrd''' ma per prelevare il programma '''busybox''' che è al suo interno. Busybox è un programma che si può comportare in maniera diversa a seconda di come lo si invoca, se noi infatti creiamo un link simbolico chiamato mount a '''busybox''', allora questo si comporterà come '''mount'''. L'elenco di tutti i programmi che è in grado di simulare lo si può ottenere lanciando '''busybox''' senza parametri.
crearsene uno a mano.<BR>
 
Noi useremo il pacchetto, che quindi deve essere installato, non per lanciare l''''mkinitrd''' ma per prelevare il
 
programma '''busybox''' che è al suo interno. Busybox è un programma che si può comportare in maniera diversa a seconda
 
di come lo si invoca, se noi infatti creaiamo un link simbolico chiamato mount a '''busybox''', allora questo si
 
comporterà come '''mount'''. L'elenco di tutti i programmi che è in grado di simulare lo si può ottenere lanciando
 
'''busybox''' senza parametri.
 
Il pacchetto mkinitrd ha la '''busybox''' inserita all'interno di un archivio tar.gz il cui path completo è:
Il pacchetto mkinitrd ha la '''busybox''' inserita all'interno di un archivio tar.gz il cui path completo è:
Riga 73: Riga 76:
==Creiamo lo script init==
==Creiamo lo script init==
Ora dobbiamo creare lo script '''init''', ovvero lo script che verrà eseguito dal kernel dopo l'inizializzazione dei driver e
+
Ora dobbiamo creare lo script '''init''', ovvero lo script che verrà eseguito dal kernel dopo l'inizializzazione dei driver e che è incaricato di risolvere i problemi su citati, cioè:
che è incaricato di risolvere i problemi su citati, cioé:
+
* caricare eventualmente i moduli del kernel per i controller USB e per il file system ext3/4
* caricare eventualmente i moduli del kernel per i controller USB e per il file system ext3
 
* dare il tempo ai controller USB di rilevare la pennina e montare, dopo averla scovata, la root directory
* dare il tempo ai controller USB di rilevare la pennina e montare, dopo averla scovata, la root directory
* eseguire il vero processo init della distribuzione
* eseguire il vero processo init della distribuzione
Prima di cimentarci nella risoluzione di questi problemi dobbiamo notare che '''init''', per come lo vogliamo utilizzare noi,
+
Prima di cimentarci nella risoluzione di questi problemi dobbiamo notare che '''init''', per come lo vogliamo utilizzare noi, è uno script, e in quanto tale ha bisogno di un interprete, la '''busybox''' può fare questo per noi visto che al suo interno ha anche una piccola shell. Andiamo nella directory ''/tmp/initrd/bin'' e creiamo un link simbolico a '''busybox''' in questo modo:
è uno script, e in quanto tale ha bisogno di un interprete, la '''busybox''' può fare questo per noi visto che al suo interno
 
ha anche una piccola shell. Andiamo nella directory ''/tmp/initrd/bin'' e creiamo un link simbolico a '''busybox''' in questo
 
modo:
 
# ln -s busybox ash
# ln -s busybox ash
e quindi con un qualsiasi editor di testo creiamo il file ''/tmp/initrd/init'' e mettiamoci come prima riga:
e quindi con un qualsiasi editor di testo creiamo il file ''/tmp/initrd/init'' e mettiamoci come prima riga:
#!/bin/ash
#!/bin/ash
===Caricare i moduli del kernel necessari al rilevamento della periferica USB e del file system ext3===
+
===Caricare i moduli del kernel necessari al rilevamento della periferica USB e del file system ext3/4===
Il kernel huge è compilato con il supporto sia alle periferiche USB, sia al file system ext3 in maniera statica, e
+
Il kernel huge è compilato con il supporto sia alle periferiche USB, sia al file system ext3 (o ext4) in maniera statica, e quindi ci permette di superare in maniera trasparente questo problema.<BR>
quindi ci permette di superare in maniera traparente questo problema.<BR>
+
Si fa notare che il fatto di avere il supporto compilato in maniera statica nel kernel è un fattore da non sottovalutare. Infatti l'ambiente dell'initrd dovrebbe essere il più generale possibile, se spettasse all'initrd (e quindi allo script '''init''') caricare qualche modulo del kernel, allora l'initrd non sarebbe più indipendente, ma al suo interno dovrebbe avere i moduli compilati per il kernel specifico che lo ha eseguito.
Si fa notare che il fatto di avere il supporto compilato in maniera statica nel kernel è un fattore da non
 
sottovalutare. Infatti l'ambiente dell'initrd dovrebbe essere il più generale possibile, se spettasse all'initrd (e
 
quindi allo script '''init''') caricare qualche modulo del kernel, allora l'initrd non sarebbe più indipendente, ma al
 
suo interno dovrebbe avere i moduli compilati per il kernel specifico che lo ha eseguito.
 
===Dare il tempo ai controller USB di rilevare la pennina e montaggio della root directory===
===Dare il tempo ai controller USB di rilevare la pennina e montaggio della root directory===
Abbiamo installato sulla nostra pennina USB un file system del tipo ext3 che abbiamo anche etichettato con il nome di
+
Abbiamo installato sulla nostra pennina USB un file system del tipo ext3 (o ext4) che abbiamo anche etichettato con il nome di 'minislack'. Bene, grazie alla capacità del comando '''mount''' di utilizzare il nome di etichetta per identificare un file system, il problema può essere risolto semplicemente mettendo nello script '''init''' quanto segue:
'minislack'. Bene, grazie alla capacità del comando '''mount''' di utilizzare il nome di etichetta per identificare un
 
file system, il problema può essere risolto semplicemente mettendo nello script '''init''' quanto segue:
 
mount -n proc -t proc /proc
mount -n proc -t proc /proc
while ! mount -n -r -L minislack /mnt 2> /dev/null;
while ! mount -n -r -L minislack /mnt 2> /dev/null;
Riga 95: Riga 98:
done
done
umount -n /proc
umount -n /proc
Il "montaggio" del file system proc è necessario in quanto il comando '''mount''' fa uso di questo file system per scovare
+
Il "montaggio" del file system proc è necessario in quanto il comando '''mount''' fa uso di questo file system per scovare l'etichetta 'minislack'.<BR>
l'etichetta 'minislack'.<BR>
+
Il ciclo '''while''' con lo '''sleep''' non fa altro che dare il tempo necessario ai driver USB del kernel di rilevare la pennina.
Il ciclo '''while''' con lo '''sleep''' non fa altro che dare il tempo necessario ai driver USB del kernel di rilevare la
+
Quindi la nostra root directory, o meglio il file system che noi abbiamo etichettato come 'minislack' sarà montato nella directory ''/mnt'' a prescindere dal device a cui il driver USB (e più precisamente il modulo che gestisce le periferiche di archiviazione di massa USB, l'usb_storage) lo ha collegato.
pennina.
 
Quindi la nostra root directory, o meglio il file system che noi abbiamo etichettato come 'minislack' sarà montato nella
 
directory ''/mnt'' a prescindere dal device a cui il driver USB (e più precisamente il modulo che gestisce le
 
periferiche di archiviazione di massa USB, l'usb_storage) lo ha collegato.
 
Nelle sette righe di codice precedenti abbiamo:
+
Nelle sei righe di codice precedenti abbiamo:
* usato il comando mount
* usato il comando mount
* caricato il file system proc nella directory /proc
* caricato il file system proc nella directory /proc
Riga 106: Riga 109:
* montato la root directory in /mnt
* montato la root directory in /mnt
* utilizzato il comando umount
* utilizzato il comando umount
per quanto potevano sembrare innocenti, quelle sette righe implicano:
+
per quanto potevano sembrare innocenti, quelle sei righe implicano:
* che il kernel al momento dell'esecuzione di queste righe, abbia il supporto al procfs e al tipo di file system della root directory che montiano su ''/mnt'' (nel nostro caso il kernel huge ce li ha entrambi in maniera statica)
+
* che il kernel al momento dell'esecuzione di queste righe, abbia il supporto al procfs e al tipo di file system della root directory che montiamo su ''/mnt'' (nel nostro caso il kernel huge ce li ha entrambi in maniera statica)
* che esistano i programmi mount, umount e sleep
* che esistano i programmi mount, umount e sleep
* che esistano il device ''/dev/null'' e quello al quale sarà collegata la pennina USB (è vero che mount può scovare il device grazie all'etichetta del suo file system, ma è altrettanto vero che poi '''mount''' dovrà montare questo device)
* che esistano il device ''/dev/null'' e quello al quale sarà collegata la pennina USB (è vero che mount può scovare il device grazie all'etichetta del suo file system, ma è altrettanto vero che poi '''mount''' dovrà montare questo device)
* che esistano le directory ''/proc'' e ''/mnt''
* che esistano le directory ''/proc'' e ''/mnt''
La '''busybox''' può comportarsi come '''mount''' semplicemente facendo un link simbolico ad essa chiamato appunto
+
La '''busybox''' può comportarsi come '''mount''' semplicemente facendo un link simbolico ad essa chiamato appunto ''mount'', il problema è che quello fornito dalla '''busybox''' non è in grado di scovare le etichette dei file system (non riconosce il flag -L). Abbiamo necessariamente bisogno del comando '''mount''' del pacchetto util-linux (dalla Slackware 12.1 e successive, il pacchetto si chiama util-linux-ng) contenuto
''mount'', il problema è che quello fornito dalla '''busybox''' non è in grado di scovare le etichette dei file system
 
(non riconosce il flag -L). Abbiamo necessariamente bisogno del comando '''mount''' del pacchetto util-linux contenuto
 
sempre nella directory della serie ''a/'' della Slackware.<BR>
sempre nella directory della serie ''a/'' della Slackware.<BR>
Copiamo quindi il comando '''mount''' come segue:
Copiamo quindi il comando '''mount''' come segue:
Riga 128: Riga 131:
e copiamoci dentro le librerie condivise con:
e copiamoci dentro le librerie condivise con:
# cp -p /lib/libblkid.so.1 /lib/libuuid.so.1 /lib/libc.so.6 /lib/ld-linux.so.2 /tmp/initrd/lib
# cp -p /lib/libblkid.so.1 /lib/libuuid.so.1 /lib/libc.so.6 /lib/ld-linux.so.2 /tmp/initrd/lib
Si noti che i file originali probabilmente sono link simbilici, ma il comando '''cp''' copierà il file al quale puntano
+
Si noti che i file originali probabilmente sono link simbolici, ma il comando '''cp''' copierà il file al quale puntano e non il link.
e non il link.
 
Per il comando '''umount''' e '''sleep''' invece possiamo tranquillamente usare quelli della '''busybox''', quindi andiamo
+
<nowiki>** NOTA **</nowiki>
nella directory ''/tmp/initrd/bin'' e facciamo:
+
  +
Su slackware 13.1 il comando '''mount''' necessita di altre librerie:
  +
# ldd /bin/mount
  +
linux-gate.so.1 => (0xffffe000)
  +
/usr/lib/libv4l/v4l1compat.so (0xb7838000)
  +
/usr/lib/libv4l/v4l2convert.so (0xb7836000)
  +
libblkid.so.1 => /lib/libblkid.so.1 (0xb77eb000)
  +
libuuid.so.1 => /lib/libuuid.so.1 (0xb77e7000)
  +
libc.so.6 => /lib/libc.so.6 (0xb7683000)
  +
libv4l1.so.0 => /usr/lib/libv4l1.so.0 (0xb767e000)
  +
libv4l2.so.0 => /usr/lib/libv4l2.so.0 (0xb7674000)
  +
/lib/ld-linux.so.2 (0xb783b000)
  +
libpthread.so.0 => /lib/libpthread.so.0 (0xb765b000)
  +
libv4lconvert.so.0 => /usr/lib/libv4lconvert.so.0 (0xb75ef000)
  +
librt.so.1 => /lib/librt.so.1 (0xb75e5000)
  +
libm.so.6 => /lib/libm.so.6 (0xb75bf000)
  +
  +
Quindi sarà necessario copiare anche le nuove librerie:
  +
# cp -p /usr/lib/libv4l/v4l1compat.so /usr/lib/libv4l/v4l2convert.so /usr/lib/libv4l1.so.0 /usr/lib/libv4l2.so.0 /tmp/initrd/lib
  +
# cp -p /lib/libpthread.so.0 /usr/lib/libv4lconvert.so.0 /lib/librt.so.1 /lib/libm.so.6 /tmp/initrd/lib
  +
  +
Su Slackware 13.37 le dipendenze di '''mount''' sembrano essere le stesse della 12, ma anche se non risulta con '''ldd''', serve anche ''/lib/libm.so.6''.
  +
Quindi rispetto alla 12 bisognerà copiare anche libm.so.6:
  +
# cp -p /lib/libm.so.6 /tmp/initrd/lib
  +
  +
Su Slackware 14.0 le dipendenze diventano:
  +
# ldd /bin/mount
  +
linux-gate.so.1 (0xf771b000)
  +
libblkid.so.1 => /lib/libblkid.so.1 (0xf76b3000)
  +
libmount.so.1 => /lib/libmount.so.1 (0xf7687000)
  +
libuuid.so.1 => /lib/libuuid.so.1 (0xf7683000)
  +
libc.so.6 => /lib/libc.so.6 (0xf74fe000)
  +
/lib/ld-linux.so.2 (0xf771c000)
  +
  +
Anche qui non risulta /lib/libm.so.6, ma è necessaria per far funzionare '''mount'''.
  +
Vanno copiate tutte in questo modo:
  +
# cp -p /lib/libblkid.so.1 /lib/libmount.so.1 /lib/libuuid.so.1 /lib/libc.so.6 /lib/libm.so.6 /lib/ld-linux.so.2 /tmp/initrd/lib
  +
<nowiki>** FINE NOTA **</nowiki>
  +
  +
Per il comando '''umount''' e '''sleep''' invece possiamo tranquillamente usare quelli della '''busybox''', quindi andiamo nella directory ''/tmp/initrd/bin'' e facciamo:
# ln -s busybox umount
# ln -s busybox umount
# ln -s busybox sleep
# ln -s busybox sleep
Il programma '''mount''' l'abbiamo utilizzato passandogli anche il flag -n, dicendogli quindi di non scrivere quello che
+
Il programma '''mount''' l'abbiamo utilizzato passandogli anche il flag -n, dicendogli quindi di non scrivere quello che sarà il file ''/etc/mtab'', benché esso non lo scriva, vuole comunque leggerlo per controllare se il file system che si sta tentando di montare non sia già stato montato. Dobbiamo quindi creare il file vuoto ''/tmp/initrd/etc/mtab'':
sarà il file ''/etc/mtab'', benché esso non lo scriva, vuole comunque leggerlo per controllare se il file system che si
 
sta tentando di montare non sia già stato montato. Dobbiamo quindi creare il file vuoto ''/tmp/initrd/etc/mtab'':
 
# mkdir /tmp/initrd/etc
# mkdir /tmp/initrd/etc
# touch /tmp/initrd/etc/mtab
# touch /tmp/initrd/etc/mtab
Proseguiamo quindi con la creazione del device null e dei possibili device a cui sarà collegata la pennina USB. In generale
+
Proseguiamo quindi con la creazione del device null e dei possibili device a cui sarà collegata la pennina USB. In generale la pennina USB viene vista come una periferica SCSI disk e quindi sarà attaccata ad un device del tipo ''/dev/sdXY'' dove X varia a seconda di quante periferiche di archiviazione rilevate come SCSI (ad esempio i dischi sata) sono state trovate prima della pennina, mentre Y rappresenta una qualsiasi partizione.<BR>
la pennina USB viene vista come una periferica SCSI disk e quindi sarà attaccata ad un device del tipo ''/dev/sdXY'' dove X
+
Se, ad esempio, un PC non ha nessun disco rilevato come SCSI e ci si inserisce una pennina con tre partizioni, queste tre partizioni saranno collegate rispettivamente ai device: sda1, sda2 e sda3.
varia a seconda di quante periferiche di archiviazione rilevate come SCSI (ad esempio i dischi sata) sono state trovate prima
 
della pennina, mentre Y rappresenta una qualsiasi partizione.<BR>
 
Se, ad esempio, un PC non ha nessun disco rilevato come SCSI e ci si inserisce una pennina con tre partizioni, queste tre
 
partizioni saranno collegate rispettivamente ai device: sda1, sda2 e sda3.
 
Y allora la possiamo ricavare facilmente, infatti all'inizio abbiamo supposto che la nostra pennina avesse solo una
+
Y allora la possiamo ricavare facilmente, infatti all'inizio abbiamo supposto che la nostra pennina avesse solo una partizione e che essa (la partizione) venisse attaccata ad device ''/dev/sda1'', allora Y=1 e la pennina sarà sempre collegata ad un device dal nome ''/dev/sdX1''.<BR>
partizione e che essa (la partizione) venisse attaccata ad device ''/dev/sda1'', allora Y=1 e la pennina sarà sempre
 
collegata ad un device dal nome ''/dev/sdX1''.<BR>
 
Quindi creiamoci la directory in cui inserire i device:
Quindi creiamoci la directory in cui inserire i device:
# mkdir /tmp/initrd/dev
# mkdir /tmp/initrd/dev
Riga 148: Riga 151:
# cp -R /dev/null /tmp/initrd/dev
# cp -R /dev/null /tmp/initrd/dev
Al momento attuale gli SCSI disk sono gestiti dal device driver con major number 8. Questo device driver è in grado di gestire
+
Al momento attuale gli SCSI disk sono gestiti dal device driver con major number 8. Questo device driver è in grado di gestire sino a 15 partizioni per ogni disco, questo vuol dire che due device con X consecutive e con uguale Y hanno una distanza (in termini di minor number) pari a 16. Ad esempio il device sda avrà un minor number uguale a 0 laddove il device sdb avrà invece minor number uguale a 16, e così via.
sino a 15 partizioni per ogni disco, questo vuol dire che due device con X consecutive e con uguale Y hanno una distanza (in
 
termini di minor number) pari a 16. Ad esempio il device sda avrà un minor number uguale a 0 laddove il device sdb
 
avrà invece minor number uguale a 16, e così via.
 
Possiamo allora creare i device con:
Possiamo allora creare i device con:
Riga 156: Riga 159:
# mknod /tmp/initrd/dev/sdd1 b 8 49
# mknod /tmp/initrd/dev/sdd1 b 8 49
Ora per rendere tutto coerente con quanto scritto sempre nelle sette innocenti righe di codice inserite nel file
+
Ora per rendere tutto coerente con quanto scritto sempre nelle sei innocenti righe di codice inserite nel file ''init'', non ci resta che creare due directory vuote nelle quali verranno montati i file system proc e quello contenente la nostra directory radice.
''init'', non ci resta che creare due directory vuote nelle quali verranno montati i file system proc e quello
 
contenente la nostra directory radice.
 
# mkdir /tmp/initrd/proc /tmp/initrd/mnt
# mkdir /tmp/initrd/proc /tmp/initrd/mnt
===Eseguire il vero processo init===
===Eseguire il vero processo init===
L'ultimo passo che deve eseguire lo script '''init''' dell'initrd è quello di lanciare il vero processo '''init''' situato
+
L'ultimo passo che deve eseguire lo script '''init''' dell'initrd è quello di lanciare il vero processo '''init''' situato nella directory radice della distribuzione e poi liberare la memoria allocata.<BR>
nella directory radice della distribuzione e poi liberare la memoria allocata.<BR>
 
I passi teorici da eseguire sono:
I passi teorici da eseguire sono:
* spostare la directory radice dell'initrd sulla directory radice della distribuzione
* spostare la directory radice dell'initrd sulla directory radice della distribuzione
Riga 172: Riga 175:
* exec chroot . /sbin/init $@
* exec chroot . /sbin/init $@
Il comando '''pivot_root''' ultimamente sembra non comportarsi bene nell'ambiente dell'initrd. Fortunatamente la
+
Il comando '''pivot_root''' ultimamente sembra non comportarsi bene nell'ambiente dell'initrd. Fortunatamente la '''busybox''' ha al suo interno un programma che dovrebbe eseguire tutti i passi precedenti, il comando si chiama '''switch_root ''' e come al solito quindi basta fare un link simbolico a '''busybox''' entrando in ''/tmp/initrd/bin''
'''busybox''' ha al suo interno un programma che dovrebbe eseguire tutti i passi precedenti, il comando si chiama
 
'''switch_root ''' e come al solito quindi basta fare un link simbolico a '''busybox''' entrando in ''/tmp/initrd/bin''
 
ed eseguendo:
ed eseguendo:
# ln -s busybox switch_root
# ln -s busybox switch_root
Riga 179: Riga 182:
exec switch_root /mnt /sbin/init $@
exec switch_root /mnt /sbin/init $@
'''NOTA:''' si noti il passaggio a '''/sbin/init''' dei parametri $@, questi sono i parametri che il kernel non ha
+
'''NOTA:''' si noti il passaggio a '''/sbin/init''' dei parametri $@, questi sono i parametri che il kernel non ha riconosciuto nella sua riga di comando (quella passatagli dal loader), e che quindi passa al comando che esegue.
riconosciuto nella sua riga di comando (quella passatagli dal loader), e che quindi passa al comando che esegue.
 
===Lo script init nella sua interezza===
===Lo script init nella sua interezza===
Riga 226: Riga 229:
|-- mnt
|-- mnt
`-- proc
`-- proc
+
6 directories, 17 files
6 directories, 17 files
Non resta altro da fare che creare un archivio cpio di questa directory, comprimerla con il comando '''gzip''' e renderla
+
Non resta altro da fare che creare un archivio cpio di questa directory, comprimerla con il comando '''gzip''' e renderla disponibile al loader di linux.<BR>
disponibile al loader di linux.<BR>
 
Partendo dal solito presupposto che la pennina sia collegata dal kernel al device sda1, la si monti ad esempio nella directory
+
Partendo dal solito presupposto che la pennina sia collegata dal kernel al device sda1, la si monti ad esempio nella directory ''/mnt/memory'' con:
''/mnt/memory'' con:
 
# mount /dev/sda1 /mnt/memory
# mount /dev/sda1 /mnt/memory
si crei poi una directory in cui inserire l'archivio cpio compresso che è l'initrd con:
si crei poi una directory in cui inserire l'archivio cpio compresso che è l'initrd con:
Riga 243: Riga 246:
=Fase 2: installazione della distribuzione sulla pennina=
=Fase 2: installazione della distribuzione sulla pennina=
Ora ci si occuperà di installare e configurare una serie minimale ma importantissima di pacchetti Slackware.<BR>
Ora ci si occuperà di installare e configurare una serie minimale ma importantissima di pacchetti Slackware.<BR>
Ovviamente non ci sono limitazioni, se non quelle fisiche della pennina, al numero di pacchetti che il lettore può
+
Ovviamente non ci sono limitazioni, se non quelle fisiche della pennina, al numero di pacchetti che il lettore può installare, ma per lo scopo di questo wiki è sufficiente installare i pacchetti essenziali a far partire la distribuzione.<BR>
installare, ma per lo scopo di questo wiki è sufficiente installare i pacchetti essenziali a far partire la
+
I pacchetti che verranno installati si trovano tutti nella directory ''a/'' della Slackware, quindi, supponendo che il CD o DVD della Slackware sia stato montato nella directory ''/mnt/dvd/'', per prima cosa ci si deve spostare dentro questa directory con:
distribuzione.<BR> I pacchetti che verranno installati si trovano tutti nella directory ''a/'' della Slackware, quindi,
 
supponendo che il CD o DVD della Slackware sia stato montato nella directory ''/mnt/dvd/'', per prima cosa ci si deve
 
spostare dentro questa directory con:
 
# cd /mnt/dvd/slackware/a
# cd /mnt/dvd/slackware/a
==Un piccolo accorgimento==
==Un piccolo accorgimento==
I pacchetti verranno installati sfruttando l'opzione -root dello script '''installpkg''', alcuni dei pacchetti hanno uno
+
I pacchetti verranno installati sfruttando l'opzione -root dello script '''installpkg''', alcuni dei pacchetti hanno uno script aggiuntivo, il famoso '''doinst.sh''', che viene avviato dopo l'installazione del pacchetto. Gli script '''doinst.sh''' sono "chrootati" sulla pennina e devono poter eseguire comandi, quali ad esempio '''cd''', '''rm''' o
script aggiuntivo, il famoso '''doinst.sh''', che viene avviato dopo l'installazione del pacchetto. Gli script
 
'''doinst.sh''' sono "chrootati" sulla pennina e devono poter eseguire comandi, quali ad esempio '''cd''', '''rm''' o
 
'''ln'''. Questo implica che:
'''ln'''. Questo implica che:
* il programma che il '''doinst.sh''' vuole eseguire sia presente sulla pennina
+
* il programma che il '''doinst.sh''' vuole eseguire deve essere presente sulla pennina
* si abbiano i diritti di esecuzione sulla pennina
* si abbiano i diritti di esecuzione sulla pennina
La prima implicazione è risolta installando i pacchetti in un ordine ben preciso, facendo in modo di installare prima i
+
La prima implicazione è risolta installando i pacchetti in un ordine ben preciso, facendo in modo di installare prima i pacchetti che contengono i programmi usuali usati dai '''doinst.sh'''.
pacchetti che contengono i programmi usuali usati dai '''doinst.sh'''.
 
La seconda implicazione viene verificata se si esegue un piccolo accorgimento, ovvero smontare la pennina e rimontarla
+
La seconda implicazione viene verificata se si esegue un piccolo accorgimento, ovvero smontare la pennina e rimontarla con l'opzione 'exec' del '''mount''', in questo modo:
con l'opzione 'exec' del '''mount''', in questo modo:
 
# umount /mnt/memory
# umount /mnt/memory
# mount -o exec -rw -t ext3 /dev/sda1 /mnt/memory
+
# mount -o exec -rw /dev/sda1 /mnt/memory
==I pacchetti da installare==
==I pacchetti da installare==
La domanda è semplice, come si determinano i pacchetti che si devono installare?<BR>
La domanda è semplice, come si determinano i pacchetti che si devono installare?<BR>
La risposta non è altrettanto semplice, sicuramente ci sarà il programma ''/sbin/init'' per avere un collegamento
+
La risposta non è altrettanto semplice, sicuramente ci sarà il programma ''/sbin/init'' per avere un collegamento all'initrd creato nella 'Fase 1', ma poi? Poi bisogna seguire l''''init''' e capire cosa esegue, in modo da fargli trovare i programmi che tenta di eseguire. Se è necessario, bisogna anche seguire i programmi che '''init''' esegue per capire cosa fanno e se hanno bisogno di altri programmi o file di configurazione.<BR>
all'initrd creato nella 'Fase 1', ma poi? Poi bisogna seguire l''''init''' e capire cosa esegue, in modo da fargli
+
In generale quindi, il primo file da analizzare è ''/etc/inittab'', file di configurazione di '''init''', ci si accorge quindi che '''init''' esegue una serie di script di inizializzazione, e quindi bisogna seguire questi script per capire cosa fanno.
trovare i programmi che tenta di eseguire. Se è necessario, bisogna anche seguire i programmi che '''init''' esegue per
 
capire cosa fanno e se hanno bisogno di altri programmi o file di configurazione.<BR>
 
In generale quindi, il primo file da analizzare è ''/etc/inittab'', file di configurazione di '''init''', ci si accorge
 
quindi che '''init''' esegue una serie di script di inizializzazione, e quindi bisogna seguire questi script per capire
 
cosa fanno.
 
Per lo scopo di questo wiki il lavoro è stato già fatto dall'autore e quindi verranno segnalati solo i passi
+
Per lo scopo di questo wiki il lavoro è stato già fatto dall'autore e quindi verranno segnalati solo i passi fondamentali da fare affinché la distribuzione possa partire.
fondamentali da fare affinchè la distribuzione possa partire.
 
Qui si riporta l'elenco dei pacchetti che devono essere installati, nell'ordine di seguito riportato (l'ordine è
+
Qui si riporta l'elenco dei pacchetti che devono essere installati nell'ordine di seguito riportato (l'ordine è importante solo per i primi tre pacchetti). Accanto al nome del pacchetto vi è una piccola descrizione di cosa contiene:
importante solo per i primi tre pacchetti). Accanto al nome del pacchetto vi è una piccola descrizione di cosa contiene:
+
a/aaa_base ---> Crea tutte le directory base
aaa_base-12.0.0-noarch-1.tgz ---> Crea tutte le directory base
+
a/coreutils ---> Programmi utilizzati dagli script '''doisnt.sh'''
coreutils-6.9-i486-1.tgz ---> Programmi utilizzati dagli script '''doisnt.sh'''
+
a/glibc-solibs ---> La libreria glibc, usata da molti eseguibili (tra cui '''init''')
glibc-solibs-2.5-i486-4.tgz ---> La libreria glibc, usata da molti eseguibili (tra cui '''init''')
+
a/glibc-zoneinfo ---> Contiene lo script '''timeconfig''' che verrà usato in seguito
glibc-zoneinfo-2.5-noarch-4.tgz ---> Contiene lo script '''timeconfig''' che verrà usato in seguito
+
a/dialog ---> Usato per visualizzare i box dei dialoghi da altri programmi
bash-3.1.017-i486-2.tgz ---> La shell
+
(tra cui '''timeconfig''')
etc-11.1-noarch-6.tgz ---> File di configurazione dei programmi utilizzati
+
a/bash ---> La shell
util-linux-2.12r-i486-6.tgz ---> Contiene, tra l'altro, il programma '''mount'''
+
a/etc ---> File di configurazione dei programmi utilizzati
sysvinit-2.86-i486-5.tgz ---> Contiene il programma '''init'''
+
a/util-linux ---> Contiene, tra l'altro, il programma '''mount'''. Dalla Slackware 12.1 alla 13.1,
sysvinit-scripts-1.2-noarch-13.tgz ---> I famosi script '''rc.d''' della Slackware, invocati da '''init'''
+
il pacchetto si chiama util-linux-ng
module-init-tools-3.2.2-i486-3.tgz ---> '''modprobe''' e altri programmi per gestire i moduli
+
a/sysvinit ---> Contiene il programma '''init'''
e2fsprogs-1.39-i486-1.tgz ---> Comandi per i filesystem ext2/3
+
a/sysvinit-scripts ---> I famosi script '''rc.d''' della Slackware, invocati da '''init'''
devs-2.3.1-noarch-25.tgz ---> I device, senza di questi....
+
a/module-init-tools ---> '''modprobe''' e altri programmi per gestire i moduli
findutils-4.2.31-i486-1.tgz ---> '''find''', usato dagli script di inizializzazione
+
a/e2fsprogs ---> Comandi per i filesystem ext2/3/4
aaa_elflibs-12.0.0-i486-3.tgz ---> Libreria libtermcap per i terminali
+
a/devs ---> I device, senza di questi....
aaa_terminfo-5.6-noarch-1.tgz ---> File di informazione sui terminali usati dalla libreria libtermcap
+
a/findutils ---> '''find''', usato dagli script di inizializzazione
shadow-4.0.3-i486-14.tgz ---> Contiene, tra l'altro, i programmi '''login''' e '''sulogin'''
+
a/aaa_elflibs ---> Libreria libtermcap per i terminali
grep-2.5-i486-3.tgz ---> '''grep''', usato dagli script di inizializzazione
+
a/aaa_terminfo ---> File di informazione sui terminali usati dalla libreria libtermcap
procps-3.2.7-i486-2.tgz ---> '''ps''', usato dagli script di inizializzazione
+
a/shadow ---> Contiene, tra l'altro, i programmi '''login''' e '''sulogin'''
kernel-huge-2.6.21.5-i486-2.tgz ---> Il kernel...
+
a/grep ---> '''grep''', usato dagli script di inizializzazione
kernel-modules-2.6.21.5-i486-2.tgz ---> ... i suoi moduli
+
a/procps ---> '''ps''', usato dagli script di inizializzazione
  +
a/kernel-huge ---> Il kernel...
  +
a/kernel-modules ---> ... i suoi moduli
Per installare questi pacchetti si deve eseguire:
+
<nowiki>** NOTA **</nowiki>
# installpkg -root /mnt/memory aaa_base-12.0.0-noarch-1.tgz coreutils-6.9-i486-1.tgz bash-3.1.017-i486-2.tgz ....
+
dove i '...' indicano tutti gli altri pacchetti su menzionati.
+
Su slackware 13.1 è necessario anche il seguente pacchetto
  +
l/v4l-utils ---> Librerie necessarie ai programmi di sistema (ad es: '''mount''')
  +
  +
mentre su Slackware 14.0 non troveremo module-init-tools, ma al suo posto:
  +
a/kmod ---> '''modprobe''' e altri programmi per gestire i moduli
  +
  +
<nowiki>** FINE NOTA **</nowiki>
  +
  +
Per installare questi pacchetti si deve eseguire '''installpkg''' con l'opzione -root ''/mnt/memory'', ad esempio:
  +
# installpkg -root /mnt/memory aaa_base-12.0.0-noarch-1.tgz
==Una facile configurazione==
==Una facile configurazione==
Come per la domanda 'Quali pacchetti si devono installare?', così la risposta alla domanda 'Cosa si deve configurare?'
+
Come per la domanda 'Quali pacchetti si devono installare?', così la risposta alla domanda 'Cosa si deve configurare?' dipende sempre dall'amministratore del sistema e da cosa esso intenda far eseguire all'avvio della macchina.<BR>
dipende sempre dall'amministratore del sistema e da cosa esso intenda far eseguire all'avvio della macchina.<BR>
+
Nel wiki si intende lasciare intatti gli script di inizializzazione fatti da Patrick J. Volkerding, creatore della Slackware, e quindi si procederà nella minima configurazione necessaria proprio a questi script di inizializzazione.
Nel wiki si intende lasciare intatti gli script di inizializzazione fatti da Patrick J. Volkerding, creatore della
 
Slackware, e quindi si procederà nella minima configurazione necessaria proprio a questi script di inizializzazione.
 
===/etc/fstab===
===/etc/fstab===
Si comincia con il creare il file ''/etc/fstab'' come segue:
Si comincia con il creare il file ''/etc/fstab'' come segue:
# echo -e "LABEL=minislack\t\t/\text3\trw\t1 1" > /mnt/memory/etc/fstab
+
# echo -e "LABEL=minislack\t\t/\text3\trw,noatime\t0 1" > /mnt/memory/etc/fstab
  +
Nel caso si abbia scelto ext4 diventa:
  +
# echo -e "LABEL=minislack\t\t/\text4\trw,noatime\t0 1" > /mnt/memory/etc/fstab
===/etc/hardwareclock===
===/etc/hardwareclock===
Un altro file richiesto dagli script di inizializzazione della Slackware è il file ''/etc/hardwareclock'' che indica
+
Un altro file richiesto dagli script di inizializzazione della Slackware è il file ''/etc/hardwareclock'' che indica come è impostato l'orologio hardware. In effetti questo file non contiene granché, ma viene consigliato di editarlo/crearlo tramite lo script '''/usr/sbin/timeconfig''', quindi bisogna eseguire lo script spostandogli la directory root, in questo modo:
come è impostato l'orologio hardware. In effetti questo file non contiene granché, ma viene consigliato di
 
editarlo/crearlo tramite lo script '''/usr/sbin/timeconfig''', quindi bisogna eseguire lo script spostandogli la
 
directory root, in questo modo:
 
# cd /mnt/memory
# cd /mnt/memory
# chroot . usr/sbin/timeconfig
# chroot . usr/sbin/timeconfig
Riga 308: Riga 311:
=Fase 3: impostare il boot loader e testare il tutto=
=Fase 3: impostare il boot loader e testare il tutto=
L'ultima cosa da fare è quella di rendere la pennina "bootabile", ovvero di inserire nel suo primo settore, il famoso
+
L'ultima cosa da fare è quella di rendere la pennina "bootabile", ovvero di inserire nel suo primo settore, il famoso settore di boot. Per fare questo basta creare un file ''lilo.conf'' ad-hoc, e poi lanciare LILO passandogli il file appena creato.<BR>
settore di boot. Per fare questo basta creare un file ''lilo.conf'' ad-hoc, e poi lanciare LILO passandogli il file
+
Si crei quindi il file, ad esempio ''/mnt/memory/etc/lilo.conf'', direttamente sulla pennina in modo che rimanga con essa, con all'interno quanto segue:
appena creato.<BR>
 
Si crei quindi il file, ad esempio ''/mnt/memory/etc/lilo.conf'', direttamente sulla pennina in modo che rimanga con
 
essa, con all'interno quanto segue:
 
<PRE>
<PRE>
boot = /dev/sda
boot = /dev/sda
Riga 317: Riga 320:
compact
compact
lba32
lba32
  +
large-memory
image = /mnt/memory/boot/vmlinuz
image = /mnt/memory/boot/vmlinuz
Riga 322: Riga 326:
</PRE>
</PRE>
Si noti l'opzione 'initrd', con la quale si indica al kernel che deve usare l'initrd creato nella 'Fase 1'. Ora non
+
Si noti l'opzione 'initrd', con la quale si indica al kernel che deve usare l'initrd creato nella 'Fase 1'. Ora non resta quindi che lanciare LILO come segue:
resta quindi che lanciare LILO come segue:
 
# lilo -C /mnt/memory/etc/lilo.conf
# lilo -C /mnt/memory/etc/lilo.conf
e riavviare il PC facendogli fare il boot dalla pennina USB.<BR>
e riavviare il PC facendogli fare il boot dalla pennina USB.<BR>
Con la configurazione minimale che si è fatta nella 'Fase 2', basta, al momento del login, inserire l'username di 'root'
+
Con la configurazione minimale che si è fatta nella 'Fase 2', basta, al momento del login, inserire l'username di 'root' per avere una shell con tutti i privilegi del super-utente.
per avere una shell con tutti i privilegi del superutente.
 
=Esempi d'uso=
=Esempi d'uso=
Una volta che si ha una pennina USB "bootabile", con all'interno un intera distribuzione, serve solo la fantasia per
+
Una volta che si ha una pennina USB "bootabile", con all'interno un intera distribuzione, serve solo la fantasia per farci quello che ci pare.<BR>
farci quello che ci pare.<BR>
+
Esempi d'uso potrebbero essere quello di crearsi una distribuzione adatta alla lettura di contenuti multimediali, in questo modo basta trovare un PC per vedere un DVD o ascoltare della musica, senza preoccuparsi che il PC sia dotato di tutti i programmi o codec adatti.
Esempi d'uso potrebbero essere quello di crearsi una distribuzione adatta alla lettura di contenuti multimediali, in
 
questo modo basta trovare un PC per vedere un DVD o ascoltare della musica, senza preoccuparsi che il PC sia dotato di
 
tutti i programmi o codec adatti.
 
Un altro esempio è che si ha sempre a portata di mano un "disco di ripristino". Se la distribuzione installata sul PC
+
Un altro esempio è che si ha sempre a portata di mano un "disco di ripristino". Se la distribuzione installata sul PC non dovesse partire perché ci si è divertiti un po' troppo con i file di configurazione, si può sempre fare il boot del PC con la pennina e provvedere a rimediare agli eventuali danni che si è combinati.
non dovesse partire perchè ci si è divertiti un pò troppo con i file di configurazione, si può sempre fare il boot del
 
PC con la pennina e provvedere a rimediare agli eventuali danni che si è combinati.
 
==Aggiornare la distribuzione==
 
Un altro esempio potrebbe essere quello di aggiornare la distribuzione. L'aggiornamento a caldo della distribuzione non
 
è sempre possibile, alcuni programmi infatti dipendono da librerie che se aggiornate rendono il programma
 
inutilizzabile, e se non si possono utilizzare programmi come '''rm''' o '''ls''' allora il lavoro di aggiornamento
 
risulta molto complicato.<BR>
 
Se invece si fa il boot dalla pennina, allora si può montare il file system della distribuzione e installare/upgradare
 
tutta una serie di pacchetti, usando ad esempio l'opzione '-root' di '''installpkg''' o '''upgradepkg'''.
 
===Lo script analyze_SlackPack.sh===
+
=Appendice=
Ad esempio si supponga di avere una directory ''/usr/local/src/slackware'' in cui si mantiene aggiornato, tramite
+
==A: altri pacchetti utili==
'''rsync''', il repository ufficiale Slackware.
+
Se si vuole rendere la distribuzione che si è installata sulla pennina un po' più indipendente, bisogna essere in grado di manipolare i pacchetti della Slackware, non solo, ma sarebbe anche carino poter utilizzare tutta una serie di comandi utili ad un sistemista. Quindi, oltre all'insieme minimo di pacchetti menzionati nella sezione
  +
'[[#I_pacchetti_da_installare|I pacchetti da installare]]', qui di seguito c'è un elenco dei pacchetti che rendono la distribuzione sulla pennina, più user-friendly:
  +
a/pkgtools ---> Per gestire i pacchetti della Slackware
  +
a/bin ---> Usato dagli script di pkgtools
  +
a/sed ---> Usato dagli script di pkgtools
  +
a/gzip ---> Usato dagli script di pkgtools
  +
a/tar ---> Usato dagli script di pkgtools
  +
a/xz ---> Usato dagli script di pkgtools per il nuovo formato '.txz' della Slackware 13
Si crei ora uno file nella pennina chiamato ''/mnt/memory/usr/local/bin/analyze_SlackPkg.sh'' copiandoci dentro lo
+
ap/man ---> Il comando man più tornare molto utile
script seguente:
+
ap/man-pages ---> Le pagine di manuale di molti comandi
<PRE>
+
ap/groff ---> Il formattatore usato da man
#!/bin/bash
+
a/cxxlibs ---> Libreria c++ standard usata da groff
# by Spina <spina80@freemail.it>
+
a/less ---> Il comando che man usa per visualizzare le pagine di manuale
function _get_pack_name
+
a/udev ---> Utile se si vogliono usare driver che necessitano di firmware
{
 
local pack_name=${1##*/};
 
local array=($(echo $pack_name | tr -s '-' ' '));
 
local array_size=${#array[@]};
 
pack_name=$(i=0; while (( $i < $array_size-3 )); do echo -n ${array[$i]}"-"; let i++; done);
 
pack_name=${pack_name%-};
 
echo $pack_name;
 
}
 
function _check_ext_program
+
ap/nano ---> Il famoso e semplice editor di testo
{
 
local ext_prog=(bunzip2 grep mktemp rm sed tr);
 
local prog;
 
local error=0;
 
 
for prog in ${ext_prog[@]}; do
 
if ! which $prog >& /dev/null; then
 
echo "$prog: not found. I need it.";
 
error=1;
 
fi
 
done
 
 
(( $error == 1 )) && exit 1;
 
}
 
function _help
+
a/bzip2 ---> Sempre più spesso si trovano archivi bzip
{
 
echo -e "Use: ${0##*/} [-h | -n | -m] [root_directory]\n\
 
For every package found in ROOT_DIRECTORY/var/log/packages,\n\
 
it searches in ./MANIFEST.bz2 this package and print his name\n\
 
if this package needs upgrade.\n\n\
 
-h\tprint this help and exit\n\
 
-n\tprint the name of packages which don't need upgrade\n\
 
-m\tprint the name of packages which are missing in ./MANIFEST.bz2\n\n\
 
ROOT_DIRECTORY is / for default, or the value of ROOT enviroment\n\
 
variable, or the value of root_directory passed in command line.\n\
 
If both variable ROOT and root_directory are set, root_directory is used.";
 
}
 
_check_ext_program;
+
a/reiserfsprogs ---> Per gestire il famoso file system reiser
[ ! -f "MANIFEST.bz2" ] &&\
 
echo "MANIFEST.bz2 not found in current directory,"\
 
"please enter in the directory where is located MANIFEST.bz2" &&\
 
exit 2;
 
FLAG_N=0;
+
=Ringraziamenti=
FLAG_M=0;
+
Ringrazio ZeroUno per i suoi consigli e le sue prove.
while getopts hnm OPT; do
+
Note per Slackware 13.1 a cura di [[Utente:Ansa89|Ansa89]].
case $OPT in
 
h)
 
_help;
 
exit 0;
 
;;
 
n)
 
FLAG_N=1;
 
;;
 
m) FLAG_M=1;
 
;;
 
?)
 
exit 3;
 
;;
 
esac
 
done
 
if (( FLAG_N == 1 )) && (( FLAG_M == 1 )); then
+
Integrazioni per Slackware 13.37-14.0, ext4 e tune2fs a cura di sya54M.
echo "Only one option between -n and -m must be set";
 
exit 4;
 
fi
 
while (( $OPTIND != 1 )); do
 
shift;
 
let OPTIND--;
 
done
 
 
root=$1;
 
root=${root:-$ROOT};
 
root=${root%/};
 
root=${root}/var/log/packages/;
 
 
[ ! -d $root ] && \
 
echo "$root not found, $1 is not the root directory" &&\
 
exit 5;
 
 
TMP_FILE=$(mktemp -p /tmp packages.XXXXXX);
 
bunzip2 -c MANIFEST.bz2 | sed -n /Package:/'{s/.*\(\.\/.*\)/\1/;p;}' > $TMP_FILE;
 
 
for file in ${root}*; do
 
pack_name=$(_get_pack_name $file);
 
prob_pack=($(grep "/$pack_name-" $TMP_FILE));
 
 
case ${#prob_pack[@]} in
 
0)
 
pack="";
 
;;
 
1)
 
pack=${prob_pack[0]};
 
;;
 
*)
 
pack="";
 
for package in ${prob_pack[@]}; do
 
if [[ $(_get_pack_name $package) == $pack_name ]]; then
 
pack=$package;
 
break
 
fi
 
done
 
;;
 
esac
 
 
if (( FLAG_N == 1 )); then
 
if [[ $pack != "" ]] && [[ ${pack##*/} == ${file##*/}.tgz ]]; then
 
echo ${file##*/};
 
fi
 
elif (( FLAG_M == 1 )); then
 
if [[ $pack == "" ]]; then
 
echo ${file##*/};
 
fi
 
else
 
if [[ $pack != "" ]] && [[ ${pack##*/} != ${file##*/}.tgz ]]; then
 
echo "$pack";
 
fi
 
fi
 
done
 
 
rm -f $TMP_FILE;
 
exit 0;
 
</PRE>
 
ora ci si sposti nella directory contente il file MANIFEST.bz2 del ropository Slackware con:
 
# cd /usr/local/src/slackware/slackware
 
se ora si prova a lanciare lo script con:
 
# sh /mnt/memory/usr/local/bin/analyze_SlackPkg.sh
 
quello che si ottiene è l'elenco di tutti quei pacchetti che possono essere "upgradati". Lo script accetta anche due
 
opzioni facoltative, che sono:
 
* -n -> stampa l'elenco dei pacchetti che non hanno la necessità di essere "upgradati"
 
* -m -> stampa l'elenco dei pacchetti che non sono stati trovati nel file MANIFEST.bz2
 
Ovviamente gli elenchi che lo script può stampare sono tutti e tre differenti, e la somma di tutte le loro voci è
 
uguale al totale dei pacchetti che si hanno installati nella distribuzione.
 
 
Si può quindi utilizzare lo script '''analyze_SlakPkg.sh''' per fare un aggiornamento completo della distribuzione in questo modo:
 
# si avvii il PC dalla pennina
 
# si monti il file system della distribuzione su ''/mnt/hd''
 
# ci si sposti nella directory contentente il repository aggiornato Slackware con:
 
#: # cd /mnt/hd/usr/local/src/slackware/slackware
 
# si lanci il seguente comando:
 
# export ROOT=/mnt/hd; for pack in $(analyze_SlackPkg.sh); do upgradepkg $pack; done
 
 
'''NOTA 0''': ovviamente l'upgrade della distribuzione lo si dovrebbe fare controllando il file Changelog della
 
stessa. Infatti alcuni pacchetti possono cambiare nome e quindi non li aggiornerà, etc., etc.....
 
 
'''NOTA 1''': si consiglia inoltre di controllare prima l'elenco dei pacchetti che si stanno upgradando, ridirezionando
 
l'output dello script in un file temporaneo.
 
 
'''NOTA 2''': si noti anche che l'insieme minimale di pacchetti installati nella 'Fase 2' non basta a far eseguire lo
 
script, mancano infatti, e lo script lo segnalerà, il pacchetto contenente '''bunzip2''', quello di '''mktemp''' e
 
quello di '''sed''', rispettivamente:
 
* a/bzip2-1.0.4-i486-1.tgz
 
* a/bin-11.1-i486-1.tgz
 
* a/sed-4.1.5-i486-1.tgz
 
 
 
=Appendice=
 
==A: altri pacchetti utili==
 
Se si vuole rendere la distribuzione che si è installata sulla pennina un pò più indipendente, bisogna essere in grado
 
di manipolare i pacchetti della Slackware, non solo, ma sarebbe anche carino poter utilizzare anche tutta una serie di
 
comandi utili per un "sistemista". Quindi, oltre all'insieme minimo di pacchetti menzionati nella sezione
 
'[[#i_pacchetti_da_installare|I pacchetti da installare]]', qui di seguito c'è un elenco dei pacchetti che rendono la
 
distribuzione che si è installata sulla pennina, più user-friendly:
 
a/pkgtools-12.0.0-noarch-4.tgz ---> Per gestire i pacchetti della Slackware
 
a/bin-11.1-i486-1.tgz ---> Usato dagli script di pkgtools
 
a/sed-4.1.5-i486-1.tgz ---> Usato dagli script di pkgtools
 
a/gzip-1.3.12-i486-1.tgz ---> Usato dagli script di pkgtools
 
a/tar-1.16.1-i486-1.tgz ---> Usato dagli script di pkgtools
 
 
ap/man-1.6c-i486-2.tgz ---> Il comando man più tornare molto utile
 
ap/man-pages-2.55-noarch-1.tgz ---> Le pagine di manuale di molti comandi
 
ap/groff-1.19.2-i486-1.tgz ---> Il formattatore usato da man
 
a/cxxlibs-6.0.8-i486-4.tgz ---> Libreria c++ standard usata da groff
 
a/less-394-i486-1.tgz ---> Il comando che man usa per visualizzare le pagine di manuale
 
 
ap/nano-2.0.6-i486-1.tgz ---> Il famoso e semplice editor di testo
 
 
a/bzip2-1.0.4-i486-1.tgz ---> Sempre più spesso si trovano archivi bzip
 
 
a/reiserfsprogs-3.6.19-i486-2.tgz ---> Per gestire il famoso file system reiser
 
 
 
=Autore e ringraziamenti=
 
Per qualsiasi cosa scrivetemi pure:<BR>
Per qualsiasi cosa scrivetemi pure:<BR>
Emanuele Tomasi<BR>
+
[[Utente:targzeta|targzeta]]
 
Ringrazio ZeroUno per i suoi consigli e le sue prove.
 
 
[[Utente:Spina|Spina]] 15:12, 3 Mag 2008 (CEST)
 

Versione delle 14:06, 30 apr 2013

Indice

Introduzione

Questo wiki vuole essere una guida, il più completa possibile, sui passi da fare per crearsi un propria distribuzione Slackware su un dispositivo di archiviazione di massa USB (che da ora in poi chiameremo più semplicemente, pennina).
Affronteremo tutti i vari passaggi strettamente necessari a far partire un kernel installato sulla pennina ed a creare/configurare la distribuzione Slackware.
Ovviamente, benché pensata e testata sulla Slackware, la teoria che acquisiremo alla fine di questo wiki sarà tale da permetterci di installare una qualsivoglia distribuzione, la differenza sarà solo sugli strumenti che useremo.

Tutti o quasi tutti i comandi che eseguiremo durante il wiki devono poter godere dei diritti dall'utente root, e per questo saranno caratterizzati dal carattere iniziale '#' che è tipico della shell del super-utente.

I path e i comandi verranno evidenziati rispettivamente dallo stile corsivo e dal font grassetto in questo modo:

  • /questo/è/un/path
  • questo è un comando


Perché installare la distribuzione su una pennina?

Alcuni esempi d'uso verranno esposti alla fine del wiki, ma facciamo comunque alcune considerazioni importanti.
Questa guida è rivolta a tutti coloro che sono curiosi, affamati di conoscenza, che usano il PC non solo come strumento di lavoro, ma anche con la voglia di portare alla luce ciò che sembra arcano. Lo scopo del wiki non è la creazione della distribuzione tascabile, bensì la divulgazione della conoscenza, è importante che il lettore tenga presente questo concetto, perché è quello che ci preme rimanga più a lungo nella mente di chi legge questo wiki.
Oltre ad avere una pennina da portare nei negozi di informatica per testare i PC che solitamente hanno installato solo lo scadente Windows, acquisiremo una conoscenza più o meno approfondita di tutti i programmi necessari all'avvio di una distribuzione GNU/Linux.


Software usato

Gli strumenti software che sono stati usati per testare questo wiki sono:

  • Slackware 12 (sebbene alcuni utenti l'abbiano testato con successo anche sulla 13.0, 13.1, 13.37 e sulla 14.0)
  • kernel huge, presente nella directory della serie a/ della Slackware
  • comandi linux che verranno citati man mano, tutti comunque presenti nella distribuzione Slackware

L'elenco sopra citato è da tenere a mente sia perché citeremo nomi di pacchetti Slackware, sia perché il kernel huge fornisce un sopporto tale che alcuni problemi che si potrebbero incontrare verranno solo citati, in quanto risolti grazie alla sua configurazione statica.

Fase 0: preparazione della pennina

Noi installeremo la distribuzione Slackware direttamente sulla pennina, iniziamo allora preparando proprio il nostro supporto di archiviazione di massa USB.
L'unica cosa di cui abbiamo bisogno e di installarci dentro un file system ext3. Le pennine USB, proprio come gli hard disk, possono essere partizionate, supponiamo quindi che sulla pennina ci sia un unica partizione e che questa venga collegata dal kernel al device /dev/sda1. Installiamoci dentro un file system ext3 con il seguente comando:

# mkfs.ext3 -L minislack /dev/sda1

Da Slackware 13 in poi è possibile usare ext4:

# mkfs.ext4 -L minislack /dev/sda1

bene, quella che abbiamo appena creato sarà la directory radice della nostra distribuzione.

Per salvaguardare la salute della nostra perdrive è una buona idea disattivare il journaling, che è predefinitivamente attivo su questi filesystem, in modo da ridurre le scritture su disco:

# tune2fs -O ^has_journal /dev/sda1

ATTENZIONE: tutti i file sulla pennina saranno ovviamente persi dopo l'esecuzione del comando mkfs.ext3 o mkfs.ext4, quindi facciamo in modo che la pennina sia vuota prima di lanciare il comando.

Nota: si noti l'uso dell'opzione -L per impostare un etichetta al file system appena creato, vedremo dopo a cosa ci servirà. L'etichetta del file system la si può impostare/modificare anche successivamente attraverso l'uso del comando e2label o tune2fs -L.

Fase 1: creazione dell'initrd

Più in là nel wiki, vedremo come far caricare il kernel di linux installato su una pennina, qui invece ci apprestiamo ad affrontare un problema inerente proprio al fatto che la distribuzione si trova su una periferica USB.

Perché dobbiamo creare un initrd?

Una volta caricato il kernel, esso si preoccupa di attivare tutti i driver che sono stati compilati in maniera statica al suo interno. L'attivazione avviene in maniera parallela, il kernel cioè non attiva un driver, aspetta che esso abbia finito di inizializzarsi e poi ne attiva un altro, ma li attiva tutti quanti "contemporaneamente". Dopo questa fase di inizializzazione dei driver il kernel deve montare quella che è la root directory (o directory radice) della distribuzione, la famosa directory /. Una volta montata la directory radice, esegue quello che sarà l'unico processo avviato direttamente dal kernel (che in generale è il processo /sbin/init).

  • Ma i driver (o controller) USB potrebbero non essere stati compilati in maniera statica nel kernel, e senza i driver il kernel non si accorge neanche della presenza della pennina, come possiamo risolvere questo problema?
  • Non solo, ma anche ammesso che il kernel abbia i driver compilati in maniera statica, questi devono avere il tempo di accorgersi che al PC è collegata una pennina USB, come si può dire al kernel di aspettare visto che i driver sono attivati in maniera parallela?
  • Ancora, come facciamo a sapere su quale device si verrà a trovare la directory radice? Il driver USB collegherà la pennina al device sda o sdb, oppure ad un altro?
  • E infine, la directory radice che abbiamo creato sulla pennina usa il file system ext3 (o ext4), il kernel per poter riconoscere e di conseguenza usare questo file system ha bisogno del driver, e se questo driver non è compilato in maniera statica?

Per tutti questi problemi esiste una soluzione unica, l'initrd. L'initrd fondamentalmente non è altro che una mini distribuzione la cui directory radice viene montata in ram, più precisamente collegata al device /dev/ram0, con un programma o uno script (che si deve chiamare init o linuxrc) che viene avviato dal kernel (il quale deve essere compilato con il supporto all'initrd) subito dopo aver inizializzato i driver. Il kernel in pratica non si occupa più di montare la root directory e di lanciare il processo /sbin/init, ma semplicemente lancia il comando (o script) init che è nell'initrd e delega a lui tutto il resto.
Questo semplice meccanismo ci permette in pratica di creare uno script per risolvere tutti i problemi sopra citati.

Nota: Quando il kernel carica in memoria l'initrd e lancia il programma (o lo script) init, la root directory della nostra distribuzione non è ancora montata! Quindi la distribuzione non esiste, e con lei non esistono tutti i programmi usuali che uno pensa di usare nell'initrd. Se si vuole usare un programma, lo si deve copiare nell'ambiente dell'initrd e si devono copiare anche tutte quelle librerie condivise di cui il programma necessita.

Initrd come archivio cpio

Uno dei modi più semplici per creare un initrd è quello di inserire tutto il necessario in una directory vuota (programmi che si voglio usare nell'initrd, librerie di cui necessitano questi programmi, eventuali moduli del kernel, etc...etc...) e poi di creare un archivio cpio, magari compresso con gzip, di questa directory. Il kernel sarà poi in grado di decomprimere (se era compresso) l'archivio e di estrarne il contenuto.
Creiamoci allora una directory vuota ed entriamoci dentro con:

# mkdir /tmp/initrd
# cd /tmp/initrd

Il pacchetto mkinitrd e la busybox

Il pacchetto mkinitrd della Slackware (che si trova nella directory a/) contiene lo script omonimo mkinitrd, che generalmente viene usato da coloro che necessitano di un initrd e non vogliono (o non hanno le competenze adatte a) crearsene uno a mano.
Noi useremo il pacchetto, che quindi deve essere installato, non per lanciare l'mkinitrd ma per prelevare il programma busybox che è al suo interno. Busybox è un programma che si può comportare in maniera diversa a seconda di come lo si invoca, se noi infatti creiamo un link simbolico chiamato mount a busybox, allora questo si comporterà come mount. L'elenco di tutti i programmi che è in grado di simulare lo si può ottenere lanciando busybox senza parametri.

Il pacchetto mkinitrd ha la busybox inserita all'interno di un archivio tar.gz il cui path completo è:

/usr/share/mkinitrd/initrd-tree.tar.gz

preleviamo la busybox con:

# tar -C /tmp/initrd -zxf /usr/share/mkinitrd/initrd-tree.tar.gz './bin/busybox'

a questo punto la nostra directory /tmp/initrd avrà questa struttura:

# tree /tmp/initrd
/tmp/initrd
`-- bin
    `-- busybox

Creiamo lo script init

Ora dobbiamo creare lo script init, ovvero lo script che verrà eseguito dal kernel dopo l'inizializzazione dei driver e che è incaricato di risolvere i problemi su citati, cioè:

  • caricare eventualmente i moduli del kernel per i controller USB e per il file system ext3/4
  • dare il tempo ai controller USB di rilevare la pennina e montare, dopo averla scovata, la root directory
  • eseguire il vero processo init della distribuzione

Prima di cimentarci nella risoluzione di questi problemi dobbiamo notare che init, per come lo vogliamo utilizzare noi, è uno script, e in quanto tale ha bisogno di un interprete, la busybox può fare questo per noi visto che al suo interno ha anche una piccola shell. Andiamo nella directory /tmp/initrd/bin e creiamo un link simbolico a busybox in questo modo:

# ln -s busybox ash

e quindi con un qualsiasi editor di testo creiamo il file /tmp/initrd/init e mettiamoci come prima riga:

#!/bin/ash

Caricare i moduli del kernel necessari al rilevamento della periferica USB e del file system ext3/4

Il kernel huge è compilato con il supporto sia alle periferiche USB, sia al file system ext3 (o ext4) in maniera statica, e quindi ci permette di superare in maniera trasparente questo problema.
Si fa notare che il fatto di avere il supporto compilato in maniera statica nel kernel è un fattore da non sottovalutare. Infatti l'ambiente dell'initrd dovrebbe essere il più generale possibile, se spettasse all'initrd (e quindi allo script init) caricare qualche modulo del kernel, allora l'initrd non sarebbe più indipendente, ma al suo interno dovrebbe avere i moduli compilati per il kernel specifico che lo ha eseguito.

Dare il tempo ai controller USB di rilevare la pennina e montaggio della root directory

Abbiamo installato sulla nostra pennina USB un file system del tipo ext3 (o ext4) che abbiamo anche etichettato con il nome di 'minislack'. Bene, grazie alla capacità del comando mount di utilizzare il nome di etichetta per identificare un file system, il problema può essere risolto semplicemente mettendo nello script init quanto segue:

mount -n proc -t proc /proc
while ! mount -n -r -L minislack /mnt 2> /dev/null;
 do
   sleep 1
 done
umount -n /proc

Il "montaggio" del file system proc è necessario in quanto il comando mount fa uso di questo file system per scovare l'etichetta 'minislack'.
Il ciclo while con lo sleep non fa altro che dare il tempo necessario ai driver USB del kernel di rilevare la pennina. Quindi la nostra root directory, o meglio il file system che noi abbiamo etichettato come 'minislack' sarà montato nella directory /mnt a prescindere dal device a cui il driver USB (e più precisamente il modulo che gestisce le periferiche di archiviazione di massa USB, l'usb_storage) lo ha collegato.

Nelle sei righe di codice precedenti abbiamo:

  • usato il comando mount
  • caricato il file system proc nella directory /proc
  • usato il device null per ridirigere lo standard error del comando mount
  • usato il comando sleep per far attendere alla shell 1 secondo
  • montato la root directory in /mnt
  • utilizzato il comando umount

per quanto potevano sembrare innocenti, quelle sei righe implicano:

  • che il kernel al momento dell'esecuzione di queste righe, abbia il supporto al procfs e al tipo di file system della root directory che montiamo su /mnt (nel nostro caso il kernel huge ce li ha entrambi in maniera statica)
  • che esistano i programmi mount, umount e sleep
  • che esistano il device /dev/null e quello al quale sarà collegata la pennina USB (è vero che mount può scovare il device grazie all'etichetta del suo file system, ma è altrettanto vero che poi mount dovrà montare questo device)
  • che esistano le directory /proc e /mnt

La busybox può comportarsi come mount semplicemente facendo un link simbolico ad essa chiamato appunto mount, il problema è che quello fornito dalla busybox non è in grado di scovare le etichette dei file system (non riconosce il flag -L). Abbiamo necessariamente bisogno del comando mount del pacchetto util-linux (dalla Slackware 12.1 e successive, il pacchetto si chiama util-linux-ng) contenuto sempre nella directory della serie a/ della Slackware.
Copiamo quindi il comando mount come segue:

# cp -p /bin/mount /tmp/initrd/bin

ora però dobbiamo copiare anche le librerie condivise di cui necessita. Vediamo quali sono lanciando:

# ldd /bin/mount
       linux-gate.so.1 =>  (0xffffe000)
       libblkid.so.1 => /lib/libblkid.so.1 (0xb7f80000)
       libuuid.so.1 => /lib/libuuid.so.1 (0xb7f7d000)
       libc.so.6 => /lib/libc.so.6 (0xb7e4e000)
       /lib/ld-linux.so.2 (0x80000000)

Creiamoci la directory lib all'interno del nostro initrd con:

# mkdir /tmp/initrd/lib

e copiamoci dentro le librerie condivise con:

# cp -p /lib/libblkid.so.1 /lib/libuuid.so.1 /lib/libc.so.6 /lib/ld-linux.so.2 /tmp/initrd/lib

Si noti che i file originali probabilmente sono link simbolici, ma il comando cp copierà il file al quale puntano e non il link.

** NOTA **

Su slackware 13.1 il comando mount necessita di altre librerie:

# ldd /bin/mount
       linux-gate.so.1 =>  (0xffffe000)
       /usr/lib/libv4l/v4l1compat.so (0xb7838000)
       /usr/lib/libv4l/v4l2convert.so (0xb7836000)
       libblkid.so.1 => /lib/libblkid.so.1 (0xb77eb000)
       libuuid.so.1 => /lib/libuuid.so.1 (0xb77e7000)
       libc.so.6 => /lib/libc.so.6 (0xb7683000)
       libv4l1.so.0 => /usr/lib/libv4l1.so.0 (0xb767e000)
       libv4l2.so.0 => /usr/lib/libv4l2.so.0 (0xb7674000)
       /lib/ld-linux.so.2 (0xb783b000)
       libpthread.so.0 => /lib/libpthread.so.0 (0xb765b000)
       libv4lconvert.so.0 => /usr/lib/libv4lconvert.so.0 (0xb75ef000)
       librt.so.1 => /lib/librt.so.1 (0xb75e5000)
       libm.so.6 => /lib/libm.so.6 (0xb75bf000)

Quindi sarà necessario copiare anche le nuove librerie:

# cp -p /usr/lib/libv4l/v4l1compat.so /usr/lib/libv4l/v4l2convert.so /usr/lib/libv4l1.so.0 /usr/lib/libv4l2.so.0 /tmp/initrd/lib
# cp -p /lib/libpthread.so.0 /usr/lib/libv4lconvert.so.0 /lib/librt.so.1 /lib/libm.so.6 /tmp/initrd/lib

Su Slackware 13.37 le dipendenze di mount sembrano essere le stesse della 12, ma anche se non risulta con ldd, serve anche /lib/libm.so.6. Quindi rispetto alla 12 bisognerà copiare anche libm.so.6:

# cp -p /lib/libm.so.6 /tmp/initrd/lib

Su Slackware 14.0 le dipendenze diventano:

# ldd /bin/mount
       linux-gate.so.1 (0xf771b000)
       libblkid.so.1 => /lib/libblkid.so.1 (0xf76b3000)
       libmount.so.1 => /lib/libmount.so.1 (0xf7687000)
       libuuid.so.1 => /lib/libuuid.so.1 (0xf7683000)
       libc.so.6 => /lib/libc.so.6 (0xf74fe000)
       /lib/ld-linux.so.2 (0xf771c000)

Anche qui non risulta /lib/libm.so.6, ma è necessaria per far funzionare mount. Vanno copiate tutte in questo modo:

# cp -p /lib/libblkid.so.1 /lib/libmount.so.1 /lib/libuuid.so.1 /lib/libc.so.6 /lib/libm.so.6 /lib/ld-linux.so.2 /tmp/initrd/lib

** FINE NOTA **

Per il comando umount e sleep invece possiamo tranquillamente usare quelli della busybox, quindi andiamo nella directory /tmp/initrd/bin e facciamo:

# ln -s busybox umount
# ln -s busybox sleep

Il programma mount l'abbiamo utilizzato passandogli anche il flag -n, dicendogli quindi di non scrivere quello che sarà il file /etc/mtab, benché esso non lo scriva, vuole comunque leggerlo per controllare se il file system che si sta tentando di montare non sia già stato montato. Dobbiamo quindi creare il file vuoto /tmp/initrd/etc/mtab:

# mkdir /tmp/initrd/etc
# touch /tmp/initrd/etc/mtab

Proseguiamo quindi con la creazione del device null e dei possibili device a cui sarà collegata la pennina USB. In generale la pennina USB viene vista come una periferica SCSI disk e quindi sarà attaccata ad un device del tipo /dev/sdXY dove X varia a seconda di quante periferiche di archiviazione rilevate come SCSI (ad esempio i dischi sata) sono state trovate prima della pennina, mentre Y rappresenta una qualsiasi partizione.
Se, ad esempio, un PC non ha nessun disco rilevato come SCSI e ci si inserisce una pennina con tre partizioni, queste tre partizioni saranno collegate rispettivamente ai device: sda1, sda2 e sda3.

Y allora la possiamo ricavare facilmente, infatti all'inizio abbiamo supposto che la nostra pennina avesse solo una partizione e che essa (la partizione) venisse attaccata ad device /dev/sda1, allora Y=1 e la pennina sarà sempre collegata ad un device dal nome /dev/sdX1.
Quindi creiamoci la directory in cui inserire i device:

# mkdir /tmp/initrd/dev

e copiamoci subito dentro il device /dev/null con:

# cp -R /dev/null /tmp/initrd/dev

Al momento attuale gli SCSI disk sono gestiti dal device driver con major number 8. Questo device driver è in grado di gestire sino a 15 partizioni per ogni disco, questo vuol dire che due device con X consecutive e con uguale Y hanno una distanza (in termini di minor number) pari a 16. Ad esempio il device sda avrà un minor number uguale a 0 laddove il device sdb avrà invece minor number uguale a 16, e così via.

Possiamo allora creare i device con:

# mknod /tmp/initrd/dev/sda1 b 8 1
# mknod /tmp/initrd/dev/sdb1 b 8 17
# mknod /tmp/initrd/dev/sdc1 b 8 33
# mknod /tmp/initrd/dev/sdd1 b 8 49

Ora per rendere tutto coerente con quanto scritto sempre nelle sei innocenti righe di codice inserite nel file init, non ci resta che creare due directory vuote nelle quali verranno montati i file system proc e quello contenente la nostra directory radice.

# mkdir /tmp/initrd/proc /tmp/initrd/mnt

Eseguire il vero processo init

L'ultimo passo che deve eseguire lo script init dell'initrd è quello di lanciare il vero processo init situato nella directory radice della distribuzione e poi liberare la memoria allocata.
I passi teorici da eseguire sono:

  • spostare la directory radice dell'initrd sulla directory radice della distribuzione
  • smontare l'initrd
  • deallocare la memoria allocata dal kernel per l'initrd
  • eseguire il vero processo init

Che poi praticamente, dato che per ognuno dei passi precedenti esiste uno specifico programma che lo esegue, diventa:

  • cd /mnt; mkdir initrd; pivot_root . initrd
  • umount /initrd
  • blockdev --flushbufs /dev/ram0
  • exec chroot . /sbin/init $@

Il comando pivot_root ultimamente sembra non comportarsi bene nell'ambiente dell'initrd. Fortunatamente la busybox ha al suo interno un programma che dovrebbe eseguire tutti i passi precedenti, il comando si chiama switch_root e come al solito quindi basta fare un link simbolico a busybox entrando in /tmp/initrd/bin ed eseguendo:

# ln -s busybox switch_root

Ora non resta che inserire nello script init quanto segue:

exec switch_root /mnt /sbin/init $@

NOTA: si noti il passaggio a /sbin/init dei parametri $@, questi sono i parametri che il kernel non ha riconosciuto nella sua riga di comando (quella passatagli dal loader), e che quindi passa al comando che esegue.

Lo script init nella sua interezza

Riassumendo, lo script /tmp/initrd/init è questo:

#!/bin/ash
# Aspetto finché i driver USB non rilevano la pennina e monto la vera directory radice
mount -n proc /proc -t proc
while ! mount -n -r -L minislack /mnt 2> /dev/null;
 do
    sleep 1;
 done
umount /proc

# Avvio il vero /sbin/init
exec switch_root /mnt /sbin/init $@

questo script deve essere eseguito dal kernel è quindi dobbiamo assicurarci che abbia i diritti di esecuzione:

# chmod u+x /tmp/initrd/init

Creazione dell'archivio cpio compresso initrd.gz

La directory /tmp/initrd ora dovrebbe essere così strutturata:

# tree /tmp/initrd
  /tmp/initrd/
  |-- bin
  |   |-- ash -> busybox
  |   |-- busybox
  |   |-- mount
  |   |-- sleep -> busybox
  |   |-- switch_root -> busybox
  |   `-- umount -> busybox
  |-- dev
  |   |-- null
  |   |-- sda1
  |   |-- sdb1
  |   |-- sdc1
  |   `-- sdd1
  |-- etc
  |   `-- mtab
  |-- init
  |-- lib
  |   |-- ld-linux.so.2
  |   |-- libblkid.so.1
  |   |-- libc.so.6
  |   `-- libuuid.so.1
  |-- mnt
  `-- proc

6 directories, 17 files

Non resta altro da fare che creare un archivio cpio di questa directory, comprimerla con il comando gzip e renderla disponibile al loader di linux.

Partendo dal solito presupposto che la pennina sia collegata dal kernel al device sda1, la si monti ad esempio nella directory /mnt/memory con:

# mount /dev/sda1 /mnt/memory

si crei poi una directory in cui inserire l'archivio cpio compresso che è l'initrd con:

# mkdir /mnt/memory/boot

ed infine si crei l'archivio cpio compresso (il tanto sudato initrd):

# cd /tmp/initrd
# find . | cpio -o -H newc | gzip -9 -n > /mnt/memory/boot/initrd.gz

Quando, più in là nel wiki, si configurerà il loader di linux, si vedrà come utilizzare questo file.


Fase 2: installazione della distribuzione sulla pennina

Ora ci si occuperà di installare e configurare una serie minimale ma importantissima di pacchetti Slackware.
Ovviamente non ci sono limitazioni, se non quelle fisiche della pennina, al numero di pacchetti che il lettore può installare, ma per lo scopo di questo wiki è sufficiente installare i pacchetti essenziali a far partire la distribuzione.
I pacchetti che verranno installati si trovano tutti nella directory a/ della Slackware, quindi, supponendo che il CD o DVD della Slackware sia stato montato nella directory /mnt/dvd/, per prima cosa ci si deve spostare dentro questa directory con:

# cd /mnt/dvd/slackware/a

Un piccolo accorgimento

I pacchetti verranno installati sfruttando l'opzione -root dello script installpkg, alcuni dei pacchetti hanno uno script aggiuntivo, il famoso doinst.sh, che viene avviato dopo l'installazione del pacchetto. Gli script doinst.sh sono "chrootati" sulla pennina e devono poter eseguire comandi, quali ad esempio cd, rm o ln. Questo implica che:

  • il programma che il doinst.sh vuole eseguire deve essere presente sulla pennina
  • si abbiano i diritti di esecuzione sulla pennina

La prima implicazione è risolta installando i pacchetti in un ordine ben preciso, facendo in modo di installare prima i pacchetti che contengono i programmi usuali usati dai doinst.sh.

La seconda implicazione viene verificata se si esegue un piccolo accorgimento, ovvero smontare la pennina e rimontarla con l'opzione 'exec' del mount, in questo modo:

# umount /mnt/memory
# mount -o exec -rw /dev/sda1 /mnt/memory

I pacchetti da installare

La domanda è semplice, come si determinano i pacchetti che si devono installare?
La risposta non è altrettanto semplice, sicuramente ci sarà il programma /sbin/init per avere un collegamento all'initrd creato nella 'Fase 1', ma poi? Poi bisogna seguire l'init e capire cosa esegue, in modo da fargli trovare i programmi che tenta di eseguire. Se è necessario, bisogna anche seguire i programmi che init esegue per capire cosa fanno e se hanno bisogno di altri programmi o file di configurazione.
In generale quindi, il primo file da analizzare è /etc/inittab, file di configurazione di init, ci si accorge quindi che init esegue una serie di script di inizializzazione, e quindi bisogna seguire questi script per capire cosa fanno.

Per lo scopo di questo wiki il lavoro è stato già fatto dall'autore e quindi verranno segnalati solo i passi fondamentali da fare affinché la distribuzione possa partire.

Qui si riporta l'elenco dei pacchetti che devono essere installati nell'ordine di seguito riportato (l'ordine è importante solo per i primi tre pacchetti). Accanto al nome del pacchetto vi è una piccola descrizione di cosa contiene:

a/aaa_base              --->    Crea tutte le directory base
a/coreutils             --->    Programmi utilizzati dagli script doisnt.sh
a/glibc-solibs          --->    La libreria glibc, usata da molti eseguibili (tra cui init)
a/glibc-zoneinfo        --->    Contiene lo script timeconfig che verrà usato in seguito
a/dialog                --->    Usato per visualizzare i box dei dialoghi da altri programmi
                                (tra cui timeconfig)
a/bash                  --->    La shell
a/etc                   --->    File di configurazione dei programmi utilizzati
a/util-linux            --->    Contiene, tra l'altro, il programma mount. Dalla Slackware 12.1 alla 13.1,
                                il pacchetto si chiama util-linux-ng
a/sysvinit              --->    Contiene il programma init
a/sysvinit-scripts      --->    I famosi script rc.d della Slackware, invocati da init
a/module-init-tools     --->    modprobe e altri programmi per gestire i moduli
a/e2fsprogs             --->    Comandi per i filesystem ext2/3/4
a/devs                  --->    I device, senza di questi....
a/findutils             --->    find, usato dagli script di inizializzazione
a/aaa_elflibs           --->    Libreria libtermcap per i terminali
a/aaa_terminfo          --->    File di informazione sui terminali usati dalla libreria libtermcap
a/shadow                --->    Contiene, tra l'altro, i programmi login e sulogin
a/grep                  --->    grep, usato dagli script di inizializzazione
a/procps                --->    ps, usato dagli script di inizializzazione
a/kernel-huge           --->    Il kernel...
a/kernel-modules        --->    ... i suoi moduli

** NOTA **

Su slackware 13.1 è necessario anche il seguente pacchetto

l/v4l-utils             --->    Librerie necessarie ai programmi di sistema (ad es: mount)

mentre su Slackware 14.0 non troveremo module-init-tools, ma al suo posto:

a/kmod                  --->    modprobe e altri programmi per gestire i moduli

** FINE NOTA **

Per installare questi pacchetti si deve eseguire installpkg con l'opzione -root /mnt/memory, ad esempio:

# installpkg -root /mnt/memory aaa_base-12.0.0-noarch-1.tgz

Una facile configurazione

Come per la domanda 'Quali pacchetti si devono installare?', così la risposta alla domanda 'Cosa si deve configurare?' dipende sempre dall'amministratore del sistema e da cosa esso intenda far eseguire all'avvio della macchina.
Nel wiki si intende lasciare intatti gli script di inizializzazione fatti da Patrick J. Volkerding, creatore della Slackware, e quindi si procederà nella minima configurazione necessaria proprio a questi script di inizializzazione.

/etc/fstab

Si comincia con il creare il file /etc/fstab come segue:

# echo -e "LABEL=minislack\t\t/\text3\trw,noatime\t0 1" > /mnt/memory/etc/fstab

Nel caso si abbia scelto ext4 diventa:

# echo -e "LABEL=minislack\t\t/\text4\trw,noatime\t0 1" > /mnt/memory/etc/fstab

/etc/hardwareclock

Un altro file richiesto dagli script di inizializzazione della Slackware è il file /etc/hardwareclock che indica come è impostato l'orologio hardware. In effetti questo file non contiene granché, ma viene consigliato di editarlo/crearlo tramite lo script /usr/sbin/timeconfig, quindi bisogna eseguire lo script spostandogli la directory root, in questo modo:

# cd /mnt/memory
# chroot . usr/sbin/timeconfig


Fase 3: impostare il boot loader e testare il tutto

L'ultima cosa da fare è quella di rendere la pennina "bootabile", ovvero di inserire nel suo primo settore, il famoso settore di boot. Per fare questo basta creare un file lilo.conf ad-hoc, e poi lanciare LILO passandogli il file appena creato.
Si crei quindi il file, ad esempio /mnt/memory/etc/lilo.conf, direttamente sulla pennina in modo che rimanga con essa, con all'interno quanto segue:

boot = /dev/sda
backup = ""
map=/mnt/memory/boot/map

compact
lba32
large-memory

image = /mnt/memory/boot/vmlinuz
  initrd = /mnt/memory/boot/initrd.gz

Si noti l'opzione 'initrd', con la quale si indica al kernel che deve usare l'initrd creato nella 'Fase 1'. Ora non resta quindi che lanciare LILO come segue:

# lilo -C /mnt/memory/etc/lilo.conf

e riavviare il PC facendogli fare il boot dalla pennina USB.
Con la configurazione minimale che si è fatta nella 'Fase 2', basta, al momento del login, inserire l'username di 'root' per avere una shell con tutti i privilegi del super-utente.


Esempi d'uso

Una volta che si ha una pennina USB "bootabile", con all'interno un intera distribuzione, serve solo la fantasia per farci quello che ci pare.
Esempi d'uso potrebbero essere quello di crearsi una distribuzione adatta alla lettura di contenuti multimediali, in questo modo basta trovare un PC per vedere un DVD o ascoltare della musica, senza preoccuparsi che il PC sia dotato di tutti i programmi o codec adatti.

Un altro esempio è che si ha sempre a portata di mano un "disco di ripristino". Se la distribuzione installata sul PC non dovesse partire perché ci si è divertiti un po' troppo con i file di configurazione, si può sempre fare il boot del PC con la pennina e provvedere a rimediare agli eventuali danni che si è combinati.


Appendice

A: altri pacchetti utili

Se si vuole rendere la distribuzione che si è installata sulla pennina un po' più indipendente, bisogna essere in grado di manipolare i pacchetti della Slackware, non solo, ma sarebbe anche carino poter utilizzare tutta una serie di comandi utili ad un sistemista. Quindi, oltre all'insieme minimo di pacchetti menzionati nella sezione 'I pacchetti da installare', qui di seguito c'è un elenco dei pacchetti che rendono la distribuzione sulla pennina, più user-friendly:

a/pkgtools           --->    Per gestire i pacchetti della Slackware
a/bin                --->    Usato dagli script di pkgtools
a/sed                --->    Usato dagli script di pkgtools
a/gzip               --->    Usato dagli script di pkgtools
a/tar                --->    Usato dagli script di pkgtools
a/xz                 --->    Usato dagli script di pkgtools per il nuovo formato '.txz' della Slackware 13
ap/man               --->    Il comando man più tornare molto utile
ap/man-pages         --->    Le pagine di manuale di molti comandi
ap/groff             --->    Il formattatore usato da man
a/cxxlibs            --->    Libreria c++ standard usata da groff
a/less               --->    Il comando che man usa per visualizzare le pagine di manuale
a/udev               --->    Utile se si vogliono usare driver che necessitano di firmware
ap/nano              --->    Il famoso e semplice editor di testo
a/bzip2              --->    Sempre più spesso si trovano archivi bzip
a/reiserfsprogs      --->    Per gestire il famoso file system reiser


Ringraziamenti

Ringrazio ZeroUno per i suoi consigli e le sue prove.

Note per Slackware 13.1 a cura di Ansa89.

Integrazioni per Slackware 13.37-14.0, ext4 e tune2fs a cura di sya54M.

Per qualsiasi cosa scrivetemi pure:
targzeta

Strumenti personali
Namespace

Varianti