Linux Base - File System
Edizioni ByteMan



File System (parte 1)



L'albero delle directory

L'organizzazione del filesystem di GNU/Linux è piuttosto diversa da quella di Windows alla quale probabilmente si è abituati. A prima vista sembra criptica: non ci sono quelle belle cartelle con nomi esplicativi chiamate "Programmi" o "Documenti", però occorre tenere presente che UNIX è stato scritto da hacker per gli hacker, per cui "meno lettere possibile, ma significative". Come si può notare i nomi delle directory hanno nomi mediamente di quattro lettere e quando si lavora al terminale di un server senza interfaccia grafica, meno si scrive e più si è veloci.

Gli eseguibili, in particolare quelli di sistema, non vengono disseminati dappertutto, ma seguono delle regole ben precise. Si rinuncia ad un po' di arbitrio in cambio di una maggiore organizzazione.
Unix a differenza di Win ha un unico albero nel quale vengono innestati i rami di ogni periferica che viene "montata". In Windows ogni disco (anche se astratto, di rete) invece è un albero separato individuato da una lettera (A:, B:, C:, D:, ...) ciascuno con la sua root e le sue directory, tutto ciò è di derivazione DOS (Disk Operating System) che è un sistema operativo basato sui dischi.


/E' il punto di origine di tutto il filesystem e viene indicato con il nome di radice o root (Attenzione a non confonderla con la directory /root). Non deve contenere file (se non il kernel in casi particolari) ma solo le directory stabilite dallo standard FHS.
/binContiene i programmi eseguibili fondamentali per la gestione del sistema (binaries, binari) che possono essere usati sia dall'amministratore (/root) sia dagli utenti (in /sbin che vedremo dopo vanno i binari di uso esclusivo del superutente). I comandi che impareremo ad usare più tardi sono tutti contenuti in questa directory!
/bootBoot contiene tutto ciò che serve al processo di avvio (bootstrap) del sistema: per esempio il kernel (nocciolo del sistema operativo) stesso.
/devDevice contiene i file speciali di dispositivo, uno per ogni dispositivo fisico del computer. In pratica è come se si trattasse di "driver" dei dispositivi. In Unix ogni cosa è un file.
/etcContiene i dati di configurazione del computer, distribuiti su molti file ed ulteriori sottodirectory dal nome a volte esplicativo a volte meno. Tutti i file sono di tipo ASCII e sono modificabili, con qualsiasi editor di testo, secondo la sintassi propria dell'applicazione. I comandi grafici per la gestione del sistema vanno a modificare i file che sono qui contenuti, quindi e' possibile una gestione mista grafica/testuale.
/homeHome contiene i dati personali di tutti gli utenti (tranne root) del sistema, suddivisi in una directory per ogni utente che ha solitamente come nome lo username dell'utente. Spessissimo si tratta di un filesystem secondario (un altro disco o partizione o condivisione di rete) montato in questo punto (per ragioni di sicurezza e di scalabilità)
/libLibraries contiene i file di libreria condivisi necessari per l'avvio del sistema e per i programmi di uso generale che si possono trovare in /bin e /sbin. Le librerie che riguardano solo programmi collocati in /usr non vanno qui. Prevede anche la subdirectory /lib/modules che contiene i moduli caricabili dal kernel.
/mntMount è il punto di innesto standard per filesystem montati temporaneamente. Normalmente dovrebbe essere vuota e riservata ai montaggi temporanei (come specificato da FHS v2.3) ma finora è stato uso comune montarvi permanentemente i filesystem ospiti /mnt/floppy, /mnt/cdrom, /mnt/removable (zip, usb). Montare e smontare i filesystem ospiti è una caratteristica di Unix.
/optOptional serve per contenere applicazioni opzionali ed altri software, ognuno in una sua sottodirectory. I file di configurazione di questi pacchetti dovrebbero poi andare in /etc/opt e i file variabili in /var/opt. Peccato che non sempre questa convenzione venga rigorosamente rispettata, spesso in favore di un po' di subdirectory aggiunte in /usr.
/procProcesses è una directory vuota che viene usata dal SO per montare il filesystem virtuale omonimo (solo in GNU/Linux non fa parte dell'HFS). I file e le directory contenuti in questo filesystem virtuale sono indispensabili ai programmi che hanno la necessità di accedere alle informazioni sul sistema.
/rootQuesta è la home del superutente (root) contiene i dati (documenti) e le impostazioni dell'utente amministratore del sistema. Ci sono molti validi motivi per tenerla separata dalle home degli utenti comuni: impedire più facilmente accessi indesiderati, poterla mantenere nel filesystem principale anche se le home degli utenti sono su un filesystem separato in modo da essere in grado di accedervi anche quando il sistema viene avviato in condizioni di emergenza e non si possono montare altri filesystem.
/sbinSystem Binaries contiene i binari di sistema, utility per l'amministrazione del sistema essenziali per avvio, restore, riparazione del sistema in aggiunta a quelli contenuti in /bin.
/tmpContiene i file temporanei dei programmi. Potrebbe addirittura essere collocata in un disco virtuale basato su memoria volatile (RAMdisk).
/usrCostituisce la seconda maggior sezione del filesystem. Si compone di una struttura molto articolata, /usr contiene solo dati condivisibili e statici (ogni file di contenuto variabile o che contenga opzioni specifiche per la macchina locale dovrebbe stare in una delle directory che hanno questo scopo: /etc o /var). In pratica /usr replica l'albero principale per contenere tutti i programmi non essenziali per l'amministrazione del sistema (ovvero tutti quelli che usiamo di più se non facciamo il sysadmin di mestiere.)
/varContiene le directory e i file di contenuto variabile (cioè un po' di tutto di quello che non può stare in /usr perchè /usr deve poter funzionare anche in sola lettura.


Lo standard FHS

La disposizione di directory e file di Unix (e quindi di GNU/Linux) segue lo standard FHS (Filesystem Hierarchy Standard) [con qualche piccola eccezione...(ad es: /proc)]. FHS è una raccolta di requisiti e linee guida per la disposizione di file e directory nei sistemi operativi Unix-like. Il suo scopo è quello di garantire l'interoperabilità di applicazioni, strumenti di amministrazione, ambienti di sviluppo e scripts, così come una maggiore uniformità nella documentazione di questi strumenti.

Attenzione a / (slash) e \ (backslash). Internet, e non solo, usa la convenzione UNIX, ed è per questo che gli indirizzi URL usano lo slash, esattamente come nei pathname Unix.
Ogni ramo (o anche sottoramo) può essere un filesystem diverso (periferica diversa o partizione diversa) che si dice montato (innestato) sull'albero.

In caso di installazioni toste si usa mettere alcune directory su dischi o partizioni separate (/boot, /home, /var, /usr, /usr/local, /tmp, /var) per mantenere intatti certi dati in caso di guasti hardware o upgrade del SO e mantenere il più leggero possibile il filesystem di base che deve partire nudo in caso di guai.
Il punto in cui si innesta nell'albero un filesystem separato si chiama mountpoint (punto di innesto).

Lo standard FHS v2.2 richiede, in particolare, che all'interno di / siano obbligatoriamente presenti (o soft-linkate) le seguenti directory: /bin /boot /dev /etc /lib /mnt /opt /sbin /tmp /usr /var. Sono richieste, solo se i relativi sottosistemi sono installati, anche: /home /lib (condivise per sistemi diversi) /root.
FHS v2.3 ha appportato alcune variazioni che alcune distribuzioni hanno già implementato: /media (punto di mount per filesistem ospitati costantemente floppy, cdrom, rimovibili), /srv.
Ed infine c'è sempre montata (ma non si vede) almeno una partizione di swap ovvero di memoria virtuale che si aggiunge alla RAM in caso di necessità. Nei sistemi Intel x86 si possono montare fino a 16 partizioni di swap contemporaneamente! In caso di problemi alla partizione che la ospita è possibile disattivare/attivare le aree di swap con i comandi #swapoff e #swapon.

Altre directory notevoli

Vediamo adesso alcune sottodirectory di particolare importanza ed alcune directory che sono state incluse recentemente dallo standard FHS o che vengono utilizzate solo da alcune distribuzioni.


/initrdFuori standard, usata da Mandrake solo durante l'avvio del sistema, poi praticamente vuota.
/mediaIntrodotta con lo standard FHS 2.3, è il punto di mount per filesistem ospitati costantemente floppy, cdrom, rimovibili.
/usr/binStrumenti ed applicazioni per gli utenti.
/usr/dictDizionari ed elenchi di parole. Viene lentamente sostituita dalla directory /usr/share/dict.
/usr/docDocumentazione varia di sistema.
/usr/gamesGiochi e passatempi.
/usr/infoFile per il sistema ipertestuale GNU Info.
/usr/libLibrerie utilizzate dagli strumenti ed applicazioni presenti in /usr/bin.
/usr/localGerarchia in cui vengono installati i programmi locali (che non possono essere eseguiti dalle macchine in rete con noi). L'albero che si dirama da questa directory non viene sovrascritto in caso di upgrade (aggiornamento) del sistema.
/usr/manI manuali in linea che vengono letti con il comando man.
/usr/shareContiene i dati che possono essere condivisi tra macchine con piattaforme hardware differenti (i386, alph, PPC...) (sono molto più di quelli che pensiamo possano esistere, l'interoperabilità è un miraggio solo nelle pubblicità dei SO proprietari.). Contiene anche le manpages in /usr/share/man (i comandi sono uguali e hanno le stesse opzioni su tutte le piattaforme. Se vi sedete davanti a un IBM S/370 o ad una macchina Sparc con Linux a bordo, sarete perfettamente in grado di usarla come il vostro portatile.). Alcune sue sottodirectory hanno l'equivalente in /usr.
/usr/srcContiene il codice sorgente dei programmi da compilare e in /usr/src/linux il codice sorgente del sistema operativo stesso (prima o poi occorrerà imparare a ricompilarlo.)
/usr/tmpAltra directory per file temporanei.
/usr/X11R6Contiene la gerarchia riguardante il sistema grafico di Unix ed i suoi programmi. Nella directory /usr/X1136/bin sono contenuti gli eseguibili attivati da X.
/var/localDati variabili relativi alla struttura /usr/local.
/var/logContiene i log dei programmi e di sistema (importante controllarli spesso).
/var/spoolContiene le code di stampa e delle e-mail ancora da consegnare agli utenti.
/var/wwwContiene le pagine web se c'è installato apache o un altro server web.







File System (parte 2)


Considerazioni sui File System

Un file system è, nel linguaggio corrente, un meccanismo con il quale i file sono immagazzinati e organizzati su un dispositivo di archiviazione, come un hard disk o un CD-ROM, e costituisce parte integrante di qualsiasi sistema operativo moderno. Più correttamente, un file system è l'insieme dei tipi di dati astratti necessari per la memorizzazione, l'organizzazione gerarchica, la manipolazione, la navigazione, l'accesso e la lettura dei dati.

I file system più comuni si appoggiano a dispositivi di archiviazione che offrono l'accesso ad un array di blocchi di dimensione fissa, generalmente chiamati settori, tipicamente di 512 byte l'uno. Il software che li supporta è responsabile dell'organizzazione di questi settori in file e directory, e tiene traccia dei settori che appartengono ai vari file e dei settori non utilizzati.

I file system tipicamente hanno tabelle che associano i nomi dei file con i file, usualmente collegando il nome del file ad un indice in una tabella di allocazione dei file (file allocation table) di qualche genere, come la FAT di un file system MS-DOS, o un inode in un file system di tipo Unix.
Le strutture delle directory possono essere ad un solo livello, oppure possono permettere una struttura gerarchica in cui delle directory possono contenere sottodirectory.


Il File System Journaled

I requisiti per un filesystem di moderna concezione sono: capacità di supportare grossi volumi fisici (oramai centinaia di gigabyte), integrità dei dati, riduzione della frammentazione interna ed esterna, recovery veloce in caso di crash e manipolazione in modo veloce ed efficiente sia dei file voluminosi sia dei file piccoli.

Un File System Journaled (con libro giornale) ha la capacità di recuperare lo stato consistente dell'hard disk in pochi secondi, la tecnica di recovery, ereditata dai database, si basa sulle transazioni. In caso di 'crash' del sistema, lo stato consistente del disco viene recuperato leggendo il Journal (libro giornale) e riapplicando le modifiche: quindi lo stato precedente.

In un filesystem non journaled lo stato consistente del disco passa attraverso l'analisi dei meta-data (i-node, directory, i-node map...) che richiede la scansione completa (blocco per blocco) del volume logico. Questo avviene in quanto la ricerca dei blocchi liberi avviene mappandoli in una sequenza di bit (detta comunemente 'struttura a bitmap'); più il filesystem cresce in dimensioni, più lo spazio occupato cresce di conseguenza: l'algoritmo di ricerca utilizzato è sequenziale.
ovviamente per filesystem di piccole dimensioni il sistema è comunque decisamente efficiente, e non penalizza le prestazioni del server.


Esempi di File System

L'elenco seguente include solo alcuni dei moltissimi tipi di file system conosciuti, è soprattutto orientato al mondo Linux, ma non può trascurare i prodotti Microsoft.


Altri File System

In questo elenco, per nulla completo, vengono brevemente citati altri tipi di file system usati o riconosciuti da Linux.








I permessi per l'accesso ai file

Ad ogni file Linux associa sempre l'utente che ne è proprietario (il cosiddetto owner) ed un gruppo di appartenenza, secondo il meccanismo degli identificatori di utente e gruppo (uid e gid).
Il controllo di accesso ai file segue un modello abbastanza semplice che prevede tre permessi fondamentali strutturati su tre livelli di accesso. I tre permessi di base associati ad ogni file sono:

mentre i tre livelli su cui sono divisi i privilegi sono:

L'insieme dei permessi viene espresso con un numero a 12 bit (espresso in ottale); di questi i nove meno significativi sono usati a gruppi di tre per indicare i permessi base di lettura, scrittura ed esecuzione e sono applicati rispettivamente al proprietario, al gruppo, a tutti gli altri.



I 3 bit più significativi non rivestono, per il momento, una particolare importanza e saranno oggetto di attenzione prossimamente. Il significato del tipo di accesso dipende a seconda che venga applicato ai file o alle directory.
Per un file: l'accesso in lettura permette di leggerne il contenuto, l'accesso in scrittura permette di modificarne il contenuto, l'accesso in esecuzione permette di eseguirlo (ammesso che si tratti di un eseguibile binario o di uno script di qualunque tipo).
Per una directory: l'accesso in lettura permette di leggerne il contenuto (poter conoscere l'elenco dei file in esse contenuti, di qualunque tipo essi siano), l'accesso in scrittura permette di modificarne il contenuto (creare, eliminare e rinominare i file), l'accesso in esecuzione permette di attraversare una directory.

I permessi si possono esprimere in due forme diverse: o con una una stringa alfabetica o con un numero ottale. La stringa utilizza le lettere r, w, x per rappresentare i permessi di lettura, scrittura ed esecuzione, mentre quando si utilizza la notazione ottale, il numero 4 rappresenta un permesso in lettura, il numero 2 rappresenta un permesso in scrittura e il numero 1 rappresenta un permesso in esecuzione. Si ottiene la combinazione di più tipi di permesso di accesso sommando le cifre necessarie.

La notazione numerica ottale è preferibile rispetto a quella simbolica essendo più completa e immediata. In particolare, se il numero non utilizza tutte le cifre, si intende che manchino quelle anteriori e che queste siano semplicemente azzerate. Per esempio, il permesso 755 (pari a 0755) indica che l'utente proprietario può leggere, modificare ed eseguire il file, mentre sia gli utenti del gruppo sia gli altri possono solo leggere ed eseguire il file.

Quando viene creato un file, questo appartiene automaticamente all'utente che lo crea e al gruppo principale dell'utente stesso. I permessi gli vengono attribuiti in base alla maschera dei permessi (umask). Questa maschera rappresenta i permessi che non vengono attribuiti. Di solito, il suo valore è 022 e con questo, non viene attribuito il permesso di scrittura (2) né al gruppo, né agli altri utenti.

E' evidente che la gestione dei permessi è affidata principalmente all'amministratore del sistema, il quale dispone di una serie di appositi comandi, ma anche i normali utenti (con qualche limitazione) possono effettuare delle modifiche.
Per modificare la modalità di accesso di un qualsiasi file di cui si sia proprietari si utilizza il comando chmod (change mode). Questo strumento accetta due argomenti: una operazione che specifica i permessi da concedere/revocare, e i nomi dei file su cui lavorare. L'operazione si avvale dei seguenti tre operatori:

+ aggiunge permessi
- rimuove permessi
= fissa come unici permessi

chmod go-w pippo          impedisce la scrittura al gruppo e agli altri 
chmod a+rw pippo          autorizza tutti a leggere e scrivere 
chmod a+x myscript        rende il file eseguibile da parte di tutti 
chmod go=r pippo          rende il file a sola lettura per il gruppo e gli altri 
chmod go= secret          rende il file privato, gruppo e altri senza permessi, nulla dopo l'operatore =








Il filesystem: gerarchia

Per file system si intende l'astrazione (metodo e protocolli) con cui un sistema operativo organizza i file su un supporto fisico di memorizzazione ad accesso casuale (floppy, cdrom, memoria, hard disk...). I sistemi operativi moderni tipicamente utilizzano un sistema gerarchico (diviso in directory e sottodirectory) e possono supportare nativamente uno o più diversi file system.
Linux vede ogni cosa come se fosse un file; spesso addirittura come un file di testo che, generalmente, può essere aperto, letto e modificato, se lo si ritiene opportuno. Alcuni esempi sono i file contenuti in /dev (devices) e /proc (process). La directory /dev è la posizione dove risiedono le periferiche collegate al Pc (l'hardware), mentre la directory /proc rappresenta letteralmente il contenuto della memoria di sistema, dagli irq al bus Pci, fino ai file temporanei. Non è assolutamente un buona idea apportare modifiche in /dev o /proc ma osservarne il contenuto può aiutare a capire il concetto che tutto in linux è considerato un file, in un modo o nell'altro.
I sistemi unix-like (quindi anche linux) esistono fin dagli albori dell'informatica, e il loro file system, anche se nel corso del tempo ha avuto qualche cambiamento, è rimasto sostanzialmente lo stesso. Oggi esiste uno standard chiamato FHS a cui normalmente ci si attiene nella strutturazione del file system.

Anche se il file system di linux può sembrare complesso all'inizio, esso è flessibile e logico una volta appreso il suo funzionamento, e la sua conoscenza è essenziale in moltissime circostanze d'uso.



Cartella radice "/"

Il concetto più importante da cogliere al volo è che questa directory contiene tutto: dagli elementi fondamentali del sistema ai punti di innesto (mount) per i dispositivi ed altri eventuali file system.



Cartella: "/bin"

Contiene tutti i file fondamentali (binaries) per l'uso del sistema, sia da parte dell'utente root sia da parte degli utenti ordinari. Ad esempio, non possono mancare in questa directory i comandi per copiare e rimuovere file, per spostarsi fra le directory ma anche alcuni applicativi di rete.



Cartella: "/boot"

Contiene di norma i file essenziali per l'avvio del sistema: solitamente, al suo interno viene conservata anche l'immagine del kernel, necessaria per il boot del sistema. Da qui il sistema si avvia, viene allocata la memoria, riconosciuto l'hardware e montati i filesystem, e tutte le varie altre cose che devono essere effettuate all'avvio. Non è opportuno, se non si è assolutamente sicuri di ciò che si sta facendo, modificare questi file.



Cartella: "/dev"

Contiene tutta la lista dell'hardware del pc, con alcune ripetizioni necessarie per server e configurazioni hardware speciali, tutte le periferiche a cui si ha accesso sono localizzate in questa posizione. Sono, in effetti, contenuti dei file che identificano i device presenti nella macchina.
Come si ricorderà, abbiamo identificato la prima partizione del primo disco IDE come /dev/hda1: esplorando questa directory, ovviamente, lo ritroveremo assieme a molti altri.



Cartella: "/etc"

E' una directory "contenitore", visto che al suo interno trovano spazio i file di configurazione dei programmi installati nel sistema. Per chiarezza, solitamente, ogni programma crea una propria sottodirectory in /etc nella quale inserisce i propri file di configurazione (a meno che il file di configurazione sia solo uno). Per la configurazione del sistema, quindi, /etc è il primo posto dove andare a guardare.
Contiene, ad esempio, i binari del sistema a finestre X (in /etc/X11), gli script di avvio (/etc/rc.d), la lista dei filesystem e dei punti di mount (fstab e mtab) e vari altri file.



Cartelle: "/home" e "/root"

/home
E' la "casa" degli utenti ordinari del sistema: al suo interno trovano infatti spazio diverse directory, una per ogni utente e con il nome dell'utente stesso (ad esempio, /home/user1 e /home/user2). Ogni utente, dopo il login, verrà mandato proprio nella sua home directory dove potrà lavorare in libertà, visto che nel resto del sistema difficilmente potrà scrivere dei file.
Ogni utente è separato dagli altri grazie ai permessi utente. Solo root può scavalcare questi permessi in ogni momento ed è in grado di leggere e modificare ogni file del sistema.

/root
E' la casa dove l'amministratore (o "superuser" o appunto "root") tiene i suoi file, per un normale utente è impossibile accedere in questa directory, alcuni amministratori rinominano la directory /root e la spostano in qualche altra parte del sistema, per prevenire curiosi ed eventuali hackers che riescano ad accedere al sistema.



Cartella: "/lib"

Contiene soltanto le librerie dinamiche richieste dalle applicazioni, in modo analogo alle DLL (Dynamic Linking Library) di Windows.



Cartelle: "/mnt" e "/opt"

/mnt
Questa è generalmente la directory dove vengono montati (innestati) altri file system, questa non è una regola, ma è più semplice avere il cdrom in /mnt/cdrom e il floppy disk in /mnt/floppy piuttosto che sparsi in altre directory del disco fisso.

/opt
Sta per optional. Destinata a contenere software non presente nella distribuzione.



Cartella: "/proc"

Il contenuto di questa cartella (abbreviazione di process) in realtà non esiste, si tratta del contenuto della memoria di sistema, essa non occupa dello spazio sul disco ed il suo contenuto viene ricreato ad ogni riavvio, questa directory è utile per capire cosa linux sta facendo durante il suo funzionamento. Può essere utile per tenere un log dello stato del sistema o come punto di riferimento per informazioni tecniche da utilizzare per l'assistenza.

cat /proc/cpuinfo         informazioni sul processore
cat /proc/version         informazioni sulla versione del sistema operativo
cat /proc/interrupts      mostra quali interrupt vengono usati dal sistema
cat /proc/pci             informazioni dettagliate sullo stato del bus pci
cat /proc/meminfo         informazioni contenute nella ram (o "core")



Cartella: "/sbin"

Sta per superuser binaries. Contiene eseguibili di sistema, un insieme di file estremamente importanti come fsck (che controlla lo stato del filesystem), reboot, init, swapon, mount, insmod (che controlla le dipendenze dei moduli e le cambia dinamicamente al riavvio), ifconfig, route.
Non dovrebbe essere messa in una partizione separata perchè in caso di corruzione del file /etc/fstab o /etc/mtab diventerebbe impossibile usare fsck per riparare il filesystem, tenerla insieme a / (root) è un'ottima soluzione.



Cartella: "/tmp"

Essa generalmente contiene files che vengono usati temporaneamente da un'applicazione, è anche un buon posto per "buttare" qualcosa, dato che il contenuto di questa cartella viente generalmente cancellato ad ogni reboot.



Cartella: "/usr"

Questa directory contiene tutti gli eseguibili degli utenti (più alcuni eseguibili che dovrebbero essere usati solo dall' amministratore, in /usr/sbin). Sono conservati qui anche alcuni file di help e c'è anche della documentazione in /usr/doc che può tornare utile.



Cartella: "/var"

Contiene tutte le informazioni variabili, ad esempio le cartelle di spool, i file di log, informazioni sui programmi in esecuzione, gli archivi dei database server, ecc. In sostanza /var contiene tutti quei file sottoposti a cambiamento.








Le fasi di boot in Linux


Il processo di boot di una macchina Linux (su sistemi x86 Intel compatibili) comporta diverse fasi, la loro conoscenza ed interpretazione diventa fondamentale quando occorre risolvere malfunzionamenti durante l'avvio.

Questo processo, su un sistema Linux con processore x386, prevede i seguenti stadi (con altre CPU ci possono essere alcune differenze nelle fasi iniziali):

  1. Ricerca del device da utilizzare per effettuare il boot da parte del BIOS in base ad una tabella preordinata .
  2. Dal boot sector del device di boot parte il codice (o il salto di riferimento su dove trovarlo) del loader che esegue il bootstrap del sistema operativo. Nel caso di Linux i due più diffusi loader sono LILO ed il più evoluto GRUB.
  3. Il loader lancia il caricamento del kernel di Linux, che copiandosi in memoria esegue i controlli ed il riconoscimento dell'hardware presente.
  4. A fine caricamento il kernel esegue il processo init, padre di tutti i processi, che gestisce il caricamento di tutti gli altri programmi da eseguire per completare il boot.

La figura seguente mostra uno schema un po' più dettagliato della situazione che verrà illustrata subito dopo:



Accensione

All'accensione, il controllo passa al codice presente nella ROM detto BIOS (Basic Input/Output System) che si occupa dell'inizializzazione della macchina. Come è noto ogni sistema Intel ha sulla motherboard questo chip di memoria con cui gestire l'hardware del sistema perchè all'avvio di un computer non c'è nulla di definito in RAM e nessun programma predefinito da caricare. Il BIOS controlla non solo la prima fase del processo di avvio, ma fornisce l'interfaccia di livello inferiore alle periferiche. Per questo motivo è scritto in una memoria permanente in sola lettura e può sempre essere utilizzato.


POST

Durante la fase di POST (Power On Self Test) vengono fatti i controlli di base ed individuato l'hardware di cui dispone il computer. Immediatamente dopo viene scelto, fra le impostazioni definibili dall'utente (secondo una sequenza di priorità modificabile), il dispositivo da usare per il boot. Nei BIOS più recenti è possibile effettuare il boot da: floppy, cdrom, hard disk, Zip, chiavette USB, schede di rete.


MBR

Spesso il primo disco fisso impostato per l'avvio è il disco C o il dispositivo IDE master del bus IDE primario. Gli hard disk, in particolare, hanno un settore di boot per ogni partizione ed inoltre un MBR (Master Boot Record) che è il primo settore di boot dell'intero hard disk. L'MBR ha dimensioni pari a soli 512 byte e contiene le istruzioni in codice macchina per l'avvio del computer oltre alla tabella delle partizioni. Quando si esegue il boot da un hard disk, è il codice contenuto nell'MBR che viene mandato in esecuzione. Contiene le informazioni per avviare il programma di boot secondario (second stage boot loader).
Nei casi più semplici MBR si limita a passare il controllo al codice presente nella cosiddetta partizione attiva (caso di MS-DOS).
Normalmente, però, i boot loader permettono un maggior controllo e la scelta di differenti sistemi operativi.




BootLoader

Esistono diversi loader che eseguono il bootstrap del sistema operativo per Linux, LILO e GRUB sono i più utilizzati con le distribuzioni GNU/Linux x86, ma ne esistono tanti altri: GAG, xosl, LoadLin, SysLinux, BootLin.
Tutti di fatto eseguono la stessa funzione, alcuni (LoadLin e SysLinux) sono programmi DOS che eseguono il kernel caricandolo da una partizione DOS, altri sono adattamenti di LILO che riguardano sistemi non basati su processori Intel.
LILO e GRUB sono caratterizzati dall'avere una piccola porzione del codice macchina binario dell'MBR, il cui unico obiettivo è quello di rilevare il boot loader secondario e caricarlo in memoria.



Quando il boot loader secondario (GRUB o LILO) è in memoria, viene visualizzata la schermata iniziale di Linux che mostra i diversi sistemi operativi o i kernel che sono stati configurati per l'avvio. Su questa schermata l'utente può usare i tasti direzionali per scegliere quale sistema operativo o kernel avviare e premere Invio per confermare. Se non viene premuto nessun tasto il boot loader carica la selezione di default dopo un periodo di tempo configurabile.

Nel caso in cui sia stato selezionato Linux, quando il boot loader di seconda fase ha determinato quale kernel avviare, rileva il kernel binario corrispondente nella directory /boot/. Il kernel binario è individuato da un nome che ha il formato che segue:
/boot/vmlinuz-<versione-kernel> per esempio: vmlinuz-2.6.0-xx

Oltre al kernel, viene caricata in memoria anche l'immagine RAM disk iniziale. Tale immagine si chiama initrd ed e' utilizzata dal kernel per caricare in memoria tutti i driver non compilati all'interno del kernel stesso che sono necessari per avviare il sistema.

initrd è un file system speciale che viene montato allo scopo di avviare un sistema minimo, con cui eseguire alcune operazioni preliminari. Al termine di queste operazioni, normalmente il sistema contenuto nel disco RAM iniziale monta il file system standard e passa il controllo al programma init.
La tecnica del disco RAM iniziale viene usata solitamente per caricare dei moduli prima di montare il file system definitivo, per esempio quando il kernel richiede un modulo speciale per accedere a tale file system.
Si può vedere il disco RAM iniziale, come un file system contenente fondamentalmente un programma init, che convenzionalmente corrisponde a /linuxrc. La difficoltà sta nel ridurre al minimo il sistema di questo disco RAM; eventualmente il file /linuxrc potrebbe essere un programma realizzato appositamente, senza bisogno di altro.
Una volta che il programma o lo script /linuxrc ha compiuto il suo lavoro, questo deve innestare il file system che deve in seguito diventare quello principale, in una directory, quindi deve eseguire la funzione pivot_root() per scambiare i ruoli. Vedi l'immagine seguente.




Una volta caricati in memoria RAM il kernel e l'immagine RAM disk initrd, il controllo della macchina passa al kernel.








Avvio del Kernel


Dopo le prime fasi di boot giunge finalmente il momento dell'avvio del kernel, il cui inizio è spesso caratterizzato dallo scorrere di una lunga serie di messaggi sul video. Con riferimento, ancora, al primo grafico riportato nel paragrafo precedente ecco illustrate le fasi successive al bootloader.


Kernel

Quando il kernel viene caricato, inizializza e configura immediatamente la memoria del computer. Visualizza vari messaggi utili per capire e conoscere il proprio sistema. È possibile, in seguito, visualizzare questi messaggi, che intanto scorrono velocemente sul monitor, tramite il comando:

dmesg

Il kernel configura i vari elementi hardware collegati al sistema, inclusi tutti i processori e i sottosistemi I/O, oltre a tutti i dispositivi di memorizzazione.

Dopo l'inizializzazione di tutti i dispositivi del sistema da parte del kernel, viene creato un dispositivo root, montata la partizione root di sola lettura e liberata la memoria non utilizzata.
Il kernel risulta così caricato in memoria e operativo. Tuttavia, senza alcuna applicazione che consenta all'utente di fornire input significativo al sistema, il kernel non è molto utile.
Per configurare l'ambiente utente, il kernel esegue il comando /sbin/init.


/sbin/init

Il processo init, il cui file si trova in /sbin/init/, è definito il padre di tutti i processi, tramite il suo file di configurazione /etc/inittab, provvede a lanciare tutti i programmi che completano il processo di caricamento e configura l'ambiente per l'utente.
Innanzitutto esegue lo script /etc/rc.d/rc.sysinit che imposta il percorso, attiva lo swapping, controlla i filesystem e così via. In sostanza, si occupa di tutti i processi che vanno eseguiti all'inizializzazione del sistema. Per esempio, la maggior parte dei sistemi utilizza un orologio e rc.sysinit usa il file di configurazione /etc/sysconfig/clock per inizializzare l'orologio. Un'altro esempio è se dovete inizializzare processi speciali per le porte seriali, rc.sysinit può eseguire anche il file /etc/rc.serial.
In seguito il comando init esegue lo script /etc/inittab, che descrive il modo in cui il sistema va configurato per ogni runlevel SysV. Questo file specifica, tra le altre cose, che /etc/inittab imposta il runlevel predefinito e che /sbin/update va eseguito a ogni avvio dei runlevel. [4].
Successivamente il comando init configura la libreria delle funzioni sorgenti /etc/rc.d/init.d/functions per il sistema, che stabilisce come avviare o terminare un programma e come trovare il PID di un programma.
A questo punto il programma init avvia tutti i processi di background cercando nella relativa directory rc il runlevel specificato come predefinito in /etc/inittab. Le directory rc sono numerate per corrispondere ai runlevel che rappresentano. Per esempio /etc/rc.d/rc5.d/ è la directory per il runlevel cinque.




RunLevels

Un runlevel è una configurazione software del sistema che permette l'esistenza solo di un gruppo selezionato di processi. I processi avviati da init per ognuno di questi runlevel sono definiti nel file /etc/inittab. Init può essere in uno degli otto runlevel, [0-6, S/s].
Il runlevel viene cambiato da un utente privilegiato lanciando /sbin/telinit, il quale invia un segnale appropriato a init, indicandogli a quale runlevel passare.

I runlevel [0,1,6] sono riservati:


I runlevel [2-5] definiscono le normali configurazioni operative, secondo il seguente schema:

In generale, gli utenti utilizzano Linux ad un runlevel 3 o runlevel 5 (entrambe modalità multiutente). Solo alcuni utenti, a volte, personalizzano i runlevel 2 e 4 per soddisfare delle esigenze specifiche

Il runlevel S o s non è in realtà pensato per essere usato direttamente, ma più che altro per gli script che sono eseguiti quando si entra nel runlevel 1. Per maggiori informazioni su questo, si vedano le pagine di manuale di shutdown(1) e inittab(5).

Sono validi anche i runlevel 7-9, sebbene non realmente documentati. Ciò perché le varianti di Unix "tradizionali" non li usano.

Nei sistemi che utilizzano l'avvio stile SystemV, e' presente il file /etc/inittab. Normalmente questo file:








/proc (filesystem)

Il file system /proc e' un file system creato e mantenuto a run-time dal Kernel di Linux per tenere traccia dei vari processi che stanno funzionando sulla macchina e del loro stato. Questa gerarchia di file speciali, che rappresentano lo stato corrente del kernel, consente alle applicazioni e agli utenti di esplorare il sistema attraverso il punto di vista del kernel. Tramite /proc si possono ottenere tantissime informazioni su ciò che e' installato, su come e' configurato e su come funziona. La directory /proc contiene

Una delle cose da tenere presente è che /proc in realtà non esiste, ma viene creata dinamicamente nella memoria del sistema in tempo reale; /proc puo' essere letta da qualunque utente abbia i corretti permessi di accesso, alcune delle sue parti pero' possono essere lette solamente dal proprietario del processo in questione e, ovviamente, da root.
Sotto linux, vi sono varie utility come lscpi, scanpci, ed altre che ottengono i loro dati proprio leggendo /proc ed interpretandone le informazioni. Altre utility simili sono ps e top.

La root (/) di un sistema Linux di solito si presenta cosi':

......
drwxr-xr-x   20 root root   480 Dec 16 20:54 mnt
drwxr-xr-x    2 root root    48 Mar  7  2005 opt
dr-xr-xr-x  112 root root     0 Dec 18 06:28 proc <---
drwxr-xr-x   22 root root   960 Dec 18 06:11 root
drwxr-xr-x    2 root root  5136 Dec 15 19:13 sbin
drwxr-xr-x   10 root root     0 Dec 18 06:28 sys
......

Si noti che poichè /proc e' un file system virtuale, esso viene ricreato ogni volta che la macchina viene accesa, e quindi la sua data/ora e' sempre aggiornata. Il listato del suo contenuto assomiglia a qualcosa del genere:

1, 105, 1353, 1354, 16, 160, 161, 162, 163, 2, 2671, 3, 3431, 4, 4262, 4265,
4270, 4353, 4423, 4424, 4425, 4426, 4427, 4505, 4511, 4516, 4518, 4525, 4530,
4531, 4535, 4536, 4537, 4538, 4539, 4540, 4557, 4563, 4564, 4565, 4566, 4567,
4623, 4624, 4643, 4681, 4708, 4711, 4713, 4716, 4723, 4729, 4747, 4749, 4752,
4763, 4765, 4767, 4770, 4784, 4797, 4800, 4801, 4809, 4811, 4813, 4946, 4954,
4963, 4967, 4969, 4971, 4976, 4979, 4991, 4999, 5002, 5003, 5004, 5011, 5013,
5090, 754, 839, 844, 845, 857, 882, 883, 886, 92, acpi, asound, buddyinfo,
bus, cmdline, cpuinfo, crypto, devices, diskstats, dma, driver, execdomains,
fb, filesystems, fs, ide, interrupts, iomem, ioports, irq, kallsyms, kcore,
kmsg, loadavg, locks, meminfo, misc, modules, mounts, mtrr, net, partitions,
pci, scsi, self, slabinfo, splash, stat, swaps, sys, sysrq-trigger, sysvipc,
tty, uptime, version, vmstat

Si notino una serie di directory contrassegnate da un numero, si tratta dei singoli processi in esecuzione nella macchina nell'istante in cui è stato eseguito il comando ls -m /proc. Per "vedere" il contenuto di ogni singola directory occorre essere root, questo perche' se il processo appartiene ad un diverso utente ne viene proibito l'accesso. A titolo di esempio osserviamo il contenuto di una di esse:

totale 0
dr-xr-xr-x   3 root root 0 2005-12-19 09:35 .
dr-xr-xr-x  90 root root 0 2005-12-19 09:35 ..
dr-xr-xr-x   2 root root 0 2005-12-19 09:56 attr
-r--------   1 root root 0 2005-12-19 09:56 auxv
-r--r--r--   1 root root 0 2005-12-19 09:56 cmdline
lrwxrwxrwx   1 root root 0 2005-12-19 09:56 cwd -> /
-r--------   1 root root 0 2005-12-19 09:56 environ
lrwxrwxrwx   1 root root 0 2005-12-19 09:56 exe
dr-x------   2 root root 0 2005-12-19 09:56 fd
-r--r--r--   1 root root 0 2005-12-19 09:56 maps
-rw-------   1 root root 0 2005-12-19 09:56 mem
-r--r--r--   1 root root 0 2005-12-19 09:56 mounts
-rw-r--r--   1 root root 0 2005-12-19 09:56 oom_adj
-r--r--r--   1 root root 0 2005-12-19 09:56 oom_score
lrwxrwxrwx   1 root root 0 2005-12-19 09:56 root -> /
-r--r--r--   1 root root 0 2005-12-19 09:41 stat
-r--r--r--   1 root root 0 2005-12-19 09:56 statm
-r--r--r--   1 root root 0 2005-12-19 09:41 status
dr-xr-xr-x   3 root root 0 2005-12-19 09:56 task
-r--r--r--   1 root root 0 2005-12-19 09:56 wchan

Il contenuto delle altre directory numeriche e' praticamente lo stesso, indipendentemente dalla directory che scegliamo. Solo i valori dei singoli parametri cambiano a seconda del processo scelto. Dall'esame di alcuni file, contenuti all'interno di una sottodirectory di /proc che identifica un processo, si possono scoprire delle informazioni interessanti relative al processo stesso:

-r--r--r--   1 root root 0 2005-12-19 09:56 cmdline
File contenente l'intera linea di comando invocata per avviare
il processo, non viene usata nessuna formattazione particolare.

-r--------   1 root root 0 2005-12-19 09:56 environ
File contenente tutte le variabili di ambiente definite per quel 
particolare processo, nella forma VARIABILE=valore,
non viene usata nessuna formattazione particolare.

lrwxrwxrwx   1 root root 0 2005-12-19 09:56 root -> /
Questo link mostra quale e' la directory "root" per quel particolare
processo. Un processo può, infatti, avere una root che non corrisponde 
alla "vera" root.

-r--r--r--   1 root root 0 2005-12-19 09:41 status
File che fornisce informazioni relative allo stato del processo,
(dormiente, attivo,...), PID, UID, PPID ed altre informazioni simili. 
Queste informazioni possono essere visualizzate usando ps e top.


Sinteticamente ecco le informazioni riportate da alcuni di questi file:

/proc/cpuinfo   Riporta informazioni sul processore, per esempio il tipo, marca, modello e le varie performance.
/proc/devices   Elenca i driver configurati nel kernel corrente
/proc/dma   Mostra quali canali DMA sono in uso al momento
/proc/filesystems   Mostra i filesystem configurati (supportati) nel kernel
/proc/interrupts   Visualizza gli interrupts in uso e quanti e quali sono stati usati.
/proc/ioports   Mostra quali porte di i/o sono in uso al momento