author: Wale Soyinka contributors: Steven Spencer, Ganna Zhyrnova tested on: Tutte le versioni tags: - lab exercise - Linux Kernel - compile
Laboratorio 7: Il kernel Linux¶
Obiettivi¶
Dopo aver completato questo laboratorio, sarete in grado di:
- installare un nuovo kernel da un pacchetto binario
- compilare e installare un nuovo kernel dai file sorgente
Tempo stimato per completare questo laboratorio: 90 minuti
kernel¶
Uno dei compiti che occasionalmente potreste dover svolgere durante l'amministrazione di un sistema Linux sarà quello di aggiornare o risolvere i problemi relativi al kernel del sistema operativo.
Il kernel è il cuore del sistema operativo Linux. È una cosa che accomuna le varie distribuzioni di Linux (Rocky Linux, Red hat, Mandrake, SuSE, Yellow dog ecc.). È responsabile della gestione di varie risorse di sistema e funge da livello di astrazione tra l'hardware del sistema e il software che si interfaccia con esso, fornendo i driver hardware.
Il kernel è sempre in fase di miglioramento e vengono sempre aggiunte nuove funzionalità o risolti bug. Come amministratore potrebbe essere necessario aggiornare al kernel più recente perché:
- Il kernel più recente contiene correzioni di bug o specifiche ottimizzazioni desiderate
- Ripara le falle di sicurezza presenti nel vecchio kernel
- Contiene i driver per un componente hardware che non era possibile utilizzare con il vecchio kernel
Codice sorgente e versioni del kernel¶
Il kernel comprende oltre un milione di righe di codice di programmazione in C. Questo costituisce il cosiddetto codice sorgente del Kernel.
Il repository principale del kernel è il sito web del kernel gestito dall'URL:
In questo sito troverete sempre le versioni più recenti [e più vecchie] del kernel.
Come già detto, il kernel è comune a tutte le varie distribuzioni Linux. Queste distribuzioni a volte ri-pacchettizzano il codice sorgente del kernel per facilitare l'installazione e gli aggiornamenti o per adattarsi alla loro particolare distribuzione.
Le varie versioni del codice sorgente del Kernel utilizzano la seguente convenzione di denominazione:
linux-<kernel.version>.tar.bz2 (o linux-<kernel.version>.tar.gz)
La convenzione attuale è quella di chiamare e numerare le nuove versioni principali del kernel come "Linux 5.x" (chiamate anche kernel vanilla o mainline). Pertanto, la prima di questa serie sarà la versione 5.0 di Linux (uguale alla 5.0.0), la successiva sarà la versione 5.1 di Linux (uguale alla 5.1.0), seguita dalla versione 5.2 e così via.
Eventuali modifiche o aggiornamenti minori all'interno di ciascuna versione della major release si rifletteranno con incrementi alla terza cifra. Questi vengono comunemente chiamati rilasci di punti stabili. Pertanto, la prossima release stabile per il kernel della serie 5.0.0 sarà la versione 5.0.1 di Linux, seguita dalla versione 5.0.2 e così via. Un altro modo per affermare ciò è dire, ad esempio, che la versione 5.0.4 di Linux è la quarta release stabile basata sulla serie 5.0.0 di Linux.
moduli del kernel¶
I moduli sono file di oggetti condivisi (con nomi come nome_modulo.o, nome_modulo.ko ecc.). Pensate ai moduli come ai driver di Microsoft Windows.
I moduli sono pezzi di codice del kernel che possono o meno essere inclusi direttamente nel kernel. Sono compilati separatamente e possono essere inseriti e rimossi dal kernel in esecuzione in qualsiasi momento. I sistemi moderni fanno ampio uso del supporto dei moduli caricabili. I moduli caricabili offrono diversi vantaggi, come ad esempio:
- Riduce la dimensione complessiva dell'immagine finale del kernel, poiché non sono strettamente parte del kernel in esecuzione.
- Risparmia la RAM - vengono caricati nella RAM solo quando sono necessari
Alcuni moduli devono essere compilati direttamente nel kernel, mentre altri possono essere caricati separatamente.
La scelta di quando rendere disponibile una particolare funzionalità come modulo o compilarla nel kernel è di solito abbastanza semplice. In generale, se l'uso è poco frequente e se le funzionalità sono quelle di un modulo, è meglio compilarlo come modulo.
Configurazione del kernel¶
In genere esistono tre metodi per gestire il kernel nelle distribuzioni Linux. Questi sono:
-
Utilizzando la versione preconfezionata del kernel fornita dal produttore della distribuzione. Ad esempio utilizzando kernel-
.*.rpm. È la soluzione più sicura, più semplice e preferibile -
Tramite il patching. Utilizzando file di patch come - patch-kernel.version.gz.
-
Compilando il kernel dai sorgenti, ad esempio usando linux-kernel.version.tar.bz2
Nei prossimi esercizi si aggiornerà il kernel in uso a una versione leggermente più recente. Per eseguire l'aggiornamento si utilizzerà innanzitutto una versione preconfezionata (binaria) del kernel Linux.
Esercizio 1¶
Aggiornamento dal pacchetto binario [rpm]¶
In questo esercizio si aggiornerà direttamente il kernel utilizzando l'applicazione rpm.
Per aggiornare il kernel utilizzando rpm¶
-
Assicuratevi di aver effettuato l'accesso al sistema come root.
-
Eseguire l'utilità
rpm
per elencare tutti i pacchetti del kernel attualmente installati sul sistema. Digitare:$ rpm -q kernel
-
Eseguire l'utilità
uname
per visualizzare alcune informazioni sul kernel in esecuzione. Digitare:$ uname --kernel-release 5.*.el9_8.x86_64
Annotare il numero di versione/rilascio nell'output.
-
Usare
dnf
per scaricare l'ultimo pacchetto del kernel disponibile dal repository ufficiale dei pacchetti Rocky Linux. Digitare:Ora si dovrebbe avere un pacchetto RPM con un nome simile a kernel-*.x86_64.rpm salvato nella propria PWD.$ dnf download kernel
-
Usare di nuovo
rpm
per interrogare il pacchetto scaricato e ottenere ulteriori informazioni su di esso. Digitare:[root@localhost ~]# rpm -qip kernel-*.x86_64.rpm
-
Usare
rpm
per fare un'installazione di prova del kernel*.rpm scaricato per assicurarsi che tutte le sue dipendenze siano soddisfatte. Digitare:$ rpm --test -ivh kernel-*.x86_64.rpm error: Failed dependencies: kernel-core-uname-r = *.x86_64 is needed by kernel-*.x86_64 kernel-modules-uname-r = *.x86_64 is needed by kernel-*.x86_64
Dall'output si può vedere che il pacchetto ha dipendenze non soddisfatte.
-
Utilizzare
dnf
per scaricare le dipendenze necessarie segnalate nel precedente messaggio di errore. Digitare:$ dnf download kernel-core-uname-r kernel-modules-uname-r
-
Eseguite di nuovo
rpm
con l'opzione test per vedere se il pacchetto del kernel può essere aggiornato. Digitare:$ rpm --test -Uvh kernel-*.rpm Verifying... ################################# [100%] Preparing... ################################# [100%]
Questa volta tutto sembra a posto!
-
Infine, utilizzare
rpm
per installare il pacchetto kernel con tutte le sue dipendenze. Digitare:$ sudo rpm -ivh kernel-*.rpm
-
Usare
rpm
per elencare tutti i pacchetti kernel installati sul sistema.Domanda
Cosa c'è di diverso tra l'output del comando rpm -q kernel, prima e dopo l'installazione del nuovo kernel?
-
Abbiamo finito di usare RPM per gestire direttamente i pacchetti del kernel sul sistema. Disinstallare l'ultimo pacchetto kernel scaricato e installato. A tale scopo, è necessario specificare le informazioni esatte e corrette su nome-epoca-versione-rilascio-architettura (NEVRA) del kernel e delle sue dipendenze associate che si desidera disinstallare. Digitare:
[root@localhost ~]# rpm -e \ kernel-<NEVRA> \ kernel-core-<NEVRA> \ kernel-modules-<NEVRA>
Esercizio 2¶
Aggiornamento dal repository dei pacchetti¶
In questo esercizio si aggiornerà il kernel utilizzando l'applicazione dnf
. DNF è un gestore di pacchetti per distribuzioni Linux basate su RPM. Può essere utilizzato per gestire i pacchetti di sistema utilizzando i repository online configurati.
Per aggiornare il kernel utilizzando DNF¶
-
Assicuratevi di aver effettuato l'accesso al sistema come root.
-
Usare
dnf
per elencare tutti i pacchetti del kernel installati sul sistema e i pacchetti del kernel disponibili sul repository remoto dei pacchetti. Digitare:[root@localhost ~]# dnf list kernel
-
Utilizzare il programma
dnf
per verificare la disponibilità di pacchetti kernel aggiornati. Digitare:[root@localhost ~]# dnf check-update kernel
È possibile che vengano visualizzati o meno gli aggiornamenti dei pacchetti del kernel disponibili sul sistema; l'output dipende da quanto recentemente è stato aggiornato l'intero sistema.
-
Se si vede una nuova versione del kernel elencata come disponibile, si può usare
dnf
per interrogare il repository remoto e ottenere maggiori informazioni sul pacchetto eseguendo:[root@localhost ~]# dnf info kernel --available
-
Usare
dnf
per trovare, scaricare e installare automaticamente l'ultimo pacchetto del kernel disponibile nel repository remoto dei pacchetti. Digitare:[root@localhost ~]# dnf -y update kernel
-
Ora elenchiamo i pacchetti del kernel installati. Digitare:
[root@localhost ~]# dnf list kernel --installed
Esercizio 3¶
Aggiornare il kernel dai sorgenti¶
In questo esercizio si costruirà un nuovo kernel dai sorgenti, configurandolo, compilandolo e installandolo da soli.
Per aggiornare il kernel dai sorgenti¶
Note
La versione del kernel utilizzata in questo esercizio è l'ultima disponibile al momento. L'ultima versione disponibile al momento della lettura di questo documento potrebbe essere diversa. È stato utilizzato un asterisco () per indicare la versione del kernel utilizzata. È necessario sostituire il simbolo "" con la versione specifica in uso. Ad esempio, supponendo che la versione del kernel utilizzata nei passaggi seguenti sia 6.6.13.4, il kernel sarà indicato come versione 6.6.*
-
Accedere al sistema come utente con privilegi di amministrazione.
-
Installare gli strumenti di sviluppo necessari. Digitare:
$ sudo dnf -y groupinstall 'Development Tools'
-
Installare le librerie e gli strumenti necessari. Digitare:
$ sudo dnf -y install ncurses-devel bc openssl-devel elfutils-libelf-devel python3 dwarves
-
Scaricare l'ultimo sorgente del kernel digitando:
[root@localhost ~]# curl -L -o linux-6.5.7.tar.xz \ https://www.kernel.org/pub/linux/kernel/v6.x/linux-6.5.7.tar.xz
Si noti che linux-6.5.7.tar.xz è l'ultimo kernel disponibile al momento in cui scriviamo. Sostituite linux-6.5.7.tar.xz o linux-6.*.tar.xz con la versione del kernel che avete scelto per seguire questo esercizio.
-
Scompattate il tarball del kernel nella vostra pwd. Digitare:
[root@localhost ~]# tar xvJf linux-6.*.tar.xz
Il comando tar creerà una nuova directory chiamata: "linux-6.*" sotto la propria PWD.
-
Elencare il contenuto della nuova directory dei sorgenti del kernel
-
Passare (cd) alla directory dei sorgenti del kernel. Digitare:
$ cd linux-6.5.7
-
Pulire (preparare) l'ambiente di compilazione del kernel usando il comando
make mrproper
. Digitare:$ make O=~/build/kernel mrproper
-
Copiare e rinominare il file di configurazione preesistente della directory /boot nel nostro ambiente di creazione del kernel:
$ cp /boot/config-`uname -r` ~/build/kernel/.config
-
Avviare l'utilità di configurazione grafica del kernel. Digitare:
Verrà visualizzata una schermata simile a questa:$ make O=~/build/kernel menuconfig
Nota
La schermata di configurazione del kernel che appare è suddivisa in circa tre aree:
-
La parte superiore mostra varie informazioni utili, scorciatoie da tastiera e legende che possono aiutare a navigare nell'applicazione.
-
Il corpo principale della schermata mostra un elenco espandibile a struttura ad albero delle opzioni del kernel complessivamente configurabili. È possibile approfondire le voci con le frecce nel genitore per visualizzare e/o configurare le voci dei sottomenu (o figli).
-
Infine, nella parte inferiore della schermata vengono visualizzate le azioni/opzioni che l'utente può scegliere.
-
-
A scopo dimostrativo, si aggiungerà il supporto per il filesystem Btrfs al nuovo kernel. Nella schermata di configurazione principale, utilizzare i tasti freccia per spostarsi ed evidenziare la voce File system. Con File system selezionato, premere INVIO per visualizzare il sottomenu o le voci secondarie di File system.
Nella sezione File System, utilizzare i tasti freccia per spostarsi su Btrfs filesystem support.
-
Con Btrfs filesystem support evidenziato, premere
y
per includere il supporto perbtrfs
nel kernel personalizzato. Al termine, accanto all'opzione evidenziata dovrebbe comparire il simbolo dell'asterisco (*). La schermata finale dovrebbe assomigliare a quella mostrata qui: -
Tornare alla schermata principale di configurazione del kernel premendo due volte ESC sulla tastiera.
-
Uscire dall'applicazione di configurazione del kernel premendo nuovamente due volte ESC sulla tastiera. L'uscita dal configuratore del kernel comporta il salvataggio delle modifiche nel file .config nella radice dell'albero dei sorgenti del kernel.
-
Viene visualizzata una finestra di dialogo che richiede di salvare la nuova configurazione. Assicurarsi che sia selezionato Yes e premere ENTER.
-
Dopo l'uscita dell'utilità di configurazione del kernel, si tornerà alla propria shell, all'interno dell'albero dei sorgenti del kernel.
Suggerimento
Per visualizzare i risultati di alcune delle modifiche apportate con lo strumento
menuconfig
, utilizzare l'utilità grep per visualizzare il file .config salvato in precedenza. Ad esempio, per visualizzare l'effetto dell'abilitazione del supporto del filesystembtrfs
, digitare quanto segue:# grep ^CONFIG_BTRFS_FS ~/build/kernel/.config CONFIG_BTRFS_FS=y
-
È possibile ottimizzare il tempo di compilazione del kernel e ridurre la quantità di spazio su disco utilizzato durante la fase di compilazione del kernel. Impostando
CONFIG_DEBUG_INFO=no
, l'immagine del kernel risultante NON includerà le informazioni di debug, risultando così più piccola. Questo rimuove i simboli di debug dal kernel e dai moduli creati. Digitare:$ ./scripts/config --file ~/build/kernel/.config -d DEBUG_INFO \ -d DEBUG_INFO_DWARF_TOOLCHAIN_DEFAULT -d DEBUG_INFO_DWARF4 \ -d DEBUG_INFO_DWARF5 -e CONFIG_DEBUG_INFO_NONE
-
Completare un altro passo importante per i kernel personalizzati sulla distribuzione Rocky Linux. Digitare:
$ sed -ri '/CONFIG_SYSTEM_TRUSTED_KEYS/s/=.+/=""/g' ~/build/kernel/.config
-
Aggiungere una semplice personalizzazione al nuovo kernel, per distinguerlo più facilmente dagli altri kernel stock. Per questo, si può usare l'utilità
sed
per modificare il Makefile sul posto. Digitare:$ sed -i 's/^EXTRAVERSION.*/EXTRAVERSION = -custom/' Makefile
-
Verificare la versione completa del kernel appena personalizzato passando il target
kernelversion
al comandomake
. Digitare:$ make O=~/build/kernel kernelversion
OUTPUT:
make[1]: Entering directory '/home/rocky/build/kernel' 6.5.7-custom make[1]: Leaving directory '/home/rocky/build/kernel'
-
Siete pronti per compilare il kernel. Digitare:
$ sudo make O=~/build/kernel -j $(nproc)
OUTPUT:
make[1]: Entering directory '/root/build/kernel' SYNC include/config/auto.conf.cmd GEN Makefile HOSTCC scripts/kconfig/conf.o ...
-
Dopo che la compilazione è stata completata con successo, si otterrà il kernel finito, memorizzato qui:
~/build/kernel/arch/x86/boot/bzImage
-
Installare le parti del kernel configurate come moduli. Digitare:
$ sudo make O=~/build/kernel modules_install
-
Dopo aver compilato il kernel, è il momento di installarlo. Digitare:
$ sudo cp ~/build/kernel/arch/x86/boot/bzImage \ /boot/vmlinuz-<kernel-version>
Sostituire
con il numero di versione del kernel personalizzato. Per il kernel di esempio utilizzato in questa guida, il nome del file sarà vmlinuz-6.*-custom. Ecco il comando esatto per questo esempio: sudo cp ~/build/kernel/arch/x86/boot/bzImage /boot/vmlinuz-6.5.7-custom
-
Copiare e rinominare il file System.map corrispondente nella directory /boot utilizzando la stessa convenzione di denominazione:
$ sudo cp -v ~/build/kernel/System.map /boot/System.map-6.5.7-custom
-
Utilizzare l'utilità
kernel-install
per completare il passaggio del file. Digitare:$ sudo kernel-install add 6.5.7-custom /boot/vmlinuz-6.5.7-custom
-
L'utilità
kernel-install
crea una nuova voce di avvio nel file di configurazione del boot loader. Per i sistemi basati su EFI è possibile cercare in /boot/loader/entries/ le voci corrispondenti. -
Eseguire il programma grubby per visualizzare il kernel predefinito del server. Digitare:
$ sudo grubby --default-kernel
-
Tutto fatto. È il momento della verità. Il kernel più recente sarà probabilmente configurato come nuovo kernel predefinito per l'avvio. Se si ha accesso alla console del sistema, è possibile riavviare il sistema e selezionare il nuovo kernel personalizzato nel menu di avvio di GRUB. Se tutto va bene dopo il riavvio, si può verificare che il sistema stia eseguendo il kernel personalizzato eseguendo il comando
uname
in questo modo:$ uname -r