Chapter 10. Il concetto di boot

Table of Contents

10.1. Il boot con l'initial ramdisk
10.2. Il programma init
10.3. I runlevel
10.4. Cambiare il runlevel
10.5. Gli script init
10.6. L'editor dei runlevel editor di YaST
10.7. SuSEconfig e /etc/sysconfig
10.8. L'editor sysconfig di YaST

Abstract

Caricare ed inizializzare un sistema Unix non è una banalità, neanche per amministratori di sistema esperti. Questo capitolo vi introduce brevemente il concetto di caricamento di che mette in pratica l'inizializzazione del sistema secondo la specificazione LSB (versione 1.3.x); (cfr. la sezione Section A.4, “Standard e specificazioni”).

Con la frase lapidaria “Uncompressing Linux...” il kernel assume il controllo di tutto l'hardware del sistema. Esso verifica ed imposta la console (ovvero i registri del BIOS della scheda grafica ed il formato di output dello schermo), per poi leggere i parametri del BIOS ed inizializzare le interfacce elementari della scheda madre. In seguito, i driver (che fanno comunque parte del kernel) esaminano l'hardware disponibile ed eventualmente lo inizializzano. Dopo la verifica delle partizioni ed il mount del file system "root", il kernel avvia il programma init. Con init, viene a sua volta avviato il sistema vero e proprio, con i rispettivi programmi di servizio e configurazione. Sarà poi il kernel a gestire tutto il sistema: controllerà il tempo di elaborazione dei singoli programmi, metterà a disposizione la memoria necessaria e gestirà l'accesso all'hardware.

10.1. Il boot con l'initial ramdisk

10.1.1. La problematica

Non appena il kernel di Linux è caricato e il file system root (/) è montato, possono venire eseguiti i programmi e caricati altri moduli del kernel che mettano a disposizione funzionalità supplementari. Il mount del file system root è tuttavia soggetto ad alcune premesse: per poter comunicare con il dispositivo su cui si trova il file system root (specialmente driver SCSI), il kernel ha bisogno dei driver corrispondenti. Inoltre, il kernel deve contenere il codice necessario per leggere il file system (ext2, reiserfs, romfs etc.). E' anche possibile che il file system root sia già cifrato; in questo caso, per fare il mount, è necessaria la password/chiave.

Per quanto riguarda il problema dei driver SCSI, si può pensare a diverse soluzioni: il kernel può contenere tutti driver possibili e immaginabili. Il che non rende le cose più facili, dal momento che potrebbero verificarsi dei conflitti, ed inoltre gonfierebbero il kernel. Un'altra possibilità consiste nel mettere a disposizione diversi kernel che contengano solo uno o pochi driver SCSI. Anche questo metodo presenta delle difficoltà, poiché necessita di un gran numero di kernel differenti, ed in più la presenza di diversi kernel ottimizzati (ottimizzazione Pentium, SMP, etc.).

Caricare il driver SCSI come modulo porta alla questione generale risolta dal concetto dell'initial ramdisk: la possibilità di eseguire programmi user space già prima del mount del file system root.

10.1.2. Il concetto dell'initial ramdisk

L'initial ramdisk (denominato anche initdisk o initrd) risolve proprio questo tipo di problema. Il kernel di Linux consente di caricare un (piccolo) file system in una ramdisk ed eseguire lì dei programmi, prima che venga montato il file system root vero e proprio. Il caricamento dell'initrd viene svolto dal bootloader (, etc.); tutti questi bootloader necessitano soltanto le routine del BIOS per caricare i dati dal dispositivo di caricamento. Una volta che il bootloader carica il kernel, potrà caricare anche l'initial ramdisk. In questo modo non sono necessari speciali driver.

10.1.3. Processo di caricamento con initrd

Il bootloader carica il kernel e initrd nella memoria e inizializza il kernel, comunicandogli che è disponibile un initrd e indicandogli la sua locazione nella memoria. Se initrd è compresso (e, generalmente, lo è), il kernel lo scompatta e lo monta come file system root temporaneo. A questo punto, nell'initrd viene inizializzato un programma dal nome linuxrc. Questo programma può svolgere tutte le funzioni necessarie a montare il vero file system root. Quando linuxrc ha concluso, l'initrd (temporaneo) viene “smontato” (ingl. unmounted) ed il processo di boot procedere con il montaggio del vero file system root. Il montaggio di initrd e l'esecuzione di linuxrc possono quindi venire considerati come un breve intermezzo durante una normale procedura di caricamento. Dopo il boot della partizione root, il kernel prova a montare initrd sulla directory /initrd. Se non ci riesce, ad esempio perché non trova un punto di mount /initrd, esso proverà a smontare initrd. Se non gli riesce neanche questo, il sistema continuerà a funzionare come al solito, ma la memoria occupata da initrd non verrà mai liberata e non potrà essere usata da nessun'altra componente del sistema.

10.1.3.1. Il programma linuxrc

Il programma linuxrc in initrd deve portare il nome linuxrc e trovarsi nella directory root di initrd. Inoltre, deve essere eseguibile solamente dal kernel. Ciò significa che linuxrc può senz'altro avere un link dinamico; in questo caso, le librerie condivise devono come al solito essere disponibili completamente sotto /lib in initrd. Inoltre linuxrc può essere anche uno script di shell, ragion per cui dovrà esserci una shell detta anche finestra di comando in /bin. In altre parole, initrd deve contenere un sistema Linux minimo che permetta l'esecuzione del programma linuxrc. All'installazione di , viene usato un linuxrc con un link statico, per poter mantenere initrd il più piccolo possibile. linuxrc viene eseguito con i privileggi di root.

10.1.3.2. Il vero file system root

Non appena linuxrc ha finito, initrd viene smontato e rimosso, il processo di boot continua normalmente con il kernel che monta il vero file system root. Cosa debba venire montato come file system root può essere determinato da linuxrc. linuxrc dovrà prima montare il file system /proc e scrivere il valore del vero file system root in forma numerica sotto /proc/sys/kernel/real-root-dev.

10.1.4. Bootloader

La maggioranza dei bootloader (soprattutto , e syslinux) sono in grado di usare initrd. Ecco come istruire i singoli bootloader ad utilizzare un initrd:

immettere la riga seguente in /boot/grub/menu.lst: Dato che l'indirizzo di caricamento di initrd viene scritto nell'immagine del kernel già caricata, il comando initrd deve seguire al comando kernel.

immettere la seguente riga in /etc/lilo.conf: Il file /boot/initrd è l'initial ramdisk. Esso può (ma non deve) essere compresso.

syslinux

immettere la seguente riga in syslinux.cfg: La riga può contenere ulteriori parametri.

10.1.5. L'impiego di initrd con

10.1.5.1. Installazione del sistema

initrd viene usato già da parecchio tempo per l'installazione; se si esegue l'installazione manualmente l'utente può caricare moduli del kernel in linuxrc ed eseguire le impostazioni necessarie all'installazione. linuxrc inizializza poi , che esegue l'installazione. Una volta che abbia terminato il suo lavoro, comunica a linuxrc, dove trovare il file system root appena installato. linuxrc scrive questo valore in /proc ed esegue un reboot. In seguito si riavvia e vengono installati i rimanenti pacchetti per il sistema appena installato.

10.1.5.2. Eseguire il boot del sistema installato

In passato, metteva a disposizione per l'installazione più di 40 kernel, che si differenziavano uno dall'altro per il fatto che ognuno di essi conteneva un determinato driver SCSI. Ciò era necessario per poter montare il file system root dopo il caricamento. Altri driver potevano venire aggiunti in un secondo momento sotto forma di moduli.

Poiché, nel frattempo, esistono anche kernel ottimizzati, questo concetto non è più proponibile: ora sarebbero necessarie più di 100 immagini di kernel.

Pertanto, si usa un initrd ormai anche per il normale avvio del sistema. Il funzionamento è analogo a quello della installazione. Il linuxrc qui usato è però solo uno script di shell con l'unico compito di caricare determinati moduli. Si tratta, di norma, di un solo modulo; cioè di quel driver SCSI necessario per accedere al file system root.

10.1.5.3. Creare un initrd

La creazione di un initrd avviene tramite lo script mkinitrd (ex mk_initrd). In , i moduli da caricare vengono stabiliti tramite la voce INITRD_MODULES in /etc/sysconfig/kernel. Dopo un'installazione, questa variabile riceve automaticamente i valori giusti (il linuxrc dell'installazione sa quali moduli sono stati caricati). Degno di nota è il fatto che i moduli vengono caricati nella stessa sequenza in cui appaiono alla voce INITRD_MODULES. Ciò è particolarmente importante nel caso vengano usati più driver SCSI, poiché, altrimenti, cambierebbe la denominazione dei dischi rigidi. A rigor di logica, sarebbe sufficiente caricare solo driver SCSI necessari all'accesso al file system root. Poiché, però, il caricamento automatico di ulteriori driver SCSI è problematico, carichiamo tutti i driver SCSI usati durante l'installazione tramite initrd.

[Important]Important

Poiché il caricamento di initrd tramite il bootloader viene eseguito come il caricamento del kernel stesso ( annota nel suo file mappa la locazione dei file), dopo ogni modifica di initrd, si deve reinstallare il bootloader; se utilizzate questo non è necessario.

10.1.6. Possibili difficoltà – kernel auto-compilati

Se compilate un kernel spesso può subentrare il seguente problema: per abitudine, il driver SCSI viene linkato al kernel, senza modificare l'attuale initrd. Durante il boot avviene la seguente cosa: il kernel contiene di già il driver SCSI, l'hardware viene riconosciuto. initrd cerca però di caricare nuovamente il driver sotto forma di modulo; con alcuni driver SCSI (specialmente con aic7xxx), ciò porta all'arresto del sistema. A dire il vero, questo è un errore del kernel (un driver già esistente non dovrebbe venire caricato una seconda volta come modulo); il problema è però già noto in riferimento ai driver seriali.

Questo incoveniente può essere risolto in modi diversi: configurare il driver come modulo (in questo caso verrà caricato correttamente in initrd), o eliminare initrd da /etc/lilo.conf o rispettivamente da /etc/grub/menu.lst cosa che produce lo stesso effetto di eliminare il driver da INITRD_MODULES ed immettere mkinitrd, che, a sua volta, constaterà che non è necessario alcun initrd.

10.1.7. Prospettiva

In futuro è pensabile che initrd possa venire usato per molte più cose (e più complesse), non solo per caricare i moduli necessari all'accesso a /.

  • File system root su software RAID (linuxrc imposta i dispositivi md)

  • File system root su LVM

  • File system root è cifrato, (linuxrc richiede la password)

  • File system root su un disco rigido SCSI connesso a un adapter PCMCIA

10.1.7.1. Ulteriori informazioni

  • /usr/src/linux/Documentation/ramdisk.txt

    (Disponibile solo se sono stati installati i sorgenti del kernel)

  • La pagina di manuale di initrd.