Processo di avvio di Linux

Il processo di avvio di Linux è la procedura di inizializzazione del sistema. Consiste in tutto ciò che accade da quando il computer viene acceso per la prima volta fino a quando l'interfaccia utente è completamente operativa. 

Capire i passi del processo di avvio può aiutarti a risolvere i problemi, così come ad adattare le prestazioni del computer alle tue esigenze. 

Vero è che il processo di avvio è piuttosto tecnico e si può iniziare a usare Linux senza conoscere tutti i dettagli. Quindi se vuoi puoi leggere altri articoli presenti in questo tutorial e poi tornare a studiare questa sezione in un secondo momento, se vuoi prima farti un'idea di come usare un sistema Linux.

Processo di avvio di Linux
Processo di avvio di Linux

BIOS

L'avvio di un sistema Linux basato su x86 comporta una serie di passaggi. Quando il computer è acceso, il Basic Input/Output System (BIOS) inizializza l'hardware, compreso lo schermo, la tastiera e  testa la memoria principale. Questo processo è anche chiamato POST (Power On Self Test).

Il software del BIOS è memorizzato su un chip ROM sulla scheda madre. Dopo questo, il resto del processo di avvio è controllato dal sistema operativo.

Master Boot Record (MBR) e Boot Loader

Una volta completato il POST, il controllo del sistema passa dal BIOS al boot loader

Il boot loader è solitamente memorizzato su uno dei dischi rigidi del sistema, sia nel settore di avvio (per i sistemi tradizionali BIOS/MBR) che nella partizione EFI (per i sistemi più recenti (Unified) Extensible Firmware Interface o EFI/UEFI). Fino a questo stadio, la macchina non accede a nessun supporto di memorizzazione di massa. 

Successivamente, le informazioni sulla data, ora e le periferiche più importanti vengono caricate dai valori CMOS (una tecnologia utilizzata per l'archivio di memoria a batteria che permette al sistema di tenere traccia della data e dell'ora anche quando è spento).

Esistono diversi boot loader per Linux. I più comuni sono GRUB (per GRand Unified Boot loader), ISOLINUX (per l'avvio da supporti rimovibili), e DAS U-Boot (per l'avvio su dispositivi/apparecchiature embedded). 

La maggior parte dei boot loader Linux possono presentare un'interfaccia utente per la scelta di opzioni alternative per l'avvio di Linux e anche di altri sistemi operativi che potrebbero essere installati. 

Quando si avvia Linux, il boot loader è responsabile del caricamento dell'immagine del kernel e del disco RAM iniziale o del filesystem (che contiene alcuni file critici e i driver dei dispositivi necessari per avviare il sistema) in memoria.

Il boot loader ha due fasi distinte.

Prima fase

Per i sistemi che usano il metodo BIOS/MBR, il boot loader risiede nel primo settore dell'hard disk, conosciuto anche come Master Boot Record (MBR)

La dimensione dell'MBR è di soli 512 byte. In questa fase, il boot loader esamina la tabella delle partizioni e trova una partizione da lanciare. 

Una volta trovata una partizione idonea, cerca il boot loader del secondo stadio, per esempio GRUB, e lo carica nella RAM (Random Access Memory)

Per i sistemi che usano il metodo EFI/UEFI, il firmware UEFI legge i dati del suo Boot Manager per determinare quale applicazione UEFI deve essere lanciata e da dove (cioè da quale disco e partizione si può trovare la partizione EFI). 

Il firmware lancia poi l'applicazione UEFI, per esempio GRUB, come definito nella voce di avvio nel boot manager del firmware. Questa procedura è più complicata, ma più versatile dei vecchi metodi MBR.

Seconda fase

Il secondo stadio del boot loader risiede nel percorso /boot.

Viene visualizzato uno splash screen, che ci permette di scegliere quale sistema operativo (OS) avviare. Dopo aver scelto il sistema operativo, il boot loader carica il kernel del sistema operativo selezionato nella RAM e gli passa il controllo.

I kernel sono quasi sempre compressi, quindi il suo primo compito è quello di decomprimere se stesso. Dopo di che controlla e analizza l'hardware del sistema e inizializza qualsiasi driver di dispositivi hardware integrato nel kernel.

La RAM iniziale

L'immagine del filesystem initramfs contiene programmi e file binari che eseguono tutte le azioni necessarie per montare il corretto filesystem di root come fornire le funzionalità del kernel per il filesystem necessario ed i driver dei dispositivi per i controller di archiviazione di massa con una struttura chiamata udev (per dispositivo utente).

Questo è responsabile di capire quali dispositivi sono presenti, localizzare i driver dei dispositivi di cui hanno bisogno per funzionare correttamente e caricarli. 

Dopo che il filesystem di root è stato trovato, viene fatto un controllo se sono presenti errori e montato.

Il programma di montaggio indica al sistema operativo che un filesystem è pronto per l'uso e lo associa ad un particolare punto della gerarchia generale del filesystem, chiamato punto di montaggio. Se questo ha successo, l'initramfs viene cancellato dalla RAM e il programma init sul filesystem di root (/sbin/init) viene eseguito.

Se sono necessari speciali driver hardware prima di poter accedere alla memoria di massa, questi devono essere nell'immagine di initramfs.

Compiti dell'initramfs
Compiti dell'initramfs

Text-Mode Login

Verso la fine del processo di avvio, init inizia una serie di prompt di login in modalità testo. Questi ti permettono di digitare il tuo nome utente, la tua password, ed eventualmente di ottenere una shell di comando. 

Però se stai eseguendo un sistema con un'interfaccia grafica di login, all'inizio non le vedrai.

I terminali che eseguono le shell di comando sono accessibili usando il tasto ALT più un tasto funzione. All'interno di un ambiente grafico, il passaggio ad una console di testo, attivando la CLI (Command Line Interface) Bash premere CTRL-ALT + la lettera t (per Ubuntu). 

Di solito, come anticipato, la shell di comando di default è bash (la GNU Bourne Again Shell), ma ci sono diverse altre shell di comando avanzate disponibili. 

La shell stampa un prompt di testo, indicando che è pronta ad accettare comandi. 

Dopo che l'utente digita il comando e preme Invio, il comando viene eseguito ed un altro prompt viene visualizzato dopo il comando.

Linux Kernel

Il boot loader carica sia il kernel che un file system iniziale basato sulla RAM (initramfs) in memoria, in modo che possa essere usato direttamente dal kernel.  

Quando il kernel viene caricato nella RAM, inizializza e configura immediatamente la memoria del computer e configura anche tutto l'hardware collegato al sistema. Questo include tutti i processori, i sottosistemi I/O, i dispositivi di memorizzazione, ecc. Il kernel carica anche alcune applicazioni dello spazio utente necessarie.

/sbin/init e servizi

Una volta che il kernel ha impostato tutto il suo hardware e montato il filesystem di root, il kernel esegue /sbin/init

Questo diventa poi il processo iniziale, che poi avvia altri processi per far funzionare il sistema. La maggior parte degli altri processi del sistema si possono trovare nella parte finale ini, alcune eccezioni includono i cosiddetti processi del kernel. Questi sono avviati direttamente dal kernel e il loro compito è quello di gestire i dettagli interni del sistema operativo.

Oltre ad avviare il sistema, init è responsabile di mantenere il sistema in funzione e di spegnerlo in modo corretto. 

Una delle sue responsabilità è quella di agire quando necessario come manager per tutti i processi non del kernel. Si occupa di ripulire dopo il loro completamento e di riavviare i servizi di login gli utenti entrano ed escono. Fa lo stesso per gli altri servizi di sistema in background.

Questo metodo fa sì che il sistema passi attraverso una sequenza di processi (runlevel) che contengono script che avviano e fermano i servizi. 

Ogni runlevel supporta una diversa modalità di esecuzione del sistema. All'interno di ogni runlevel i singoli servizi possono essere impostati per funzionare o per essere arrestati se in esecuzione.

C’è da dire che tutte le principali distribuzioni recenti si sono allontanate da questo metodo sequenziale di inizializzazione del sistema a runlevel, i metodi più recenti sono Upstart e systemd.

  • Upstart: sviluppato da Ubuntu e incluso per la prima volta nel 2006, adottato in Fedora 9 (nel 2008) ed in RHEL.
  • systemd: Adottato da Fedora prima (nel 2011), da RHEL 7 e SUSE. Ha sostituito Upstart in Ubuntu dalla versione 16.04.

SysVinit (metodo runlevel) è un processo seriale, diviso in una serie di fasi sequenziali. Ogni fase richiedeva il completamento prima che la successiva potesse procedere. In questo modo l'avvio non sfruttava facilmente l'elaborazione parallela che poteva essere fatta su più processori o core.

Inoltre lo spegnimento e il riavvio era visto come un evento relativamente raro ed il tempo per svolgere questa operazione non era considerato importante. Questo non è più vero, specialmente con dispositivi mobili e sistemi Linux embedded.

Alcuni metodi moderni, possono richiedere tempi di avvio quasi istantanei. Infine i metodi più vecchi richiedevano script di avvio piuttosto complicati, che erano difficili da mantenere universali tra versioni di distribuzione, versioni del kernel, architetture e tipi di sistemi.

L'adozione quasi universale di systemd ha reso più semplice l'apprendimento di come lavorare sui sistemi Linux dato che ci sono meno differenze tra le distribuzioni.

Caratteristiche del systemd

I sistemi con systemd si avviano più velocemente di quelli con metodi precedenti. Ciò è dovuto in gran parte al fatto che sostituisce una serie di passi serializzati con tecniche di parallelizzazione che permettono di avviare più servizi contemporaneamente.

Gli script di shell di avvio complessi sono stati sostituiti con file di configurazione più semplici che elencano ciò che deve essere fatto prima che un servizio venga avviato. Come eseguire l'avvio del servizio e quali condizioni il servizio dovrebbe segnalare che sono state fatte quando l'avvio è terminato.

Una cosa da notare è che /sbin/init ora punta solo a /lib/systemd/systemd/systemd, cioè systemd si occupa del processo di init.

Il comando systemctl è usato per la maggior parte dei compiti di base. Ed esegue alcuni compiti:

  • Avviare, fermare, riavviare un servizio (nell'esempio il servizio nfs) su un sistema attualmente in esecuzione: $ sudo systemctl start|stop|restart nfs.service
  • Abilitare o disabilitare un servizio di sistema all'avvio del sistema: $ sudo systemctl enable|disabilita il servizio nfs.service

Nella maggior parte dei casi il .service può essere omesso.

X Window System

Generalmente, in un sistema desktop Linux, il sistema X Window System viene caricato nelle fasi finali del processo di avvio. 

Un servizio chiamato Display Manager tiene traccia dei display forniti e carica il server X (chiamato così perché fornisce servizi grafici alle applicazioni a volte chiamati X client).

Il display manager gestisce anche i login grafici e avvia l'ambiente desktop appropriato dopo che un utente ha effettuato il login.

X è un software piuttosto vecchio, risale alla metà degli anni '80 e, come tale, presenta alcune carenze sui sistemi moderni (per esempio, con la sicurezza). Un sistema più recente, noto come Wayland, lo sta gradualmente sostituendo ed è il sistema di visualizzazione predefinito per Fedora, RHEL 8 e altre distribuzioni recenti. 

Assomiglia a X per l'utente, ma sotto la superficie è molto diverso.