Kernel
Il Kernel di Matteo Salonia, ottimizzato per massimizzare le prestazioni dell'hardware, ed essere più leggero possibile.
Vai a:
Introduzione Setup Extra
Introduzione
I miei setup si basano su un sistema composto dai seguenti componenti:
- Distro: Gentoo Linux
- Kernel Compression: LZ4 per l'initramfs, zstd per i moduli
- Initramfs: Dracut
- Bootloader: GRUB
- Init: OpenRC
- Filesystem: FAT32 per l' ESP, XFS per il RootFS, ext4 per varie.
- Logind: elogind
Dato che uso Gentoo, i nomi dei pacchetti potrebbero essere diversi dai nomi dei pacchetti che usa la vostra distro (Arch, Debian, Fedora, ...). Siete pregati di verificare qualora i nomi fossero diversi, e di annotarli per procedere con questa guida.
Vi sono tre configurazioni di default:
- config: ThinkPad T470p, con CPU i7-7820HQ (Kaby Lake, 4C8T), Nvidia GeForce 940MX dGPU + Intel HD 630 iGPU, SATAIII/NVMe SSD, 2560x1440 display.
- config.t440p: ThinkPad T440p, con CPU i7-4700MQ (Haswell, 4C8T), Intel HD4600 iGPU, SATAIII SSD, 1366x768 display.
- config.pc: PC personalizzato, con CPU i5-11400 (Rocket Lake, 6C12T), Intel UHD 730 iGPU, NVMe SSD.
Verificate che i componenti desiderati siano abilitati nel Kernel, qualora venga usata la mia configurazione come punto di partenza. Ad esempio, componenti relativi ad AMD, Nvidia (non su T470p), NUMA, ecc. sono stati disabilitati.
Se non sapete da dove partire, usate una configurazione già esistente che sapete funzioni sul vostro hardware, se disponibile, altrimenti usate la configurazione di default di un qualsiasi Kernel, come quella fornita dalla vostra distro, o la configurazione di default del Kernel.
Setup
Assicuratevi di avere tutti gli strumenti necessari per poter proseguire. Verificate di avere git
, gcc
, make
, ecc. Tipicamente, la maggior parte di strumenti per la compilazione viene fornita da pacchetti come base-devel
. Consiglio di verificare anche la presenza di linux-firmware
, in modo tale da avere i necessari firmware per eventuali componentistiche nonfree. Non dimenticate di scaricare il microcode adatto, che sia Intel, AMD, o altro. Infine, verificate la presenza di lz4
e zstd
, per la compressione di vari componenti del Kernel.,
1. Ottenimento repository
Useremo la directory /usr/src/usr-kernel
per salvare questo progetto, e tutte le eventuali modifiche.
Assicuratevi di avere permessi di lettura e scrittura, in modo tale da poter creare la directory.
git clone --recurse-submodules "https://github.com/saloniamatteo/kernel" /usr/src/usr-kernel
cd /usr/src/usr-kernel
Qualora la directory scelta dovesse essere diversa, non dimenticatevi di modificare la variabile CUSTDIR
nel file build.sh
.
2. Selezione versione
Una volta scaricata la repository, scegliete una versione disponibile. Per vedere quali versioni sono disponibili, basta vedere i contenuti della directory con ls
. In questo esempio, utilizzeremo Linux 6.8.2-gentoo
.
Il vostro Kernel sicuramente avrà una versione diversa.
Niente panico: basterà copiare la cartella, e rinominarla in base alla vostra versione. Ad esempio, se la vostra versione dovesse essere 6.8.3-zen
, basterà eseguire: cp -r 6.8.2-gentoo 6.8.3-zen
.
Non dimenticatevi di modificare la variabile KVER
qualora la versione primaria dovesse essere diversa (esempio: 6.8.2
-> 6.8.3
), e la variabile PVER
qualora la versione secondaria dovesse essere diversa (esempio: gentoo
-> zen
)
3. Modifica script
A questo punto, non ci resta che verificare il contenuto di build.sh
. Modifichiamo il file con qualsiasi editor di testo, e osserviamo le seguenti variabili:
-
CONFIGFILE
: il nome del file di configurazione, che verrà copiato dalla directory al Kernel. -
JOBS
: quanti thread usare per la compilazione. Consiglio di impostare il numero di core fisici. -
KVER
: versione primaria Kernel. -
PVER
: versione secondaria/personalizzata Kernel. -
KERNVER
: versione completa Kernel, non modificare. -
CUSTDIR
: cartella che contiene questo progetto, da modificare qualora sia diversa dai default. -
CLEARDIR
: cartella patch Clear Linux, non modificare. -
PATCHDIR
: cartella patch, non modificare. -
BOREDIR
: cartella BORE scheduler, non modificare. -
V4L2DIR
: cartella V4L2loopback, non modificare. -
CFODIR
: cartella Kernel Compiler Patch, non modificare. -
USRDIR
: cartella che contiene la versione scelta del Kernel, non modificare. -
USRDIR
: questa variabile va impostata qualora la cartella del Kernel sia diversa da/usr/src
.
4. Selezione flag
Dopo aver modificato build.sh
, bisogna selezionare i necessari parametri per poter stabilire quali azioni intraprendere.
Segue ora una tabella con tutti i vari parametri (flag).
Flag breve | Flag esteso | Descrizione |
---|---|---|
Flag breve | Flag esteso | Descrizione |
-b | --skip-build | Non compilare il Kernel. |
-c | --skip-cfg | Non copiare il file di configurazione Kernel (config ). |
-d | --distcc | Usa distcc per velocizzare la compilazione del Kernel. |
-e | --ccache | Usa ccache per velocizzare la compilazione del Kernel. |
-f | --fastmath | Compila il Kernel con opzioni di matematica veloce non sicura (unsafe fast math). |
-h | --help | Mostra il menu' di aiuto ed esci. |
-l | --clearl-ps | Applica le patch di Clear Linux. |
-m | --menuconfig | Esegui make menuconfig nella directory del Kernel ed esci senza compilare. |
-o | --cpu-opts | Compila il Kernel con le ottimizzazioni per la famiglia del processore. |
-p | --patches | Applica le patch utente. |
-r | --bore | Compila Kernel con scheduler BORE |
-v | --v4l2 | Compila il modulo v4l2loopback. |
-z | --vars | Mostra variabili ed esci. |
5. Configurazione Kernel
Tipicamente, sarà necessario andare a configurare il Kernel, partendo da un file di configurazione. Per fare ciò, basterà eseguire il seguente comando come utente root:
./build.sh -l -m -o -p
Questo ci permetterà di:
-
-l
: Applicare le patch di Clear Linux -
-m
: Configurare il Kernel conmake menuconfig
-
-o
: Applicare le ottimizzazioni per la famiglia del processore -
-p
: Applicare le patch incluse
Una volta terminato il processo di configurazione del Kernel, il nuovo file di configurazione sarà disponibile presso /usr/src/linux/.config
(oppure sotto $KERNELDIR/.config
qualora KERNELDIR
fosse stato impostato).
A questo punto bisognerà copiare il file .config
dalla directory del Kernel alla directory attuale, per poi confrontare i due file e controllare eventuali cambiamenti:
cp /usr/src/linux/.config config.new
diff -u config config.new | vim
L'ultimo comando qui sopra esegue il comando diff
, mostrando le differenze tra il nostro file di partenza config
ed il nuovo file config.new
, per poi mostrare il tutto con l'editor Vim. Ovviamente, bisogna modificare il nome del file config
nel comando sopra qualora fosse necessario.
Dopo aver verificato le eventuali differenze, sostituiamo il nostro file config con il file config.new
, e passiamo alla vera e propria compilazione del Kernel.
6. Compilazione Kernel
Dopo essere sicuri di avere tutto il necessario, è possibile compilare il Kernel con il seguente comando, eseguendolo come utente root:
./build.sh -f -l -o -p
Notate la presenza ripetuta delle opzioni di patch (-l
, -o
, -p
). Questo perchè lo script, in automatico, ripristina tutti i cambiamenti effettuati dalle patch presenti nella directory del Kernel, ove possibile, e rimuove gli eventuali file patch. Ho programmato lo script in questo modo in quanto mi capita spesso di dover ripristinare e rimuovere varie patch, soprattutto dopo molteplici compilazioni.
Lo script ci mostrerà tutti gli eventuali errori di compilazione e non solo, in aggiunta al calcolo del tempo effettivo di compilazione, non considerando quindi patch ed altro.
Al termine dell'esecuzione, grazie ad installkernel
, verrà generato l'initramfs, ed aggiornerà il bootloader. Con la mia configurazione questi corrispondono, rispettivamente, a dracut
e grub
.
Extra
Questa sezione specifica gli eventuali passaggi da effettuare dopo aver terminato la compilazione del Kernel, che non dipendono dallo script. Usando lo script, non sarà necessario aggiornare manualmente nè l'initramfs, nè il bootloader, perchè verranno aggiornati in automatico (vedi sopra).
V4L2loopback
Lo script installerà questo modulo per la versione del Kernel compilata. L'unico passaggio da effettuare è aggiungere le impostazioni del modulo, in quanto lo script non controlla se sono già presenti o meno.
Modificate il file /etc/modprobe.d/v4l2loopback.conf
, ed inserite il seguente contenuto:
options v4l2loopback exclusive_caps=1 card_label="Camera2"
Qui potete modificare card_label
per impostare il nome del dispositivo, qualora fosse necessario, ad esempio se si volesse mascherare il fatto che questo è un dispositivo virtuale, o se semplicemente volete un nome migliore.
Initramfs
Per avviare il Kernel è necessario un initramfs. Per generarlo, userò dracut.
Prima di tutto, accertatevi di aver configurato dracut. Ad esempio, ecco il mio /etc/dracut.conf
:
# Equivalent to -H
hostonly="yes"
# Add various modules
# Module: description
# ==================================
# base: include basic utilities
# dash: include /bin/dash as /bin/sh
# fs-lib: include filesystem tools like mount
# kernel-modules: include kernel modules
# rescue: include various utils for rescue mode
# resume: allow initramfs to resume from low-power state
# rootfs-block: mount block device that contains rootfs
# shutdown: set up hooks to run on shutdown
# udev-rules: include udev and some basic rules
# usrmount: mount /usr
dracutmodules+=" base dash fs-lib kernel-modules rescue resume rootfs-block shutdown udev-rules usrmount "
# Do not include bash (we use dash)
omit_dracutmodules="bash"
# Include elogind
install_items="/lib64/elogind/elogind-uaccess-command"
# Use lz4 to compress the initramfs
compress="lz4"
# Add early microcode loading
early_microcode="yes"
È sufficiente eseguire, come utente root, il seguente comando:
dracut --kver 6.8.2-gentoo -f
Modificate 6.8.2-gentoo
con la versione del vostro Kernel. Attenzione al flag -f
: forza la generazione dell'initramfs, anche se già esiste per la versione del Kernel interessata.
Fatto ciò, l'initramfs sarà disponibile sotto /boot
, insieme ai file del Kernel precedentemente compilato.
Bootloader
Per avviare il nostro nuovo Kernel, sarà necessario configurare il bootloader. In questa sezione vediamo solo GRUB2.
La maggior parte degli utenti, arrivati a questo punto, sicuramente avranno già un sistema funzionante, ed un bootloader configurato. Questo fatto ci allevia il carico, richiedendo semplicemente un aggiornamento della configurazione, senza modificare ulteriori file.
Perciò, è necessario eseguire come utente root:
grub-mkconfig -o /boot/grub/grub.cfg
Il comando ci comunicherà i Kernel (ed eventuali altri sistemi operativi) trovati, che saranno disponibili al riavvio del nostro sistema, oltre a comunicarci i microcode trovati.