Logo

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
Attenzione

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:

  1. config:  ThinkPad T470p, con CPU i7-7820HQ (Kaby Lake, 4C8T), Nvidia GeForce 940MX dGPU + Intel HD 630 iGPU, SATAIII/NVMe SSD, 2560x1440 display.
  2. config.t440p:  ThinkPad T440p, con CPU i7-4700MQ (Haswell, 4C8T), Intel HD4600 iGPU, SATAIII SSD, 1366x768 display.
  3. 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

Info

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.

Info

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 breveFlag estesoDescrizione
Flag breveFlag estesoDescrizione
-b--skip-buildNon compilare il Kernel.
-c--skip-cfgNon copiare il file di configurazione Kernel (config).
-d--distccUsa distcc per velocizzare la compilazione del Kernel.
-e--ccacheUsa ccache per velocizzare la compilazione del Kernel.
-f--fastmathCompila il Kernel con opzioni di matematica veloce non sicura (unsafe fast math).
-h--helpMostra il menu' di aiuto ed esci.
-l--clearl-psApplica le patch di Clear Linux.
-m--menuconfigEsegui make menuconfig nella directory del Kernel ed esci senza compilare.
-o--cpu-optsCompila il Kernel con le ottimizzazioni per la famiglia del processore.
-p--patchesApplica le patch utente.
-r--boreCompila Kernel con scheduler BORE
-v--v4l2Compila il modulo v4l2loopback.
-z--varsMostra 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 con make 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.

Info

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.

← Torna alla pagina principale